mirror of
https://github.com/tinygo-org/net.git
synced 2026-08-13 07:53: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:
+38
-16
@@ -1,4 +1,4 @@
|
||||
// TINYGO: The following is copied and modified from Go 1.21.4 official implementation.
|
||||
// TINYGO: The following is copied and modified from Go 1.26.2 official implementation.
|
||||
|
||||
// TINYGO: atomic.Pointer and atomic.Uint64 are added in Go 1.19, so keep
|
||||
// pre-1.19 code to cover min TinyGo. If TinyGo min moves to 1.19 or higher,
|
||||
@@ -332,12 +332,14 @@ func (c *conn) hijackLocked() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
|
||||
rwc = c.rwc
|
||||
rwc.SetDeadline(time.Time{})
|
||||
|
||||
buf = bufio.NewReadWriter(c.bufr, bufio.NewWriter(rwc))
|
||||
if c.r.hasByte {
|
||||
if _, err := c.bufr.Peek(c.bufr.Buffered() + 1); err != nil {
|
||||
return nil, nil, fmt.Errorf("unexpected Peek failure reading buffered byte: %v", err)
|
||||
}
|
||||
}
|
||||
c.bufw.Reset(rwc)
|
||||
buf = bufio.NewReadWriter(c.bufr, c.bufw)
|
||||
|
||||
c.setState(rwc, StateHijacked, runHooks)
|
||||
return
|
||||
}
|
||||
@@ -592,9 +594,8 @@ type writerOnly struct {
|
||||
// to a *net.TCPConn with sendfile, or from a supported src type such
|
||||
// as a *net.TCPConn on Linux with splice.
|
||||
func (w *response) ReadFrom(src io.Reader) (n int64, err error) {
|
||||
bufp := copyBufPool.Get().(*[]byte)
|
||||
buf := *bufp
|
||||
defer copyBufPool.Put(bufp)
|
||||
buf := getCopyBuf()
|
||||
defer putCopyBuf(buf)
|
||||
|
||||
// Our underlying w.conn.rwc is usually a *TCPConn (with its
|
||||
// own ReadFrom method). If not, just fall back to the normal
|
||||
@@ -620,7 +621,7 @@ func (w *response) ReadFrom(src io.Reader) (n int64, err error) {
|
||||
w.cw.flush() // make sure Header is written; flush data to rwc
|
||||
|
||||
// Now that cw has been flushed, its chunking field is guaranteed initialized.
|
||||
if !w.cw.chunking && w.bodyAllowed() {
|
||||
if !w.cw.chunking && w.bodyAllowed() && w.req.Method != "HEAD" {
|
||||
n0, err := rf.ReadFrom(src)
|
||||
n += n0
|
||||
w.written += n0
|
||||
@@ -824,11 +825,19 @@ var (
|
||||
bufioWriter4kPool sync.Pool
|
||||
)
|
||||
|
||||
var copyBufPool = sync.Pool{
|
||||
New: func() any {
|
||||
b := make([]byte, 32*1024)
|
||||
return &b
|
||||
},
|
||||
const copyBufPoolSize = 32 * 1024
|
||||
|
||||
var copyBufPool = sync.Pool{New: func() any { return new([copyBufPoolSize]byte) }}
|
||||
|
||||
func getCopyBuf() []byte {
|
||||
return copyBufPool.Get().(*[copyBufPoolSize]byte)[:]
|
||||
}
|
||||
|
||||
func putCopyBuf(b []byte) {
|
||||
if len(b) != copyBufPoolSize {
|
||||
panic("trying to put back buffer of the wrong size in the copyBufPool")
|
||||
}
|
||||
copyBufPool.Put((*[copyBufPoolSize]byte)(b))
|
||||
}
|
||||
|
||||
func bufioWriterPool(size int) *sync.Pool {
|
||||
@@ -1770,7 +1779,7 @@ func (c *conn) close() {
|
||||
// from closing a connection with known unread data.
|
||||
// This RST seems to occur mostly on BSD systems. (And Windows?)
|
||||
// This timeout is somewhat arbitrary (~latency around the planet).
|
||||
const rstAvoidanceDelay = 500 * time.Millisecond
|
||||
var rstAvoidanceDelay = 500 * time.Millisecond
|
||||
|
||||
type closeWriter interface {
|
||||
CloseWrite() error
|
||||
@@ -2123,8 +2132,21 @@ func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
|
||||
// writes are done to w.
|
||||
// The error message should be plain text.
|
||||
func Error(w ResponseWriter, error string, code int) {
|
||||
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
h := w.Header()
|
||||
|
||||
// Delete the Content-Length header, which might be for some other content.
|
||||
// Assuming the error string fits in the writer's buffer, we'll figure
|
||||
// out the correct Content-Length for it later.
|
||||
//
|
||||
// We don't delete Content-Encoding, because some middleware sets
|
||||
// Content-Encoding: gzip and wraps the ResponseWriter to compress on-the-fly.
|
||||
// See https://go.dev/issue/66343.
|
||||
h.Del("Content-Length")
|
||||
|
||||
// There might be content type already set, but we reset it to
|
||||
// text/plain for the error message.
|
||||
h.Set("Content-Type", "text/plain; charset=utf-8")
|
||||
h.Set("X-Content-Type-Options", "nosniff")
|
||||
w.WriteHeader(code)
|
||||
fmt.Fprintln(w, error)
|
||||
}
|
||||
@@ -2181,7 +2203,7 @@ func Redirect(w ResponseWriter, r *Request, url string, code int) {
|
||||
// but doing it ourselves is more reliable.
|
||||
// See RFC 7231, section 7.1.2
|
||||
if u.Scheme == "" && u.Host == "" {
|
||||
oldpath := r.URL.Path
|
||||
oldpath := r.URL.EscapedPath()
|
||||
if oldpath == "" { // should not happen, but avoid a crash if it does
|
||||
oldpath = "/"
|
||||
}
|
||||
@@ -3151,7 +3173,7 @@ func (s *Server) trackConn(c *conn, add bool) {
|
||||
}
|
||||
|
||||
func (s *Server) idleTimeout() time.Duration {
|
||||
if s.IdleTimeout != 0 {
|
||||
if s.IdleTimeout > 0 {
|
||||
return s.IdleTimeout
|
||||
}
|
||||
return s.ReadTimeout
|
||||
|
||||
Reference in New Issue
Block a user