// Copyright 2026 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build !nethttpomithttp2

package http

import (
	"context"
	"crypto/tls"
	"errors"
	"io"
	"log"
	"net"
	"net/http/internal/http2"
	"time"

	_ "unsafe" // for go:linkname
)

// net/http supports HTTP/2 by default, but this support is removed when
// the nethttpomithttp2 build tag is set.
//
// HTTP/2 support is provided by the net/http/internal/http2 package.
//
// This file (http2.go) connects net/http to the http2 package.
// Since http imports http2, to avoid an import cycle we need to
// translate http package types (e.g., Request) into the equivalent
// http2 package types (e.g., http2.ClientRequest).
//
// The golang.org/x/net/http2 package is the original source of truth for
// the HTTP/2 implementation. At this time, users may still import that
// package and register its implementation on a net/http Transport or Server.
// However, the x/net package is no longer synchronized with std.

func init() {
	// NoBody and LocalAddrContextKey need to have the same value
	// in the http and http2 packages.
	//
	// We can't define these values in net/http/internal,
	// because their concrete types are part of the net/http API and
	// moving them causes API checker failures.
	// Override the http2 package versions at init time instead.
	http2.LocalAddrContextKey = LocalAddrContextKey
	http2.NoBody = NoBody
}

type http2Server = http2.Server
type http2Transport = http2.Transport

func (s *Server) configureHTTP2() {
	h2srv := &http2.Server{}

	// Historically, we've configured the HTTP/2 idle timeout in this fashion:
	// Set once at configuration time.
	if s.IdleTimeout != 0 {
		s.h2IdleTimeout = s.IdleTimeout
	} else {
		s.h2IdleTimeout = s.ReadTimeout
	}

	if s.TLSConfig == nil {
		s.TLSConfig = &tls.Config{}
	}
	s.nextProtoErr = h2srv.Configure(http2ServerConfig{s}, s.TLSConfig)
	if s.nextProtoErr != nil {
		return
	}

	s.RegisterOnShutdown(h2srv.GracefulShutdown)

	if s.TLSNextProto == nil {
		s.TLSNextProto = make(map[string]func(*Server, *tls.Conn, Handler))
	}
	// Historically, the presence of a TLSNextProto["h2"] key has been the signal to
	// enable/disable HTTP/2 support. Set a value in the map, but we'll never use it.
	s.TLSNextProto["h2"] = func(hs *Server, c *tls.Conn, h Handler) {
		c.Close()
	}

	s.h2 = h2srv
}

func (s *Server) setHTTP2Config(conf http2ExternalServerConfig) {
	if s.h2Config != nil {
		panic("http: HTTP/2 Server already registered")
	}
	s.h2Config = conf
	s.h2Config.ServeConnFunc(s.serveHTTP2Conn)
}

func (s *Server) serveHTTP2Conn(ctx context.Context, nc net.Conn, h Handler, sawClientPreface bool, upgradeReq *Request, settings []byte) {
	s.setupHTTP2_ServeTLS()
	var serverUpgradeReq *http2.ServerRequest
	if upgradeReq != nil {
		serverUpgradeReq = http2ServerRequestFromRequest(upgradeReq)
	}
	s.h2.ServeConn(nc, &http2.ServeConnOpts{
		Context:          ctx,
		Handler:          http2Handler{h},
		BaseConfig:       http2ServerConfig{s},
		SawClientPreface: sawClientPreface,
		UpgradeRequest:   serverUpgradeReq,
		Settings:         settings,
	})
}

func http2ServerRequestFromRequest(req *Request) *http2.ServerRequest {
	return &http2.ServerRequest{
		Context:       req.Context(),
		Proto:         req.Proto,
		ProtoMajor:    req.ProtoMajor,
		ProtoMinor:    req.ProtoMinor,
		Method:        req.Method,
		URL:           req.URL,
		Header:        http2.Header(req.Header),
		Trailer:       http2.Header(req.Trailer),
		Body:          req.Body,
		Host:          req.Host,
		ContentLength: req.ContentLength,
		RemoteAddr:    req.RemoteAddr,
		RequestURI:    req.RequestURI,
		TLS:           req.TLS,
		MultipartForm: req.MultipartForm,
	}
}

