// 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) MaxHeaderValueCount() int { return s.s.maxHeaderValueCount() }
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
}
