// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn . //go:build plus package http3 import ( "context" "github.com/quic-go/quic-go" "net" "sync" "time" ) type ContextFunc func(ctx context.Context, conn net.Conn) context.Context type BasicConn struct { rawConn quic.EarlyConnection parentConn Conn ctxFunc ContextFunc connNotifier Notifier closeOnce *sync.Once } func NewConn(rawConn quic.EarlyConnection, ctxFunc ContextFunc) *BasicConn { return &BasicConn{ rawConn: rawConn, ctxFunc: ctxFunc, closeOnce: &sync.Once{}, } } func (this *BasicConn) callContextFunc(ctx context.Context) context.Context { if this.ctxFunc != nil { if this.parentConn != nil { return this.ctxFunc(ctx, this.parentConn) } return this.ctxFunc(ctx, this) } return ctx } func (this *BasicConn) SetParentConn(parentConn Conn) { this.parentConn = parentConn } func (this *BasicConn) SetNotifier(notifier Notifier) { this.connNotifier = notifier } func (this *BasicConn) notifier() (Notifier Notifier) { return this.connNotifier } func (this *BasicConn) AcceptStream(ctx context.Context) (quic.Stream, error) { stream, err := this.rawConn.AcceptStream(ctx) if err != nil { return stream, err } return NewStream(stream, this), nil } func (this *BasicConn) AcceptUniStream(ctx context.Context) (quic.ReceiveStream, error) { stream, err := this.rawConn.AcceptUniStream(ctx) if err != nil { return stream, err } return NewReceiveStream(stream, this), nil } func (this *BasicConn) OpenStream() (quic.Stream, error) { stream, err := this.rawConn.OpenStream() if err != nil { return stream, err } return NewStream(stream, this), nil } func (this *BasicConn) OpenStreamSync(ctx context.Context) (quic.Stream, error) { stream, err := this.rawConn.OpenStreamSync(ctx) if err != nil { return stream, err } return NewStream(stream, this), nil } func (this *BasicConn) OpenUniStream() (quic.SendStream, error) { stream, err := this.rawConn.OpenUniStream() if err != nil { return stream, err } return NewSendStream(stream, this), nil } func (this *BasicConn) OpenUniStreamSync(ctx context.Context) (quic.SendStream, error) { stream, err := this.rawConn.OpenUniStreamSync(ctx) if err != nil { return stream, err } return NewSendStream(stream, this), nil } func (this *BasicConn) LocalAddr() net.Addr { return this.rawConn.LocalAddr() } func (this *BasicConn) RemoteAddr() net.Addr { return this.rawConn.RemoteAddr() } func (this *BasicConn) CloseWithError(errCode quic.ApplicationErrorCode, errMsg string) error { err := this.rawConn.CloseWithError(errCode, errMsg) if this.connNotifier != nil { this.closeOnce.Do(func() { this.connNotifier.Close() }) } return err } func (this *BasicConn) Context() context.Context { return this.rawConn.Context() } func (this *BasicConn) ConnectionState() quic.ConnectionState { return this.rawConn.ConnectionState() } func (this *BasicConn) SendDatagram(b []byte) error { return this.rawConn.SendDatagram(b) } func (this *BasicConn) ReceiveDatagram(ctx context.Context) ([]byte, error) { data, err := this.rawConn.ReceiveDatagram(ctx) return data, err } func (this *BasicConn) HandshakeComplete() <-chan struct{} { return this.rawConn.HandshakeComplete() } func (this *BasicConn) NextConnection() quic.Connection { return this.rawConn.NextConnection() } /** implement net.Conn **/ func (this *BasicConn) Read(b []byte) (n int, err error) { _ = b // do nothing return } func (this *BasicConn) Write(b []byte) (n int, err error) { _ = b // do nothing return } func (this *BasicConn) Close() error { return this.CloseWithError(quic.ApplicationErrorCode(quic.NoError), "") } func (this *BasicConn) SetDeadline(t time.Time) error { _ = t // do nothing return nil } func (this *BasicConn) SetReadDeadline(t time.Time) error { _ = t // do nothing return nil } func (this *BasicConn) SetWriteDeadline(t time.Time) error { _ = t // do nothing return nil }