Merge branch 'master' of https://github.com/golang/go into typo-corrections-http-net-server

This commit is contained in:
The Backend Grip 2024-04-29 23:14:00 +02:00
commit d35753c7e0
7 changed files with 72 additions and 54 deletions

View File

@ -12,13 +12,13 @@ package json
import ( import (
"bytes" "bytes"
"cmp"
"encoding" "encoding"
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"math" "math"
"reflect" "reflect"
"slices" "slices"
"sort"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -1162,21 +1162,23 @@ func typeFields(t reflect.Type) structFields {
} }
} }
sort.Slice(fields, func(i, j int) bool { slices.SortFunc(fields, func(a, b field) int {
x := fields
// sort field by name, breaking ties with depth, then // sort field by name, breaking ties with depth, then
// breaking ties with "name came from json tag", then // breaking ties with "name came from json tag", then
// breaking ties with index sequence. // breaking ties with index sequence.
if x[i].name != x[j].name { if c := strings.Compare(a.name, b.name); c != 0 {
return x[i].name < x[j].name return c
} }
if len(x[i].index) != len(x[j].index) { if c := cmp.Compare(len(a.index), len(b.index)); c != 0 {
return len(x[i].index) < len(x[j].index) return c
} }
if x[i].tag != x[j].tag { if a.tag != b.tag {
return x[i].tag if a.tag {
return -1
} }
return slices.Compare(x[i].index, x[j].index) == -1 return +1
}
return slices.Compare(a.index, b.index)
}) })
// Delete all fields that are hidden by the Go rules for embedded fields, // Delete all fields that are hidden by the Go rules for embedded fields,

View File