type http2Handler struct {
	h Handler
}

func (h http2Handler) ServeHTTP(w *http2.ResponseWriter, req *http2.ServerRequest) {
	h.h.ServeHTTP(http2ResponseWriter{w}, &Request{
		ctx:           req.Context,
		Proto:         "HTTP/2.0",
		ProtoMajor:    2,
		ProtoMinor:    0,
		Method:        req.Method,
		URL:           req.URL,
		Header:        Header(req.Header),
		RequestURI:    req.RequestURI,
		Trailer:       Header(req.Trailer),
		Body:          req.Body,
		Host:          req.Host,
		ContentLength: req.ContentLength,
		RemoteAddr:    req.RemoteAddr,
		TLS:           req.TLS,
		MultipartForm: req.MultipartForm,
	})
}

type http2ResponseWriter struct {
	*http2.ResponseWriter
}

// Optional http.ResponseWriter interfaces implemented.
var (
	_ CloseNotifier   = http2ResponseWriter{}
	_ Flusher         = http2ResponseWriter{}
	_ io.StringWriter = http2ResponseWriter{}
)

func (w http2ResponseWriter) Flush()            { w.ResponseWriter.FlushError() }
func (w http2ResponseWriter) FlushError() error { return w.ResponseWriter.FlushError() }

func (w http2ResponseWriter) Header() Header { return Header(w.ResponseWriter.Header()) }

func (w http2ResponseWriter) Push(target string, opts *PushOptions) error {
	var (
		method string
		header http2.Header
	)
	if opts != nil {
		method = opts.Method
		header = http2.Header(opts.Header)
	}
	err := w.ResponseWriter.Push(target, method, header)
	if err == http2.ErrNotSupported {
		err = ErrNotSupported
	}
	return err
}

type http2ServerConfig struct {
	s *Server
}

func (s http2ServerConfig) MaxHeaderBytes() int { return s.s.MaxHeaderBytes }
func (s http2ServerConfig) ConnState(c net.Conn, st http2.ConnState) {
	if s.s.ConnState != nil {
		s.s.ConnState(c, ConnState(st))
	}
}
func (s http2ServerConfig) DoKeepAlives() bool             { return s.s.doKeepAlives() }
func (s http2ServerConfig) WriteTimeout() time.Duration    { return s.s.WriteTimeout }
func (s http2ServerConfig) SendPingTimeout() time.Duration { return s.s.ReadTimeout }
func (s http2ServerConfig) ErrorLog() *log.Logger          { return s.s.ErrorLog }
func (s http2ServerConfig) ReadTimeout() time.Duration     { return s.s.ReadTimeout }
func (s http2ServerConfig) DisableClientPriority() bool    { return s.s.DisableClientPriority }

func (s http2ServerConfig) IdleTimeout() time.Duration {
	if s.s.h2Config != nil {
		return s.s.h2Config.IdleTimeout()
	}
	return s.s.h2IdleTimeout
}

func (s http2ServerConfig) HTTP2Config() http2.Config {
	return mergeHTTP2Config(s.s.HTTP2, s.s.h2Config)
}

// http2ExternalServerConfig is an HTTP/2 configuration provided by x/net/http2.
//
// When a x/net/http2.Server wraps a net/http.Server, we need to support the user
// setting configuration settings on the x/net Server:
//
//	s1 := &http.Server{}
//	s2 := &http2.Server{}
//	http2.ConfigureServer(s1, s2)
//
//	// This setting needs to affect s1:
//	s2.MaxReadFrameSize = 10000
//
// We handle this by having http2.ConfigureServer pass us an http2ExternalServerConfig
// (see http.Server.Serve) which we can use to query the current state of the http2.Server.
type http2ExternalServerConfig interface {
	// Various configuration settings:
	HTTP2Config() HTTP2Config
	IdleTimeout() time.Duration

	// ServeConnFunc provides a function to the x/net/http2.Server which it
	// can use to serve a new connection.
	ServeConnFunc(func(ctx context.Context, nc net.Conn, h Handler, sawClientPreface bool, upgradeReq *Request, settings []byte))
}

