add files

This commit is contained in:
Smile Rex
2026-03-03 20:01:11 +03:00
commit 7d44a07996
5 changed files with 180 additions and 0 deletions

20
go.mod Normal file
View File

@@ -0,0 +1,20 @@
module qgo
go 1.25.0
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dunglas/httpsfv v1.1.0 // indirect
github.com/okdaichi/gomoqt v0.10.7 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/quic-go/qpack v0.6.0 // indirect
github.com/quic-go/quic-go v0.59.0 // indirect
github.com/quic-go/webtransport-go v0.10.0 // indirect
github.com/stretchr/objx v0.5.3 // indirect
github.com/stretchr/testify v1.11.1 // indirect
golang.org/x/crypto v0.46.0 // indirect
golang.org/x/net v0.48.0 // indirect
golang.org/x/sys v0.39.0 // indirect
golang.org/x/text v0.32.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

29
go.sum Normal file
View File

@@ -0,0 +1,29 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dunglas/httpsfv v1.1.0 h1:Jw76nAyKWKZKFrpMMcL76y35tOpYHqQPzHQiwDvpe54=
github.com/dunglas/httpsfv v1.1.0/go.mod h1:zID2mqw9mFsnt7YC3vYQ9/cjq30q41W+1AnDwH8TiMg=
github.com/okdaichi/gomoqt v0.10.7 h1:+2fEG8BgBkPPvUorwpaWd9k4IZrtUx+Nr4EDuz8BpYc=
github.com/okdaichi/gomoqt v0.10.7/go.mod h1:a85xgBn+vYbsWTn+cH7YQlnmvSE5m8XptIbP1wEz9v0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw=
github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU=
github.com/quic-go/webtransport-go v0.10.0 h1:LqXXPOXuETY5Xe8ITdGisBzTYmUOy5eSj+9n4hLTjHI=
github.com/quic-go/webtransport-go v0.10.0/go.mod h1:LeGIXr5BQKE3UsynwVBeQrU1TPrbh73MGoC6jd+V7ow=
github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4=
github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

28
localhost+3-key.pem Normal file
View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC3WrjpsflA1UTA
ieT/me0rHuMfRw/K5GVRUSAhaotthGcO3DfYRpGwbNdmvDl74B093hjdFw+iQpuC
4QC5zoehre1QZ5dbnGQ8icK1qc733mSClfLmzpkweogRpRDzdzMmNb2qSN5YINLR
DTNL3T8OWeLgwzm1ExebUvuQmKDw50T0qIWiFfjOUT5uwpop1Yez4AFkVPLFqE+X
RZqrZKzK9mWxvTvV4bVNh6Ocwq2/xcvNv+ClvnX7F02GV2E7Edxkyoxv7dmhLHx8
GdmoKGuW9b/9RpWICW/3BzKu71vsAUYwoYxFgWhEHHSYAcSRAyjaYJbFEhOd5qFY
77Z82i+XAgMBAAECggEBAJJw9BU6XyAn9cRtnieDUghJoA7gG73pkv5Sc/4ccYWj
5QfaXQPwwPWOyK82EBdfFRvPoj4a6BKpbjkm6gR87pj0KAE664lwrCIpyQh8umAA
EHi3uIwdX/53Luwg0RwTDRgsffJeRq9Ob/Ilv92MtIsKwYjQg+uadxVIPsHrFUex
pCjHI2RupGLd+qQ/7dqZDgVnzSjfwxXdw64NdRYeP6IXkkuHxTLyTjqR4qMIcs/A
B/wWA2bfch+aQmzmZ+H2rS6fcvP0COr0F36ZO6T9qS/QFjrTxHD3cpT2qdPcA5VG
3RBsmx7+j/DuEjUV/Cc/GKPVjtO/VOUL2JzjkXQtkiECgYEA5OGMgUhpO6e7H9ZP
OGORt+gw/hnnaM3OsoRYJvyTcC0XXnmZfFf1tW76Rd9zawVXN9cHNlC+GCAQC/d+
Xk0llhAP3tT+rh5TVc+s/7rL7a9kLRevekbjGUon8ZpTjuso7iqP3UpbDAh2grrS
k2S06eSJo2CaIfxyvSxEnzmmrecCgYEAzRRAn7lOAnD6lEv5oSMm1yJu0/G/fBmB
JpSDkeaB5jB8skoueZL78VRd1NEMbGvmn9aMsIx/jqVokEoh70B3qErlRPqZQ26i
a685XU2e8AUI043JExpRNXMwSAmepSRIIa4xR8lqq66RUw20h3wtJTwmKL/w0Tem
o9yOTUXlWtECgYBwlZXUnjbNVlNQdM2hEjFCgl9fDoTq45mR7FGkU8d+fV+qZCwg
ou/FIGLRbfnLIeRmHkp46Dyph1P9Xu91GYOsjhgQZzsjkN0zL6WMYWkgcI7ZM3Zo
smfRL834JQ6HFZubk6oSkxm4EI2i/pzITdhD2NvvVnxazV/vN9BFdklL7wKBgQCc
MQKPI9jwLxAKBltXiKg6TfVO4t5OLDabJZ2Xb5IbuW4fdDQ1T+cnBHR6c8Uchomd
zxBUHo3AHOaojm2OBPGdcX1wrdQw8YAut8Pe9hFJCOySA3jTXcXgCZ0KIJl9eUae
sEbEP/lITKpOMS//yGmx5D/D5XwKPHJkdsTCwatPIQKBgQDBDGmOUhpko0KiuFQU
x1behNVqzXEGduXwurorNRCW0v3oHrspgPWzQ0q6in9I9+R2Vww5rlFJAJKeOnG6
HTbXMtvrSRu4ySPhJbmHpmmXHBSHjO4w/QZ46aWVgK6a19sXMeVgcrwgEiFkQIgi
+F2EKAjDGB8SuVr4u5y35pk7zA==
-----END PRIVATE KEY-----

