mirror of
https://github.com/tinygo-org/net.git
synced 2026-08-14 08:23:39 +00:00
Upgrade net package from Go 1.21.4 to Go 1.26.2
Backport upstream Go standard library changes to TinyGo's net package. Unmodified files (18) replaced directly from Go 1.26.2 source. Modified files (22) merged via 3-way diff, preserving all TinyGo netdev adaptations, TINYGO markers, and embedded-device constraints. Notable upstream changes included: - net/http: cookie handling improvements, fs enhancements, reverse proxy updates, chunked encoding fixes - net/http: ServeMux routing and pattern matching updates - net: IP parsing and MAC address handling improvements - Various doc link syntax modernization (e.g. [Dial], [Buffers]) TinyGo-only files (netdev.go, tlssock.go) unchanged. All TINYGO comment markers preserved.
This commit is contained in:
@@ -8,13 +8,19 @@ package httptest
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// NewRequest returns a new incoming server Request, suitable
|
||||
// for passing to an http.Handler for testing.
|
||||
// NewRequest wraps NewRequestWithContext using context.Background.
|
||||
func NewRequest(method, target string, body io.Reader) *http.Request {
|
||||
return NewRequestWithContext(context.Background(), method, target, body)
|
||||
}
|
||||
|
||||
// NewRequestWithContext returns a new incoming server Request, suitable
|
||||
// for passing to an [http.Handler] for testing.
|
||||
//
|
||||
// The target is the RFC 7230 "request-target": it may be either a
|
||||
// path or an absolute URL. If target is an absolute URL, the host name
|
||||
@@ -27,16 +33,16 @@ import (
|
||||
//
|
||||
// An empty method means "GET".
|
||||
//
|
||||
// The provided body may be nil. If the body is of type *bytes.Reader,
|
||||
// *strings.Reader, or *bytes.Buffer, the Request.ContentLength is
|
||||
// set.
|
||||
// The provided body may be nil. If the body is of type [bytes.Reader],
|
||||
// [strings.Reader], [bytes.Buffer], or the value [http.NoBody],
|
||||
// the Request.ContentLength is set.
|
||||
//
|
||||
// NewRequest panics on error for ease of use in testing, where a
|
||||
// panic is acceptable.
|
||||
//
|
||||
// To generate a client HTTP request instead of a server request, see
|
||||
// the NewRequest function in the net/http package.
|
||||
func NewRequest(method, target string, body io.Reader) *http.Request {
|
||||
func NewRequestWithContext(ctx context.Context, method, target string, body io.Reader) *http.Request {
|
||||
if method == "" {
|
||||
method = "GET"
|
||||
}
|
||||
@@ -44,6 +50,7 @@ func NewRequest(method, target string, body io.Reader) *http.Request {
|
||||
if err != nil {
|
||||
panic("invalid NewRequest arguments; " + err.Error())
|
||||
}
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
// HTTP/1.0 was used above to avoid needing a Host field. Change it to 1.1 here.
|
||||
req.Proto = "HTTP/1.1"
|
||||
@@ -61,6 +68,9 @@ func NewRequest(method, target string, body io.Reader) *http.Request {
|
||||
default:
|
||||
req.ContentLength = -1
|
||||
}
|
||||
if body == http.NoBody {
|
||||
req.ContentLength = 0
|
||||
}
|
||||
if rc, ok := body.(io.ReadCloser); ok {
|
||||
req.Body = rc
|
||||
} else {
|
||||
|
||||
+35
-47
@@ -12,9 +12,11 @@ import (
|
||||
"net/textproto"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/http/httpguts"
|
||||
)
|
||||
|
||||
// ResponseRecorder is an implementation of http.ResponseWriter that
|
||||
// ResponseRecorder is an implementation of [http.ResponseWriter] that
|
||||
// records its mutations for later inspection in tests.
|
||||
type ResponseRecorder struct {
|
||||
// Code is the HTTP response code set by WriteHeader.
|
||||
@@ -45,7 +47,7 @@ type ResponseRecorder struct {
|
||||
wroteHeader bool
|
||||
}
|
||||
|
||||
// NewRecorder returns an initialized ResponseRecorder.
|
||||
// NewRecorder returns an initialized [ResponseRecorder].
|
||||
func NewRecorder() *ResponseRecorder {
|
||||
return &ResponseRecorder{
|
||||
HeaderMap: make(http.Header),
|
||||
@@ -55,12 +57,12 @@ func NewRecorder() *ResponseRecorder {
|
||||
}
|
||||
|
||||
// DefaultRemoteAddr is the default remote address to return in RemoteAddr if
|
||||
// an explicit DefaultRemoteAddr isn't set on ResponseRecorder.
|
||||
// an explicit DefaultRemoteAddr isn't set on [ResponseRecorder].
|
||||
const DefaultRemoteAddr = "1.2.3.4"
|
||||
|
||||
// Header implements http.ResponseWriter. It returns the response
|
||||
// Header implements [http.ResponseWriter]. It returns the response
|
||||
// headers to mutate within a handler. To test the headers that were
|
||||
// written after a handler completes, use the Result method and see
|
||||
// written after a handler completes, use the [ResponseRecorder.Result] method and see
|
||||
// the returned Response value's Header.
|
||||
func (rw *ResponseRecorder) Header() http.Header {
|
||||
m := rw.HeaderMap
|
||||
@@ -103,23 +105,45 @@ func (rw *ResponseRecorder) writeHeader(b []byte, str string) {
|
||||
// Write implements http.ResponseWriter. The data in buf is written to
|
||||
// rw.Body, if not nil.
|
||||
func (rw *ResponseRecorder) Write(buf []byte) (int, error) {
|
||||
// Record the write, even if we're going to return an error.
|
||||
rw.writeHeader(buf, "")
|
||||
if rw.Body != nil {
|
||||
rw.Body.Write(buf)
|
||||
}
|
||||
if !bodyAllowedForStatus(rw.Code) {
|
||||
return 0, http.ErrBodyNotAllowed
|
||||
}
|
||||
return len(buf), nil
|
||||
}
|
||||
|
||||
// WriteString implements io.StringWriter. The data in str is written
|
||||
// WriteString implements [io.StringWriter]. The data in str is written
|
||||
// to rw.Body, if not nil.
|
||||
func (rw *ResponseRecorder) WriteString(str string) (int, error) {
|
||||
// Record the write, even if we're going to return an error.
|
||||
rw.writeHeader(nil, str)
|
||||
if rw.Body != nil {
|
||||
rw.Body.WriteString(str)
|
||||
}
|
||||
if !bodyAllowedForStatus(rw.Code) {
|
||||
return 0, http.ErrBodyNotAllowed
|
||||
}
|
||||
return len(str), nil
|
||||
}
|
||||
|
||||
// bodyAllowedForStatus reports whether a given response status code
|
||||
// permits a body. See RFC 7230, section 3.3.
|
||||
func bodyAllowedForStatus(status int) bool {
|
||||
switch {
|
||||
case status >= 100 && status <= 199:
|
||||
return false
|
||||
case status == 204:
|
||||
return false
|
||||
case status == 304:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func checkWriteHeaderCode(code int) {
|
||||
// Issue 22880: require valid WriteHeader status codes.
|
||||
// For now we only enforce that it's three digits.
|
||||
@@ -137,7 +161,7 @@ func checkWriteHeaderCode(code int) {
|
||||
}
|
||||
}
|
||||
|
||||
// WriteHeader implements http.ResponseWriter.
|
||||
// WriteHeader implements [http.ResponseWriter].
|
||||
func (rw *ResponseRecorder) WriteHeader(code int) {
|
||||
if rw.wroteHeader {
|
||||
return
|
||||
@@ -152,7 +176,7 @@ func (rw *ResponseRecorder) WriteHeader(code int) {
|
||||
rw.snapHeader = rw.HeaderMap.Clone()
|
||||
}
|
||||
|
||||
// Flush implements http.Flusher. To test whether Flush was
|
||||
// Flush implements [http.Flusher]. To test whether Flush was
|
||||
// called, see rw.Flushed.
|
||||
func (rw *ResponseRecorder) Flush() {
|
||||
if !rw.wroteHeader {
|
||||
@@ -173,7 +197,7 @@ func (rw *ResponseRecorder) Flush() {
|
||||
// did a write.
|
||||
//
|
||||
// The Response.Body is guaranteed to be non-nil and Body.Read call is
|
||||
// guaranteed to not return any error other than io.EOF.
|
||||
// guaranteed to not return any error other than [io.EOF].
|
||||
//
|
||||
// Result must only be called after the handler has finished running.
|
||||
func (rw *ResponseRecorder) Result() *http.Response {
|
||||
@@ -205,9 +229,9 @@ func (rw *ResponseRecorder) Result() *http.Response {
|
||||
if trailers, ok := rw.snapHeader["Trailer"]; ok {
|
||||
res.Trailer = make(http.Header, len(trailers))
|
||||
for _, k := range trailers {
|
||||
for _, k := range strings.Split(k, ",") {
|
||||
for k := range strings.SplitSeq(k, ",") {
|
||||
k = http.CanonicalHeaderKey(textproto.TrimString(k))
|
||||
if !validTrailerHeader(k) {
|
||||
if !httpguts.ValidTrailerHeader(k) {
|
||||
// Ignore since forbidden by RFC 7230, section 4.1.2.
|
||||
continue
|
||||
}
|
||||
@@ -251,39 +275,3 @@ func parseContentLength(cl string) int64 {
|
||||
}
|
||||
return int64(n)
|
||||
}
|
||||
|
||||
// ValidTrailerHeader reports whether name is a valid header field name to appear
|
||||
// in trailers.
|
||||
// See RFC 7230, Section 4.1.2
|
||||
// Copied from golang.org/x/net/http/httpguts
|
||||
func validTrailerHeader(name string) bool {
|
||||
name = textproto.CanonicalMIMEHeaderKey(name)
|
||||
if strings.HasPrefix(name, "If-") || badTrailer[name] {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
var badTrailer = map[string]bool{
|
||||
"Authorization": true,
|
||||
"Cache-Control": true,
|
||||
"Connection": true,
|
||||
"Content-Encoding": true,
|
||||
"Content-Length": true,
|
||||
"Content-Range": true,
|
||||
"Content-Type": true,
|
||||
"Expect": true,
|
||||
"Host": true,
|
||||
"Keep-Alive": true,
|
||||
"Max-Forwards": true,
|
||||
"Pragma": true,
|
||||
"Proxy-Authenticate": true,
|
||||
"Proxy-Authorization": true,
|
||||
"Proxy-Connection": true,
|
||||
"Range": true,
|
||||
"Realm": true,
|
||||
"Te": true,
|
||||
"Trailer": true,
|
||||
"Transfer-Encoding": true,
|
||||
"Www-Authenticate": true,
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ func newLocalListener() net.Listener {
|
||||
// When debugging a particular http server-based test,
|
||||
// this flag lets you run
|
||||
//
|
||||
// go test -run=BrokenTest -httptest.serve=127.0.0.1:8000
|
||||
// go test -run='^BrokenTest$' -httptest.serve=127.0.0.1:8000
|
||||
//
|
||||
// to start the broken server so you can interact with it manually.
|
||||
// We only register this flag if it looks like the caller knows about it
|
||||
@@ -94,7 +94,7 @@ func strSliceContainsPrefix(v []string, pre string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// NewServer starts and returns a new Server.
|
||||
// NewServer starts and returns a new [Server].
|
||||
// The caller should call Close when finished, to shut it down.
|
||||
func NewServer(handler http.Handler) *Server {
|
||||
ts := NewUnstartedServer(handler)
|
||||
@@ -102,7 +102,7 @@ func NewServer(handler http.Handler) *Server {
|
||||
return ts
|
||||
}
|
||||
|
||||
// NewUnstartedServer returns a new Server but doesn't start it.
|
||||
// NewUnstartedServer returns a new [Server] but doesn't start it.
|
||||
//
|
||||
// After changing its configuration, the caller should call Start or
|
||||
// StartTLS.
|
||||
@@ -120,6 +120,7 @@ func (s *Server) Start() {
|
||||
if s.URL != "" {
|
||||
panic("Server already started")
|
||||
}
|
||||
|
||||
if s.client == nil {
|
||||
// TINYGO: Removed transport
|
||||
s.client = &http.Client{}
|
||||
@@ -216,7 +217,10 @@ func (s *Server) CloseClientConnections() {
|
||||
|
||||
// Client returns an HTTP client configured for making requests to the server.
|
||||
// It is configured to trust the server's TLS test certificate and will
|
||||
// close its idle connections on Server.Close.
|
||||
// close its idle connections on [Server.Close].
|
||||
// Use Server.URL as the base URL to send requests to the server.
|
||||
// The returned client will also redirect any requests to "example.com"
|
||||
// or its subdomains to the server.
|
||||
func (s *Server) Client() *http.Client {
|
||||
return s.client
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user