// http2ExternalTransportConfig is an HTTP/2 configuration provided by x/net/http2.
//
// When a x/net/http2.Transport wraps a net/http.Transport, we need to support the user
// setting configuration settings on the x/net Transport:
//
//	tr1 := &http.Transport{}
//	tr2 := http2.ConfigureTransports(t1)
//
//	// This setting needs to affect tr1:
//	tr2.MaxHeaderListSize = 10000
//
// We handle this by having http2.ConfigureTransports pass us an http2ExternalTransportConfig,
// which we can use to query the current state of the http2.Transport.
type http2ExternalTransportConfig interface {
	// Various configuration settings:
	HTTP2Config() HTTP2Config
	DisableCompression() bool
	MaxHeaderListSize() int64
	IdleConnTimeout() time.Duration

	// ConnFromContext is used to pass a net.Conn to Transport.NewClientConn
	// via a context value. See Transport.http2NewClientConnFromContext.
	ConnFromContext(context.Context) net.Conn

	// DialFromContext is used to dial new connections, overriding Transport.DialContext etc.
	// This is used when the user calls x/net/http2.Transport.RoundTrip directly,
	// in which case the historical behavior is to use the http2.Transport's dial functions.
	DialFromContext(ctx context.Context, network, addr string) (net.Conn, error)

	// ExternalRoundTrip reports whether Transport.RoundTrip should call the
	// external transport's RoundTrip. This is used when x/net/http2.Transport.ConnPool
	// is set, in which case the user-provided ClientConnPool has taken responsibility
	// for picking a connection to use.
	ExternalRoundTrip() bool

	// RoundTrip performs a round trip.
	// It should only be used when ExternalRoundTrip requests it.
	RoundTrip(*Request) (*Response, error)

	// Registered is called to report successful registration of the config.
	Registered(*Transport)
}

func (t *Transport) configureHTTP2(protocols Protocols) {
	if t.TLSClientConfig == nil {
		t.TLSClientConfig = &tls.Config{}
	}
	if t.HTTP2 == nil {
		t.HTTP2 = &HTTP2Config{}
	}
	t2 := http2.NewTransport(transportConfig{t})
	t.h2Transport = t2

	t.registerProtocol("https", http2RoundTripper{t2, true})
	if t.TLSNextProto == nil {
		t.TLSNextProto = make(map[string]func(authority string, c *tls.Conn) RoundTripper)
	}
	// Historically, the presence of a TLSNextProto["h2"] key has been the signal to
	// enable/disable HTTP/2 support. Set a value in the map, but we'll never use it.
	t.TLSNextProto["h2"] = func(authority string, c *tls.Conn) RoundTripper {
		return http2ErringRoundTripper{
			errors.New("unexpected use of stub RoundTripper"),
		}
	}

	// Server.ServeTLS clones the tls.Config before modifying it.
	// Transport doesn't. We may want to make the two consistent some day.
	//
	// http2configureTransport will have already set NextProtos, but adjust it again
	// here to remove HTTP/1.1 if the user has disabled it.
	t.TLSClientConfig.NextProtos = adjustNextProtos(t.TLSClientConfig.NextProtos, protocols)
}

type http2ErringRoundTripper struct{ err error }

func (rt http2ErringRoundTripper) RoundTripErr() error                   { return rt.err }
func (rt http2ErringRoundTripper) RoundTrip(*Request) (*Response, error) { return nil, rt.err }

func http2RoundTrip(req *Request, rt func(*http2.ClientRequest) (*http2.ClientResponse, error)) (*Response, error) {
	resp := &Response{}
	cresp, err := rt(&http2.ClientRequest{
		Context:       req.Context(),
		Method:        req.Method,
		URL:           req.URL,
		Header:        http2.Header(req.Header),
		Trailer:       http2.Header(req.Trailer),
		Body:          req.Body,
		Host:          req.Host,
		GetBody:       req.GetBody,
		ContentLength: req.ContentLength,
		Cancel:        req.Cancel,
		Close:         req.Close,
		ResTrailer:    (*http2.Header)(&resp.Trailer),
	})
	if err != nil {
		return nil, err
	}
	resp.Status = cresp.Status + " " + StatusText(cresp.StatusCode)
	resp.StatusCode = cresp.StatusCode
	resp.Proto = "HTTP/2.0"
	resp.ProtoMajor = 2
	resp.ProtoMinor = 0
	resp.ContentLength = cresp.ContentLength
	resp.Uncompressed = cresp.Uncompressed
	resp.Header = Header(cresp.Header)
	resp.Trailer = Header(cresp.Trailer)
	resp.Body = cresp.Body
	resp.TLS = cresp.TLS
	resp.Request = req
	return resp, nil
}