26
localhost+3.pem Normal file
View File

@@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE-----
MIIEVTCCAr2gAwIBAgIRANPwHULQ9FFqKkR2fglBngowDQYJKoZIhvcNAQELBQAw
dTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMSUwIwYDVQQLDBxSRVhc
c21pbGVyZXhAUmV4IChTbWlsZSBSZXgpMSwwKgYDVQQDDCNta2NlcnQgUkVYXHNt
aWxlcmV4QFJleCAoU21pbGUgUmV4KTAeFw0yNjAzMDMxNjU0MzBaFw0yODA2MDMx
NjU0MzBaMFAxJzAlBgNVBAoTHm1rY2VydCBkZXZlbG9wbWVudCBjZXJ0aWZpY2F0
ZTElMCMGA1UECwwcUkVYXHNtaWxlcmV4QFJleCAoU21pbGUgUmV4KTCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBALdauOmx+UDVRMCJ5P+Z7Sse4x9HD8rk
ZVFRICFqi22EZw7cN9hGkbBs12a8OXvgHT3eGN0XD6JCm4LhALnOh6Gt7VBnl1uc
ZDyJwrWpzvfeZIKV8ubOmTB6iBGlEPN3MyY1vapI3lgg0tENM0vdPw5Z4uDDObUT
F5tS+5CYoPDnRPSohaIV+M5RPm7CminVh7PgAWRU8sWoT5dFmqtkrMr2ZbG9O9Xh
tU2Ho5zCrb/Fy82/4KW+dfsXTYZXYTsR3GTKjG/t2aEsfHwZ2agoa5b1v/1GlYgJ
b/cHMq7vW+wBRjChjEWBaEQcdJgBxJEDKNpglsUSE53moVjvtnzaL5cCAwEAAaOB
hDCBgTAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwHwYDVR0j
BBgwFoAU5b3W0xZSMRVucu6dgemt+ce4/v0wOQYDVR0RBDIwMIIJbG9jYWxob3N0
ggtteWFwcC5sb2NhbIcEfwAAAYcQAAAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0B
AQsFAAOCAYEABYZKMJdOiMRN5woQ0BR14eQCxseXdE0IgCIdj3jT4fF8XztzIctf
VEynT4UEEtZXoWQDy1WU96xbrrXhwC/NIvdDRULIoIobR22kGDkQxRhTB4MCZrzU
utyrOcmbN2L+vvJRNi04cMxti4hOxgEfPhy68zmnvo8Wz04pt7ddSyGnrwe2TKvm
Af15X9c4S8iaPBag6+9bTlttu/fAOX8o8vA3wMOXdPo7ELYcDIAbCTgJ1UMyYb2p
1jzPJX9A3P3xQNdrgkUjTQxzEXikuIt2oDa6wOYi+v73pwbxw7xyl+2kNOvVbHs0
k4faHc28ActaYmUOgdMv+xbGS3aZOi8ZqAhudrTFR+emFUvuHGbl3Z2d7B53GP14
pRaL9jTZ3QnqL8m50l8QsxEMdbbZv1MuS5gD02HC++k3TDqblaLUw3RvsFESUhtA
PWzmxT9RQ7jHMdUbLL1TSGI8FQ6pDa7756apbEAhFz2wfTiQCrD0gXm39Vzf4DOu
LMCvXVF7ZufT
-----END CERTIFICATE-----

77
main.go Normal file
View File

@@ -0,0 +1,77 @@
package main
import (
"crypto/tls"
"log"
"log/slog"
"net/http"
"github.com/okdaichi/gomoqt/moqt"
"github.com/okdaichi/gomoqt/quic"
)
func main() {
// 🔐 Загружаем mkcert сертификат
cert, err := tls.LoadX509KeyPair("localhost+3.pem", "localhost+3-key.pem")
if err != nil {
log.Fatalf("failed to load server cert and key: %v", err)
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
NextProtos: []string{"h3"}, // обязательно для HTTP/3
}
// 🚀 MoQ сервер
server := moqt.Server{
Addr: ":8080",
TLSConfig: tlsConfig,
QUICConfig: &quic.Config{
Allow0RTT: true,
EnableDatagrams: true,
},
}
path := "/relay"
// 🌐 WebTransport endpoint
http.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
slog.Info("Incoming WebTransport request")
err := server.HandleWebTransport(w, r)
if err != nil {
slog.Error("WebTransport error", "error", err)
}
})
// 📡 MoQ setup handler
moqt.HandleFunc(path, func(w moqt.SetupResponseWriter, r *moqt.SetupRequest) {
slog.Info("MoQ setup request received")
sess, err := moqt.Accept(w, r, nil)
if err != nil {
slog.Error("Failed to accept session", "error", err)
return
}
slog.Info("MoQ session established", "remote", sess.RemoteAddr())
// ⚠️ НЕ блокируем поток!
go handleSession(sess)
})
slog.Info("Server starting on https://localhost:8080")
if err := server.ListenAndServe(); err != nil {
slog.Error("Server failed", "error", err)
}
}
func handleSession(sess *moqt.Session) {
defer sess.Context().Done()
for {
// Ждём закрытия соединения
select {}
}
}