@ -183,7 +183,7 @@ type Flusher interface {
// should always test for this ability at runtime. // should always test for this ability at runtime.
type Hijacker interface { type Hijacker interface {
// Hijack lets the caller take over the connection. // Hijack lets the caller take over the connection.
// After a call to Hijack, the HTTP server library // After a call to Hijack the HTTP server library
// will not do anything else with the connection. // will not do anything else with the connection.
// //
// It becomes the caller's responsibility to manage // It becomes the caller's responsibility to manage
@ -224,7 +224,7 @@ type CloseNotifier interface {
// that the channel receives a value. // that the channel receives a value.
// //
// If the protocol is HTTP/1.1 and CloseNotify is called while // If the protocol is HTTP/1.1 and CloseNotify is called while
// processing an idempotent request (such as a GET) while // processing an idempotent request (such as GET) while
// HTTP/1.1 pipelining is in use, the arrival of a subsequent // HTTP/1.1 pipelining is in use, the arrival of a subsequent
// pipelined request may cause a value to be sent on the // pipelined request may cause a value to be sent on the
// returned channel. In practice HTTP/1.1 pipelining is not // returned channel. In practice HTTP/1.1 pipelining is not
@ -1102,9 +1102,9 @@ func (w *response) Header() Header {
// maxPostHandlerReadBytes is the max number of Request.Body bytes not // maxPostHandlerReadBytes is the max number of Request.Body bytes not
// consumed by a handler that the server will read from the client // consumed by a handler that the server will read from the client
// in order to keep a connection alive. If there are more bytes than // in order to keep a connection alive. If there are more bytes
// this, it makes the server paranoid instead and sends a "Connection: // than this, the server, to be paranoid, instead sends a
// close" response. // "Connection close" response.
// //
// This number is approximately what a typical machine's TCP buffer // This number is approximately what a typical machine's TCP buffer
// size is anyway. (if we have the bytes on the machine, we might as // size is anyway. (if we have the bytes on the machine, we might as

View File

@ -109,17 +109,11 @@ func queryDNS(ctx context.Context, addr string, typ string) (res []string, err e
func handlePlan9DNSError(err error, name string) error { func handlePlan9DNSError(err error, name string) error {
if stringsHasSuffix(err.Error(), "dns: name does not exist") || if stringsHasSuffix(err.Error(), "dns: name does not exist") ||
stringsHasSuffix(err.Error(), "dns: resource does not exist; negrcode 0") || stringsHasSuffix(err.Error(), "dns: resource does not exist; negrcode 0") ||
stringsHasSuffix(err.Error(), "dns: resource does not exist; negrcode") { stringsHasSuffix(err.Error(), "dns: resource does not exist; negrcode") ||
return &DNSError{ stringsHasSuffix(err.Error(), "dns failure") {
Err: errNoSuchHost.Error(), err = errNoSuchHost
Name: name,
IsNotFound: true,
}
}
return &DNSError{
Err: err.Error(),
Name: name,
} }
return newDNSError(err, name, "")
} }
// toLower returns a lower-case version of in. Restricting us to // toLower returns a lower-case version of in. Restricting us to
@ -169,10 +163,7 @@ func (*Resolver) lookupHost(ctx context.Context, host string) (addrs []string, e
// host names in local network (e.g. from /lib/ndb/local) // host names in local network (e.g. from /lib/ndb/local)
lines, err := queryCS(ctx, "net", host, "1") lines, err := queryCS(ctx, "net", host, "1")
if err != nil { if err != nil {
if stringsHasSuffix(err.Error(), "dns failure") { return nil, handlePlan9DNSError(err, host)
err = errNoSuchHost
}
return nil, newDNSError(err, host, "")
} }
loop: loop:
for _, line := range lines { for _, line := range lines {

View File

@ -1634,6 +1634,10 @@ func TestLookupNoSuchHost(t *testing.T) {
} }
func TestDNSErrorUnwrap(t *testing.T) { func TestDNSErrorUnwrap(t *testing.T) {
if runtime.GOOS == "plan9" {
// The Plan 9 implementation of the resolver doesn't use the Dial function yet. See https://go.dev/cl/409234
t.Skip("skipping on plan9")
}
rDeadlineExcceeded := &Resolver{PreferGo: true, Dial: func(ctx context.Context, network, address string) (Conn, error) { rDeadlineExcceeded := &Resolver{PreferGo: true, Dial: func(ctx context.Context, network, address string) (Conn, error) {
return nil, context.DeadlineExceeded return nil, context.DeadlineExceeded
}} }}

View File

@ -814,6 +814,22 @@ func validOptionalPort(port string) bool {
// - if u.Fragment is empty, #fragment is omitted. // - if u.Fragment is empty, #fragment is omitted.
func (u *URL) String() string { func (u *URL) String() string {
var buf strings.Builder var buf strings.Builder
n := len(u.Scheme)
if u.Opaque != "" {
n += len(u.Opaque)
} else {
if !u.OmitHost && (u.Scheme != "" || u.Host != "" || u.User != nil) {
username := u.User.Username()
password, _ := u.User.Password()
n += len(username) + len(password) + len(u.Host)
}
n += len(u.Path)
}
n += len(u.RawQuery) + len(u.RawFragment)
n += len(":" + "//" + "//" + ":" + "@" + "/" + "./" + "?" + "#")
buf.Grow(n)
if u.Scheme != "" { if u.Scheme != "" {
buf.WriteString(u.Scheme) buf.WriteString(u.Scheme)
buf.WriteByte(':') buf.WriteByte(':')

View File

@ -355,7 +355,9 @@ func Clone[S ~[]E, E any](s S) S {
// which may have a smaller length. // which may have a smaller length.
// Compact zeroes the elements between the new length and the original length. // Compact zeroes the elements between the new length and the original length.
func Compact[S ~[]E, E comparable](s S) S { func Compact[S ~[]E, E comparable](s S) S {
if len(s) > 1 { if len(s) < 2 {
return s
}
for k := 1; k < len(s); k++ { for k := 1; k < len(s); k++ {
if s[k] == s[k-1] { if s[k] == s[k-1] {
s2 := s[k:] s2 := s[k:]
@ -370,7 +372,6 @@ func Compact[S ~[]E, E comparable](s S) S {
return s[:k] return s[:k]
} }
} }
}
return s return s
} }
@ -378,7 +379,9 @@ func Compact[S ~[]E, E comparable](s S) S {
// For runs of elements that compare equal, CompactFunc keeps the first one. // For runs of elements that compare equal, CompactFunc keeps the first one.
// CompactFunc zeroes the elements between the new length and the original length. // CompactFunc zeroes the elements between the new length and the original length.
func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S { func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S {
if len(s) > 1 { if len(s) < 2 {
return s
}
for k := 1; k < len(s); k++ { for k := 1; k < len(s); k++ {
if eq(s[k], s[k-1]) { if eq(s[k], s[k-1]) {
s2 := s[k:] s2 := s[k:]
@ -393,7 +396,6 @@ func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S {
return s[:k] return s[:k]
} }
} }
}
return s return s
} }

View File

@ -53,7 +53,10 @@
// //
// On some systems the monotonic clock will stop if the computer goes to sleep. // On some systems the monotonic clock will stop if the computer goes to sleep.
// On such a system, t.Sub(u) may not accurately reflect the actual // On such a system, t.Sub(u) may not accurately reflect the actual
// time that passed between t and u. // time that passed between t and u. The same applies to other functions and
// methods that subtract times, such as [Since], [Until], [Before], [After],
// [Add], [Sub], [Equal] and [Compare]. In some cases, you may need to strip
// the monotonic clock to get accurate results.
// //
// Because the monotonic clock reading has no meaning outside // Because the monotonic clock reading has no meaning outside
// the current process, the serialized forms generated by t.GobEncode, // the current process, the serialized forms generated by t.GobEncode,