// http2AddConn adds nc to the HTTP/2 connection pool.
func (t *Transport) http2AddConn(scheme, authority string, nc net.Conn) (RoundTripper, error) {
	if t.h2Transport == nil {
		return nil, errors.ErrUnsupported
	}
	err := t.h2Transport.AddConn(scheme, authority, nc)
	if err != nil {
		return nil, err
	}
	return http2RoundTripper{t.h2Transport, false}, nil
}

// http2NewClientConn creates an HTTP/2 genericClientConn (used to implement ClientConn) from nc.
// The connection is not added to the HTTP/2 connection pool.
func (t *Transport) http2NewClientConn(nc net.Conn, internalStateHook func()) (genericClientConn, error) {
	if t.h2Transport == nil {
		return nil, errors.ErrUnsupported
	}
	cc, err := t.h2Transport.NewClientConn(nc, internalStateHook)
	if err != nil {
		return nil, err
	}
	return http2ClientConn{cc}, nil
}

// http2NewClientConnFromContext creates a *ClientConn from a net.Conn.
//
// Transport.NewClientConn takes an address and dials a new net.Conn.
// We don't currently provide a simple way for the user to provide a net.Conn and get a
// *ClientConn out of it (although we do let the user provide their own Transport.DialContext,
// which can be used to effectively do this).
//
// x/net/http2.Transport.NewClientConn, in contrast, requires the user to provide a net.Conn.
// To support implementing the x/net/http2 NewClientConn in terms of a net/http.Transport,
// we permit x/net/http2 to pass us a net.Conn via a context key.
//
// http2NewClientConnFromContext handles extracting the net.Conn from the Context
// (when present) and creating a *ClientConn from it.
func (t *Transport) http2NewClientConnFromContext(ctx context.Context) (*ClientConn, error) {
	if t.h2Config == nil {
		return nil, errors.ErrUnsupported
	}
	nc := t.h2Config.ConnFromContext(ctx)
	if nc == nil {
		return nil, errors.ErrUnsupported
	}
	if t.h2Transport == nil {
		return nil, errors.New("http: Transport does not support HTTP/2")
	}
	cc := &ClientConn{}
	gc, err := t.http2NewClientConn(nc, cc.maybeRunStateHook)
	if err != nil {
		return nil, err
	}
	cc.stateHookMu.Lock()
	defer cc.stateHookMu.Unlock()
	cc.cc = gc
	cc.lastAvailable = gc.Available()
	return cc, nil
}

// http2ExternalDial creates a new HTTP/2 connection,
// using the x/net/http2.Transport's dial functions.
//
// This is used when the user has called x/net/http2.Transport.RoundTrip.
// If the RoundTrip needs to create a new connection,
// the historical behavior is for it to use the http2.Transport's DialTLS or DialTLSContext
// functions, and not any dial functions on the http.Transport.
func (t *Transport) http2ExternalDial(ctx context.Context, cm connectMethod) (RoundTripper, error) {
	if t.h2Config == nil {
		return nil, errors.ErrUnsupported
	}
	nc, err := t.h2Config.DialFromContext(ctx, "tcp", cm.targetAddr)
	if err != nil {
		return nil, err
	}
	return t.http2AddConn(cm.targetScheme, cm.targetAddr, nc)
}

type http2RoundTripper struct {
	t                *http2.Transport
	mapCachedConnErr bool
}

func (rt http2RoundTripper) RoundTrip(req *Request) (*Response, error) {
	resp, err := http2RoundTrip(req, rt.t.RoundTrip)
	if err != nil {
		if rt.mapCachedConnErr && http2isNoCachedConnError(err) {
			err = ErrSkipAltProtocol
		}
		return nil, err
	}
	return resp, nil
}

type http2ClientConn struct {
	http2.NetHTTPClientConn
}

