Add main.go
This commit is contained in:
108
main.go
Normal file
108
main.go
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/pion/webtransport"
|
||||||
|
"github.com/quic-go/quic-go/http3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// 1. Настройка TLS (обязательно для WebTransport/QUIC)
|
||||||
|
// Поскольку SSL терминация на VPS, здесь мы используем самоподписанный сертификат
|
||||||
|
// для внутренней связи (Dokploy <-> Caddy). Nixpacks соберет это.
|
||||||
|
// Но для простоты примера мы просто слушаем обычный HTTP, так как Caddy проксирует.
|
||||||
|
// ОДНАКО: WebTransport ТРЕБУЕТ TLS. Внутренний TLS тоже нужен.
|
||||||
|
// Мы сгенерируем его на лету, чтобы не возиться с файлами.
|
||||||
|
|
||||||
|
cert, err := generateSelfSignedCert()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsConfig := &tls.Config{
|
||||||
|
Certificates: []tls.Certificate{cert},
|
||||||
|
NextProtos: []string{"h3"}, // HTTP/3
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Настройка WebTransport Handler
|
||||||
|
server := webtransport.Server{
|
||||||
|
H3: http3.Server{
|
||||||
|
Addr: ":8080", // Порт внутри контейнера
|
||||||
|
TLSConfig: tlsConfig,
|
||||||
|
},
|
||||||
|
CheckOrigin: func(r *http.Request) bool { return true }, // Разрешить все Origin для теста
|
||||||
|
}
|
||||||
|
|
||||||
|
http.HandleFunc("/wt", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Println("New WebTransport request from:", r.RemoteAddr)
|
||||||
|
sess, err := server.Upgrade(w, r)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Upgrade failed: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обработка сессии в отдельной горутине
|
||||||
|
go handleSession(sess)
|
||||||
|
})
|
||||||
|
|
||||||
|
log.Println("WebTransport server listening on https://localhost:8080/wt (via Caddy)")
|
||||||
|
// Запускаем HTTP/3 сервер
|
||||||
|
if err := server.ListenAndServe(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обработка одной WebTransport сессии
|
||||||
|
func handleSession(sess *webtransport.Session) {
|
||||||
|
defer sess.CloseWithError(0, "session closed")
|
||||||
|
|
||||||
|
for {
|
||||||
|
// Читаем датаграммы (самый быстрый и ненадежный способ, как UDP)
|
||||||
|
msg, err := sess.ReadDatagram(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
if err != io.EOF {
|
||||||
|
log.Printf("ReadDatagram error: %v", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Printf("Received Datagram from %v: %s\n", sess.RemoteAddr(), string(msg))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вспомогательная функция для генерации внутреннего SSL
|
||||||
|
// (Для связи Caddy -> Dokploy по Wireguard)
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/x509"
|
||||||
|
"crypto/x509/pkix"
|
||||||
|
"encoding/pem"
|
||||||
|
"math/big"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func generateSelfSignedCert() (tls.Certificate, error) {
|
||||||
|
priv, _ := rsa.GenerateKey(rand.Reader, 2048)
|
||||||
|
template := x509.Certificate{
|
||||||
|
SerialNumber: big.NewInt(1),
|
||||||
|
Subject: pkix.Name{Organization: []string{"Pion WebTransport Test"}},
|
||||||
|
NotBefore: time.Now(),
|
||||||
|
NotAfter: time.Now().Add(time.Hour * 24 * 365),
|
||||||
|
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||||
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||||
|
BasicConstraintsValid: true,
|
||||||
|
}
|
||||||
|
derBytes, _ := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
|
||||||
|
|
||||||
|
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
|
||||||
|
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
|
||||||
|
|
||||||
|
return tls.X509KeyPair(certPEM, keyPEM)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user