func (cc http2ClientConn) RoundTrip(req *Request) (*Response, error) {
	return http2RoundTrip(req, cc.NetHTTPClientConn.RoundTrip)
}

// transportConfig implements the http2.TransportConfig interface,
// providing the net/http Transport's configuration to the HTTP/2 implementation.
//
// When an x/net/http2 Transport has provided a configuration (see http2ExternalTransportConfig),
// the transportConfig merges the x/net/http2 and net/http Transport configurations.
type transportConfig struct {
	t *Transport
}

func (t transportConfig) MaxResponseHeaderBytes() int64        { return t.t.MaxResponseHeaderBytes }
func (t transportConfig) DisableKeepAlives() bool              { return t.t.DisableKeepAlives }
func (t transportConfig) ExpectContinueTimeout() time.Duration { return t.t.ExpectContinueTimeout }
func (t transportConfig) ResponseHeaderTimeout() time.Duration { return t.t.ResponseHeaderTimeout }

func (t transportConfig) MaxHeaderListSize() int64 {
	if t.t.h2Config != nil {
		return t.t.h2Config.MaxHeaderListSize()
	}
	return 0
}

func (t transportConfig) DisableCompression() bool {
	if t.t.h2Config != nil && t.t.h2Config.DisableCompression() {
		return true
	}
	return t.t.DisableCompression
}

func (t transportConfig) IdleConnTimeout() time.Duration {
	// Unlike most config settings, historically IdleConnTimeout prefers the
	// http2.Transport's setting over the http.Transport.
	if t.t.h2Config != nil {
		if timeout := t.t.h2Config.IdleConnTimeout(); timeout != 0 {
			return timeout
		}
	}
	return t.t.IdleConnTimeout
}

type http2Configer interface {
	HTTP2Config() HTTP2Config
}

func mergeHTTP2Config(c1 *HTTP2Config, confer http2Configer) http2.Config {
	if c1 == nil && confer == nil {
		return http2.Config{}
	}
	var c http2.Config
	if c1 != nil {
		c = (http2.Config)(*c1)
	}
	var c2 HTTP2Config
	if confer != nil {
		c2 = confer.HTTP2Config()
	}
	if c.MaxConcurrentStreams == 0 {
		c.MaxConcurrentStreams = c2.MaxConcurrentStreams
	}
	if c2.StrictMaxConcurrentRequests {
		c.StrictMaxConcurrentRequests = true
	}
	if c.MaxDecoderHeaderTableSize == 0 {
		c.MaxDecoderHeaderTableSize = c2.MaxDecoderHeaderTableSize
	}
	if c.MaxEncoderHeaderTableSize == 0 {
		c.MaxEncoderHeaderTableSize = c2.MaxEncoderHeaderTableSize
	}
	if c.MaxReadFrameSize == 0 {
		c.MaxReadFrameSize = c2.MaxReadFrameSize
	}
	if c.MaxReceiveBufferPerConnection == 0 {
		c.MaxReceiveBufferPerConnection = c2.MaxReceiveBufferPerConnection
	}
	if c.MaxReceiveBufferPerStream == 0 {
		c.MaxReceiveBufferPerStream = c2.MaxReceiveBufferPerStream
	}
	if c.SendPingTimeout == 0 {
		c.SendPingTimeout = c2.SendPingTimeout
	}
	if c.PingTimeout == 0 {
		c.PingTimeout = c2.PingTimeout
	}
	if c.WriteByteTimeout == 0 {
		c.WriteByteTimeout = c2.WriteByteTimeout
	}
	if c2.PermitProhibitedCipherSuites {
		c.PermitProhibitedCipherSuites = true
	}
	if c.CountError == nil {
		c.CountError = c2.CountError
	}
	return c
}

func (t transportConfig) HTTP2Config() http2.Config {
	return mergeHTTP2Config(t.t.HTTP2, t.t.h2Config)
}

// transportFromH1Transport provides a way for HTTP/2 tests to extract
// the http2.Transport from an http.Transport.
//
//go:linkname transportFromH1Transport net/http/internal/http2_test.transportFromH1Transport
func transportFromH1Transport(t *Transport) any {
	t.nextProtoOnce.Do(t.onceSetNextProtoDefaults)
	return t.h2Transport
}
