mirror of
https://github.com/golang/go.git
synced 2026-04-04 02:10:08 +09:00
net/http/internal/http2: modernize the package
This CL is mostly generated by running go fix. Manual edits have also been selectively done to modernize the package where doing so is straightforward; for example, using slices.Contains in lieu of strSliceContains. Change-Id: Ie2942481672c56c370e2df0f172cf3e480a12bc5 Reviewed-on: https://go-review.googlesource.com/c/go/+/757220 Reviewed-by: Nicholas Husin <husin@google.com> Reviewed-by: Nicholas Husin <nsh@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
committed by
Nicholas Husin
parent
224489f11c
commit
e1bc5cea82
@@ -10,6 +10,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"net"
|
||||
"slices"
|
||||
"sync"
|
||||
)
|
||||
|
||||
@@ -211,10 +212,8 @@ func (c *addConnCall) run(t *Transport, key string, nc net.Conn) {
|
||||
|
||||
// p.mu must be held
|
||||
func (p *clientConnPool) addConnLocked(key string, cc *ClientConn) {
|
||||
for _, v := range p.conns[key] {
|
||||
if v == cc {
|
||||
return
|
||||
}
|
||||
if slices.Contains(p.conns[key], cc) {
|
||||
return
|
||||
}
|
||||
if p.conns == nil {
|
||||
p.conns = make(map[string][]*ClientConn)
|
||||
|
||||
@@ -21,11 +21,11 @@ import (
|
||||
// improved enough that we can instead allocate chunks like this:
|
||||
// make([]byte, max(16<<10, expectedBytesRemaining))
|
||||
var dataChunkPools = [...]sync.Pool{
|
||||
{New: func() interface{} { return new([1 << 10]byte) }},
|
||||
{New: func() interface{} { return new([2 << 10]byte) }},
|
||||
{New: func() interface{} { return new([4 << 10]byte) }},
|
||||
{New: func() interface{} { return new([8 << 10]byte) }},
|
||||
{New: func() interface{} { return new([16 << 10]byte) }},
|
||||
{New: func() any { return new([1 << 10]byte) }},
|
||||
{New: func() any { return new([2 << 10]byte) }},
|
||||
{New: func() any { return new([4 << 10]byte) }},
|
||||
{New: func() any { return new([8 << 10]byte) }},
|
||||
{New: func() any { return new([16 << 10]byte) }},
|
||||
}
|
||||
|
||||
func getDataBufferChunk(size int64) []byte {
|
||||
@@ -121,10 +121,7 @@ func (b *dataBuffer) Write(p []byte) (int, error) {
|
||||
// If the last chunk is empty, allocate a new chunk. Try to allocate
|
||||
// enough to fully copy p plus any additional bytes we expect to
|
||||
// receive. However, this may allocate less than len(p).
|
||||
want := int64(len(p))
|
||||
if b.expected > want {
|
||||
want = b.expected
|
||||
}
|
||||
want := max(b.expected, int64(len(p)))
|
||||
chunk := b.lastChunkOrAlloc(want)
|
||||
n := copy(chunk[b.w:], p)
|
||||
p = p[n:]
|
||||
|
||||
@@ -8,36 +8,37 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func fmtDataChunk(chunk []byte) string {
|
||||
out := ""
|
||||
var out strings.Builder
|
||||
var last byte
|
||||
var count int
|
||||
for _, c := range chunk {
|
||||
if c != last {
|
||||
if count > 0 {
|
||||
out += fmt.Sprintf(" x %d ", count)
|
||||
out.WriteString(fmt.Sprintf(" x %d ", count))
|
||||
count = 0
|
||||
}
|
||||
out += string([]byte{c})
|
||||
out.WriteString(string([]byte{c}))
|
||||
last = c
|
||||
}
|
||||
count++
|
||||
}
|
||||
if count > 0 {
|
||||
out += fmt.Sprintf(" x %d", count)
|
||||
out.WriteString(fmt.Sprintf(" x %d", count))
|
||||
}
|
||||
return out
|
||||
return out.String()
|
||||
}
|
||||
|
||||
func fmtDataChunks(chunks [][]byte) string {
|
||||
var out string
|
||||
var out strings.Builder
|
||||
for _, chunk := range chunks {
|
||||
out += fmt.Sprintf("{%q}", fmtDataChunk(chunk))
|
||||
out.WriteString(fmt.Sprintf("{%q}", fmtDataChunk(chunk)))
|
||||
}
|
||||
return out
|
||||
return out.String()
|
||||
}
|
||||
|
||||
func testDataBuffer(t *testing.T, wantBytes []byte, setup func(t *testing.T) *dataBuffer) {
|
||||
|
||||
@@ -104,14 +104,14 @@ func (e StreamError) As(target any) bool {
|
||||
if dstType.NumField() != numField {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < numField; i++ {
|
||||
for i := range numField {
|
||||
sf := srcType.Field(i)
|
||||
df := dstType.Field(i)
|
||||
if sf.Name != df.Name || !sf.Type.ConvertibleTo(df.Type) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
for i := 0; i < numField; i++ {
|
||||
for i := range numField {
|
||||
df := dst.Field(i)
|
||||
df.Set(src.Field(i).Convert(df.Type()))
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ func init() {
|
||||
testHookOnPanicMu = new(sync.Mutex)
|
||||
}
|
||||
|
||||
func SetTestHookOnPanic(t testing.TB, f func(sc *serverConn, panicVal interface{}) (rePanic bool)) {
|
||||
func SetTestHookOnPanic(t testing.TB, f func(sc *serverConn, panicVal any) (rePanic bool)) {
|
||||
testHookOnPanicMu.Lock()
|
||||
defer testHookOnPanicMu.Unlock()
|
||||
old := testHookOnPanic
|
||||
|
||||
@@ -196,7 +196,7 @@ func (h FrameHeader) writeDebug(buf *bytes.Buffer) {
|
||||
if h.Flags != 0 {
|
||||
buf.WriteString(" flags=")
|
||||
set := 0
|
||||
for i := uint8(0); i < 8; i++ {
|
||||
for i := range uint8(8) {
|
||||
if h.Flags&(1<<i) == 0 {
|
||||
continue
|
||||
}
|
||||
@@ -229,7 +229,7 @@ func (h *FrameHeader) invalidate() { h.valid = false }
|
||||
// frame header bytes.
|
||||
// Used only by ReadFrameHeader.
|
||||
var fhBytes = sync.Pool{
|
||||
New: func() interface{} {
|
||||
New: func() any {
|
||||
buf := make([]byte, frameHeaderLen)
|
||||
return &buf
|
||||
},
|
||||
@@ -343,8 +343,8 @@ type Framer struct {
|
||||
|
||||
debugFramer *Framer // only use for logging written writes
|
||||
debugFramerBuf *bytes.Buffer
|
||||
debugReadLoggerf func(string, ...interface{})
|
||||
debugWriteLoggerf func(string, ...interface{})
|
||||
debugReadLoggerf func(string, ...any)
|
||||
debugWriteLoggerf func(string, ...any)
|
||||
|
||||
frameCache *frameCache // nil if frames aren't reused (default)
|
||||
}
|
||||
@@ -838,7 +838,7 @@ func (f *SettingsFrame) HasDuplicates() bool {
|
||||
// If it's small enough (the common case), just do the n^2
|
||||
// thing and avoid a map allocation.
|
||||
if num < 10 {
|
||||
for i := 0; i < num; i++ {
|
||||
for i := range num {
|
||||
idi := f.Setting(i).ID
|
||||
for j := i + 1; j < num; j++ {
|
||||
idj := f.Setting(j).ID
|
||||
@@ -850,7 +850,7 @@ func (f *SettingsFrame) HasDuplicates() bool {
|
||||
return false
|
||||
}
|
||||
seen := map[SettingID]bool{}
|
||||
for i := 0; i < num; i++ {
|
||||
for i := range num {
|
||||
id := f.Setting(i).ID
|
||||
if seen[id] {
|
||||
return true
|
||||
|
||||
@@ -1132,7 +1132,7 @@ func TestMetaFrameHeader(t *testing.T) {
|
||||
tests := [...]struct {
|
||||
name string
|
||||
w func(*Framer)
|
||||
want interface{} // *MetaHeaderFrame or error
|
||||
want any // *MetaHeaderFrame or error
|
||||
wantErrReason string
|
||||
maxHeaderListSize uint32
|
||||
}{
|
||||
@@ -1181,7 +1181,7 @@ func TestMetaFrameHeader(t *testing.T) {
|
||||
name: "max_header_list_truncated",
|
||||
w: func(f *Framer) {
|
||||
var pairs = []string{":method", "GET", ":path", "/"}
|
||||
for i := 0; i < 100; i++ {
|
||||
for range 100 {
|
||||
pairs = append(pairs, "foo", "bar")
|
||||
}
|
||||
all := encodeHeaderRaw(t, pairs...)
|
||||
@@ -1279,7 +1279,7 @@ func TestMetaFrameHeader(t *testing.T) {
|
||||
name = fmt.Sprintf("test index %d", i)
|
||||
}
|
||||
|
||||
var got interface{}
|
||||
var got any
|
||||
var err error
|
||||
got, err = f.ReadFrame()
|
||||
if err != nil {
|
||||
@@ -1302,7 +1302,7 @@ func TestMetaFrameHeader(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
str := func(v interface{}) string {
|
||||
str := func(v any) string {
|
||||
if _, ok := v.(error); ok {
|
||||
return fmt.Sprintf("error %v", v)
|
||||
} else {
|
||||
@@ -1325,21 +1325,21 @@ func TestSetReuseFrames(t *testing.T) {
|
||||
// SetReuseFrames only currently implements reuse of DataFrames.
|
||||
firstDf := readAndVerifyDataFrame("ABC", 3, fr, buf, t)
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
for range 10 {
|
||||
df := readAndVerifyDataFrame("XYZ", 3, fr, buf, t)
|
||||
if df != firstDf {
|
||||
t.Errorf("Expected Framer to return references to the same DataFrame. Have %v and %v", &df, &firstDf)
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
for range 10 {
|
||||
df := readAndVerifyDataFrame("", 0, fr, buf, t)
|
||||
if df != firstDf {
|
||||
t.Errorf("Expected Framer to return references to the same DataFrame. Have %v and %v", &df, &firstDf)
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
for range 10 {
|
||||
df := readAndVerifyDataFrame("HHH", 3, fr, buf, t)
|
||||
if df != firstDf {
|
||||
t.Errorf("Expected Framer to return references to the same DataFrame. Have %v and %v", &df, &firstDf)
|
||||
@@ -1354,7 +1354,7 @@ func TestSetReuseFramesMoreThanOnce(t *testing.T) {
|
||||
firstDf := readAndVerifyDataFrame("ABC", 3, fr, buf, t)
|
||||
fr.SetReuseFrames()
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
for range 10 {
|
||||
df := readAndVerifyDataFrame("XYZ", 3, fr, buf, t)
|
||||
// SetReuseFrames should be idempotent
|
||||
fr.SetReuseFrames()
|
||||
@@ -1367,11 +1367,11 @@ func TestSetReuseFramesMoreThanOnce(t *testing.T) {
|
||||
func TestNoSetReuseFrames(t *testing.T) {
|
||||
fr, buf := testFramer()
|
||||
const numNewDataFrames = 10
|
||||
dfSoFar := make([]interface{}, numNewDataFrames)
|
||||
dfSoFar := make([]any, numNewDataFrames)
|
||||
|
||||
// Check that DataFrames are not reused if SetReuseFrames wasn't called.
|
||||
// SetReuseFrames only currently implements reuse of DataFrames.
|
||||
for i := 0; i < numNewDataFrames; i++ {
|
||||
for i := range numNewDataFrames {
|
||||
df := readAndVerifyDataFrame("XYZ", 3, fr, buf, t)
|
||||
for _, item := range dfSoFar {
|
||||
if df == item {
|
||||
|
||||
@@ -79,7 +79,7 @@ func curGoroutineID() uint64 {
|
||||
}
|
||||
|
||||
var littleBuf = sync.Pool{
|
||||
New: func() interface{} {
|
||||
New: func() any {
|
||||
buf := make([]byte, 64)
|
||||
return &buf
|
||||
},
|
||||
|
||||
@@ -14,7 +14,7 @@ func TestGoroutineLock(t *testing.T) {
|
||||
g := newGoroutineLock()
|
||||
g.check()
|
||||
|
||||
sawPanic := make(chan interface{})
|
||||
sawPanic := make(chan any)
|
||||
go func() {
|
||||
defer func() { sawPanic <- recover() }()
|
||||
g.check() // should panic
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"sort"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -273,7 +273,7 @@ func newBufferedWriter(conn net.Conn, timeout time.Duration) *bufferedWriter {
|
||||
const bufWriterPoolBufferSize = 4 << 10
|
||||
|
||||
var bufWriterPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
New: func() any {
|
||||
return bufio.NewWriterSize(nil, bufWriterPoolBufferSize)
|
||||
},
|
||||
}
|
||||
@@ -376,16 +376,12 @@ type connectionStater interface {
|
||||
ConnectionState() tls.ConnectionState
|
||||
}
|
||||
|
||||
var sorterPool = sync.Pool{New: func() interface{} { return new(sorter) }}
|
||||
var sorterPool = sync.Pool{New: func() any { return new(sorter) }}
|
||||
|
||||
type sorter struct {
|
||||
v []string // owned by sorter
|
||||
}
|
||||
|
||||
func (s *sorter) Len() int { return len(s.v) }
|
||||
func (s *sorter) Swap(i, j int) { s.v[i], s.v[j] = s.v[j], s.v[i] }
|
||||
func (s *sorter) Less(i, j int) bool { return s.v[i] < s.v[j] }
|
||||
|
||||
// Keys returns the sorted keys of h.
|
||||
//
|
||||
// The returned slice is only valid until s used again or returned to
|
||||
@@ -396,19 +392,10 @@ func (s *sorter) Keys(h Header) []string {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
s.v = keys
|
||||
sort.Sort(s)
|
||||
slices.Sort(s.v)
|
||||
return keys
|
||||
}
|
||||
|
||||
func (s *sorter) SortStrings(ss []string) {
|
||||
// Our sorter works on s.v, which sorter owns, so
|
||||
// stash it away while we sort the user's buffer.
|
||||
save := s.v
|
||||
s.v = ss
|
||||
sort.Sort(s)
|
||||
s.v = save
|
||||
}
|
||||
|
||||
// incomparable is a zero-width, non-comparable type. Adding it to a struct
|
||||
// makes that struct also non-comparable, and generally doesn't add
|
||||
// any size (as long as it's first).
|
||||
|
||||
@@ -45,7 +45,6 @@ func TestSettingString(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSorterPoolAllocs(t *testing.T) {
|
||||
ss := []string{"a", "b", "c"}
|
||||
h := Header{
|
||||
"a": nil,
|
||||
"b": nil,
|
||||
@@ -53,12 +52,6 @@ func TestSorterPoolAllocs(t *testing.T) {
|
||||
}
|
||||
sorter := new(sorter)
|
||||
|
||||
if allocs := testing.AllocsPerRun(100, func() {
|
||||
sorter.SortStrings(ss)
|
||||
}); allocs >= 1 {
|
||||
t.Logf("SortStrings allocs = %v; want <1", allocs)
|
||||
}
|
||||
|
||||
if allocs := testing.AllocsPerRun(5, func() {
|
||||
if len(sorter.Keys(h)) != 3 {
|
||||
t.Fatal("wrong result")
|
||||
|
||||
@@ -44,6 +44,7 @@ import (
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -73,7 +74,7 @@ var (
|
||||
)
|
||||
|
||||
var responseWriterStatePool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
New: func() any {
|
||||
rws := &responseWriterState{}
|
||||
rws.bw = bufio.NewWriterSize(chunkWriter{rws}, handlerChunkWriteSize)
|
||||
return rws
|
||||
@@ -84,7 +85,7 @@ var responseWriterStatePool = sync.Pool{
|
||||
var (
|
||||
testHookOnConn func()
|
||||
testHookOnPanicMu *sync.Mutex // nil except in tests
|
||||
testHookOnPanic func(sc *serverConn, panicVal interface{}) (rePanic bool)
|
||||
testHookOnPanic func(sc *serverConn, panicVal any) (rePanic bool)
|
||||
)
|
||||
|
||||
// Server is an HTTP/2 server.
|
||||
@@ -357,7 +358,7 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon
|
||||
streams: make(map[uint32]*stream),
|
||||
readFrameCh: make(chan readFrameResult),
|
||||
wantWriteFrameCh: make(chan FrameWriteRequest, 8),
|
||||
serveMsgCh: make(chan interface{}, 8),
|
||||
serveMsgCh: make(chan any, 8),
|
||||
wroteFrameCh: make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync
|
||||
bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way
|
||||
doneServing: make(chan struct{}),
|
||||
@@ -510,7 +511,7 @@ type serverConn struct {
|
||||
wantWriteFrameCh chan FrameWriteRequest // from handlers -> serve
|
||||
wroteFrameCh chan frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes
|
||||
bodyReadCh chan bodyReadMsg // from handlers -> serve
|
||||
serveMsgCh chan interface{} // misc messages & code to send to / run on the serve loop
|
||||
serveMsgCh chan any // misc messages & code to send to / run on the serve loop
|
||||
flow outflow // conn-wide (not stream-specific) outbound flow control
|
||||
inflow inflow // conn-wide inbound flow control
|
||||
tlsState *tls.ConnectionState // shared by all handlers, like net/http
|
||||
@@ -667,13 +668,13 @@ func (sc *serverConn) setConnState(state ConnState) {
|
||||
sc.hs.ConnState(sc.conn, state)
|
||||
}
|
||||
|
||||
func (sc *serverConn) vlogf(format string, args ...interface{}) {
|
||||
func (sc *serverConn) vlogf(format string, args ...any) {
|
||||
if VerboseLogs {
|
||||
sc.logf(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (sc *serverConn) logf(format string, args ...interface{}) {
|
||||
func (sc *serverConn) logf(format string, args ...any) {
|
||||
if lg := sc.hs.ErrorLog(); lg != nil {
|
||||
lg.Printf(format, args...)
|
||||
} else {
|
||||
@@ -721,7 +722,7 @@ func isClosedConnError(err error) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (sc *serverConn) condlogf(err error, format string, args ...interface{}) {
|
||||
func (sc *serverConn) condlogf(err error, format string, args ...any) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
@@ -1042,7 +1043,7 @@ func (sc *serverConn) onIdleTimer() { sc.sendServeMsg(idleTimerMsg) }
|
||||
func (sc *serverConn) onReadIdleTimer() { sc.sendServeMsg(readIdleTimerMsg) }
|
||||
func (sc *serverConn) onShutdownTimer() { sc.sendServeMsg(shutdownTimerMsg) }
|
||||
|
||||
func (sc *serverConn) sendServeMsg(msg interface{}) {
|
||||
func (sc *serverConn) sendServeMsg(msg any) {
|
||||
sc.serveG.checkNotOn() // NOT
|
||||
select {
|
||||
case sc.serveMsgCh <- msg:
|
||||
@@ -1087,7 +1088,7 @@ func (sc *serverConn) readPreface() error {
|
||||
}
|
||||
|
||||
var writeDataPool = sync.Pool{
|
||||
New: func() interface{} { return new(writeData) },
|
||||
New: func() any { return new(writeData) },
|
||||
}
|
||||
|
||||
// writeDataFromHandler writes DATA response frames from a handler on
|
||||
@@ -2596,7 +2597,7 @@ func (rws *responseWriterState) declareTrailer(k string) {
|
||||
rws.conn.logf("ignoring invalid trailer %q", k)
|
||||
return
|
||||
}
|
||||
if !strSliceContains(rws.trailers, k) {
|
||||
if !slices.Contains(rws.trailers, k) {
|
||||
rws.trailers = append(rws.trailers, k)
|
||||
}
|
||||
}
|
||||
@@ -2759,9 +2760,7 @@ func (rws *responseWriterState) promoteUndeclaredTrailers() {
|
||||
}
|
||||
|
||||
if len(rws.trailers) > 1 {
|
||||
sorter := sorterPool.Get().(*sorter)
|
||||
sorter.SortStrings(rws.trailers)
|
||||
sorterPool.Put(sorter)
|
||||
slices.Sort(rws.trailers)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3206,7 +3205,7 @@ func foreachHeaderElement(v string, fn func(string)) {
|
||||
fn(v)
|
||||
return
|
||||
}
|
||||
for _, f := range strings.Split(v, ",") {
|
||||
for f := range strings.SplitSeq(v, ",") {
|
||||
if f = textproto.TrimString(f); f != "" {
|
||||
fn(f)
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ func testServer_Push_Success(t testing.TB) {
|
||||
// Send one request, which should push two responses.
|
||||
st.greet()
|
||||
getSlash(st)
|
||||
for k := 0; k < 3; k++ {
|
||||
for k := range 3 {
|
||||
select {
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Errorf("timeout waiting for handler %d to finish", k)
|
||||
@@ -277,7 +277,7 @@ func testServer_Push_SuccessNoRace(t testing.TB) {
|
||||
// Send one request, which should push one response.
|
||||
st.greet()
|
||||
getSlash(st)
|
||||
for k := 0; k < 2; k++ {
|
||||
for k := range 2 {
|
||||
select {
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Errorf("timeout waiting for handler %d to finish", k)
|
||||
@@ -543,7 +543,7 @@ func testServer_Push_Underflow(t testing.TB) {
|
||||
// Send several requests.
|
||||
st.greet()
|
||||
const numRequests = 4
|
||||
for i := 0; i < numRequests; i++ {
|
||||
for i := range numRequests {
|
||||
st.writeHeaders(HeadersFrameParam{
|
||||
StreamID: uint32(1 + i*2), // clients send odd numbers
|
||||
BlockFragment: st.encodeHeader(),
|
||||
|
||||
@@ -119,7 +119,7 @@ func (w twriter) Write(p []byte) (n int, err error) {
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func newTestServer(t testing.TB, handler http.HandlerFunc, opts ...interface{}) *httptest.Server {
|
||||
func newTestServer(t testing.TB, handler http.HandlerFunc, opts ...any) *httptest.Server {
|
||||
t.Helper()
|
||||
if handler == nil {
|
||||
handler = func(w http.ResponseWriter, req *http.Request) {}
|
||||
@@ -173,7 +173,7 @@ var optQuiet = func(server *http.Server) {
|
||||
server.ErrorLog = log.New(io.Discard, "", 0)
|
||||
}
|
||||
|
||||
func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}) *serverTester {
|
||||
func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...any) *serverTester {
|
||||
t.Helper()
|
||||
|
||||
h1server := &http.Server{}
|
||||
@@ -436,7 +436,7 @@ func (st *serverTester) greetAndCheckSettings(checkSetting func(s Setting) error
|
||||
var gotSettingsAck bool
|
||||
var gotWindowUpdate bool
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
for range 2 {
|
||||
f := st.readFrame()
|
||||
if f == nil {
|
||||
st.t.Fatal("wanted a settings ACK and window update, got none")
|
||||
@@ -1218,7 +1218,7 @@ func testServer_MaxQueuedControlFrames(t testing.TB) {
|
||||
// Send maxQueuedControlFrames pings, plus a few extra
|
||||
// to account for ones that enter the server's write buffer.
|
||||
const extraPings = 2
|
||||
for i := 0; i < MaxQueuedControlFrames+extraPings; i++ {
|
||||
for range MaxQueuedControlFrames + extraPings {
|
||||
pingData := [8]byte{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
st.fr.WritePing(false, pingData)
|
||||
}
|
||||
@@ -1230,7 +1230,7 @@ func testServer_MaxQueuedControlFrames(t testing.TB) {
|
||||
|
||||
st.advance(GoAwayTimeout)
|
||||
// Some frames may have persisted in the server's buffers.
|
||||
for i := 0; i < 10; i++ {
|
||||
for range 10 {
|
||||
if st.readFrame() == nil {
|
||||
break
|
||||
}
|
||||
@@ -1925,7 +1925,6 @@ func TestServerRejectsContentLengthWithSignNewRequests(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
synctestSubtest(t, tt.name, func(t testing.TB) {
|
||||
writeReq := func(st *serverTester) {
|
||||
st.writeHeaders(HeadersFrameParam{
|
||||
@@ -2404,7 +2403,7 @@ func testServer_Rejects_Too_Many_Streams(t testing.TB) {
|
||||
})
|
||||
}
|
||||
var calls []*serverHandlerCall
|
||||
for i := 0; i < DefaultMaxStreams; i++ {
|
||||
for range DefaultMaxStreams {
|
||||
sendReq(streamID())
|
||||
calls = append(calls, st.nextHandlerCall())
|
||||
}
|
||||
@@ -2451,7 +2450,7 @@ func TestServer_Response_ManyHeaders_With_Continuation(t *testing.T) {
|
||||
func testServer_Response_ManyHeaders_With_Continuation(t testing.TB) {
|
||||
testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
|
||||
h := w.Header()
|
||||
for i := 0; i < 5000; i++ {
|
||||
for i := range 5000 {
|
||||
h.Set(fmt.Sprintf("x-header-%d", i), fmt.Sprintf("x-value-%d", i))
|
||||
}
|
||||
return nil
|
||||
@@ -2526,10 +2525,10 @@ func testServer_NoCrash_HandlerClose_Then_ClientClose(t testing.TB) {
|
||||
// previously.
|
||||
var (
|
||||
panMu sync.Mutex
|
||||
panicVal interface{}
|
||||
panicVal any
|
||||
)
|
||||
|
||||
SetTestHookOnPanic(t, func(sc *ServerConn, pv interface{}) bool {
|
||||
SetTestHookOnPanic(t, func(sc *ServerConn, pv any) bool {
|
||||
panMu.Lock()
|
||||
panicVal = pv
|
||||
panMu.Unlock()
|
||||
@@ -3544,7 +3543,7 @@ func testIssue20704Race(t testing.TB) {
|
||||
)
|
||||
|
||||
ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
for i := 0; i < itemCount; i++ {
|
||||
for range itemCount {
|
||||
_, err := w.Write(make([]byte, itemSize))
|
||||
if err != nil {
|
||||
return
|
||||
@@ -3559,7 +3558,7 @@ func testIssue20704Race(t testing.TB) {
|
||||
defer tr.CloseIdleConnections()
|
||||
cl := &http.Client{Transport: tr}
|
||||
|
||||
for i := 0; i < 1000; i++ {
|
||||
for range 1000 {
|
||||
resp, err := cl.Get(ts.URL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -3792,7 +3791,7 @@ func TestContentEncodingNoSniffing(t *testing.T) {
|
||||
// setting Content-Encoding as an interface instead of a string
|
||||
// directly, so as to differentiate between 3 states:
|
||||
// unset, empty string "" and set string "foo/bar".
|
||||
contentEncoding interface{}
|
||||
contentEncoding any
|
||||
wantContentType string
|
||||
}
|
||||
|
||||
@@ -4271,7 +4270,7 @@ func testServerMaxHandlerGoroutines(t testing.TB) {
|
||||
// Reset them all, but only after the handler goroutines have started.
|
||||
var stops []chan bool
|
||||
streamID := uint32(1)
|
||||
for i := 0; i < maxHandlers; i++ {
|
||||
for range maxHandlers {
|
||||
st.writeHeaders(HeadersFrameParam{
|
||||
StreamID: streamID,
|
||||
BlockFragment: st.encodeHeader(),
|
||||
@@ -4294,7 +4293,7 @@ func testServerMaxHandlerGoroutines(t testing.TB) {
|
||||
streamID += 2
|
||||
|
||||
// Start another two requests. Don't reset these.
|
||||
for i := 0; i < 2; i++ {
|
||||
for range 2 {
|
||||
st.writeHeaders(HeadersFrameParam{
|
||||
StreamID: streamID,
|
||||
BlockFragment: st.encodeHeader(),
|
||||
@@ -4322,7 +4321,7 @@ func testServerMaxHandlerGoroutines(t testing.TB) {
|
||||
|
||||
// Make a bunch more requests.
|
||||
// Eventually, the server tells us to go away.
|
||||
for i := 0; i < 5*maxHandlers; i++ {
|
||||
for range 5 * maxHandlers {
|
||||
st.writeHeaders(HeadersFrameParam{
|
||||
StreamID: streamID,
|
||||
BlockFragment: st.encodeHeader(),
|
||||
@@ -4358,7 +4357,7 @@ func testServerContinuationFlood(t testing.TB) {
|
||||
BlockFragment: st.encodeHeader(),
|
||||
EndStream: true,
|
||||
})
|
||||
for i := 0; i < 1000; i++ {
|
||||
for i := range 1000 {
|
||||
st.fr.WriteContinuation(1, false, st.encodeHeaderRaw(
|
||||
fmt.Sprintf("x-%v", i), "1234567890",
|
||||
))
|
||||
@@ -4511,7 +4510,7 @@ func testServerWriteByteTimeout(t testing.TB) {
|
||||
})
|
||||
|
||||
// Read a few bytes, staying just under WriteByteTimeout.
|
||||
for i := 0; i < 10; i++ {
|
||||
for i := range 10 {
|
||||
st.advance(timeout - 1)
|
||||
if n, err := st.cc.Read(make([]byte, 1)); n != 1 || err != nil {
|
||||
t.Fatalf("read %v: %v, %v; want 1, nil", i, n, err)
|
||||
|
||||
@@ -708,7 +708,7 @@ func (t *Transport) newTLSConfig(host string) *tls.Config {
|
||||
if t.TLSClientConfig != nil {
|
||||
*cfg = *t.TLSClientConfig.Clone()
|
||||
}
|
||||
if !strSliceContains(cfg.NextProtos, NextProtoTLS) {
|
||||
if !slices.Contains(cfg.NextProtos, NextProtoTLS) {
|
||||
cfg.NextProtos = append([]string{NextProtoTLS}, cfg.NextProtos...)
|
||||
}
|
||||
if cfg.ServerName == "" {
|
||||
@@ -1794,10 +1794,7 @@ var (
|
||||
// Request.ContentLength+1, 512KB)).
|
||||
func (cs *clientStream) frameScratchBufferLen(maxFrameSize int) int {
|
||||
const max = 512 << 10
|
||||
n := int64(maxFrameSize)
|
||||
if n > max {
|
||||
n = max
|
||||
}
|
||||
n := min(int64(maxFrameSize), max)
|
||||
if cl := cs.reqBodyContentLength; cl != -1 && cl+1 < n {
|
||||
// Add an extra byte past the declared content-length to
|
||||
// give the caller's Request.Body io.Reader a chance to
|
||||
@@ -3066,21 +3063,21 @@ var (
|
||||
errRequestHeaderListSize = httpcommon.ErrRequestHeaderListSize
|
||||
)
|
||||
|
||||
func (cc *ClientConn) logf(format string, args ...interface{}) {
|
||||
func (cc *ClientConn) logf(format string, args ...any) {
|
||||
cc.t.logf(format, args...)
|
||||
}
|
||||
|
||||
func (cc *ClientConn) vlogf(format string, args ...interface{}) {
|
||||
func (cc *ClientConn) vlogf(format string, args ...any) {
|
||||
cc.t.vlogf(format, args...)
|
||||
}
|
||||
|
||||
func (t *Transport) vlogf(format string, args ...interface{}) {
|
||||
func (t *Transport) vlogf(format string, args ...any) {
|
||||
if VerboseLogs {
|
||||
t.logf(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Transport) logf(format string, args ...interface{}) {
|
||||
func (t *Transport) logf(format string, args ...any) {
|
||||
log.Printf(format, args...)
|
||||
}
|
||||
|
||||
@@ -3089,15 +3086,6 @@ type missingBody struct{}
|
||||
func (missingBody) Close() error { return nil }
|
||||
func (missingBody) Read([]byte) (int, error) { return 0, io.ErrUnexpectedEOF }
|
||||
|
||||
func strSliceContains(ss []string, s string) bool {
|
||||
for _, v := range ss {
|
||||
if v == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type erringRoundTripper struct{ err error }
|
||||
|
||||
func (rt erringRoundTripper) RoundTripErr() error { return rt.err }
|
||||
|
||||
@@ -123,7 +123,7 @@ func TestIdleConnTimeout(t *testing.T) {
|
||||
tr.IdleConnTimeout = test.idleConnTimeout
|
||||
})
|
||||
var tc *testClientConn
|
||||
for i := 0; i < 3; i++ {
|
||||
for i := range 3 {
|
||||
req, _ := http.NewRequest("GET", "https://dummy.tld/", nil)
|
||||
rt := tt.roundTrip(req)
|
||||
|
||||
@@ -413,7 +413,7 @@ func testTransportGetGotConnHooks(t *testing.T, useClient bool) {
|
||||
getConns int32
|
||||
gotConns int32
|
||||
)
|
||||
for i := 0; i < 2; i++ {
|
||||
for i := range 2 {
|
||||
trace := &httptrace.ClientTrace{
|
||||
GetConn: func(hostport string) {
|
||||
atomic.AddInt32(&getConns, 1)
|
||||
@@ -1373,7 +1373,7 @@ func testTransportChecksResponseHeaderListSize(t testing.TB) {
|
||||
|
||||
hdr := []string{":status", "200"}
|
||||
large := strings.Repeat("a", 1<<10)
|
||||
for i := 0; i < 5042; i++ {
|
||||
for range 5042 {
|
||||
hdr = append(hdr, large, large)
|
||||
}
|
||||
hbf := tc.makeHeaderBlockFragment(hdr...)
|
||||
@@ -1571,7 +1571,7 @@ func TestTransportDisableKeepAlives_Concurrency(t *testing.T) {
|
||||
c := &http.Client{Transport: tr}
|
||||
var reqs sync.WaitGroup
|
||||
const N = 20
|
||||
for i := 0; i < N; i++ {
|
||||
for i := range N {
|
||||
reqs.Add(1)
|
||||
if i == N-1 {
|
||||
// For the final request, try to make all the
|
||||
@@ -1877,7 +1877,6 @@ func TestTransportRejectsContentLengthWithSign(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Length", tt.cl[0])
|
||||
@@ -2464,7 +2463,7 @@ func testTransportBodyDoubleEndStream(t testing.TB) {
|
||||
|
||||
tr := newTransport(t)
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
for i := range 2 {
|
||||
req, _ := http.NewRequest("POST", ts.URL, byteAndEOFReader('a'))
|
||||
req.ContentLength = 1
|
||||
res, err := tr.RoundTrip(req)
|
||||
@@ -2658,7 +2657,7 @@ func TestTransportCancelDataResponseRace(t *testing.T) {
|
||||
io.WriteString(w, msg)
|
||||
return
|
||||
}
|
||||
for i := 0; i < 50; i++ {
|
||||
for i := range 50 {
|
||||
io.WriteString(w, "Some data.")
|
||||
w.(http.Flusher).Flush()
|
||||
if i == 2 {
|
||||
@@ -2795,7 +2794,7 @@ func testTransportPingWhenReadingMultiplePings(t testing.TB) {
|
||||
),
|
||||
})
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
for range 5 {
|
||||
// No ping yet...
|
||||
time.Sleep(999 * time.Millisecond)
|
||||
if f := tc.readFrame(); f != nil {
|
||||
@@ -3157,7 +3156,7 @@ func TestTransportRequestsLowServerLimit(t *testing.T) {
|
||||
}
|
||||
|
||||
const reqCount = 3
|
||||
for i := 0; i < reqCount; i++ {
|
||||
for range reqCount {
|
||||
req, err := http.NewRequest("GET", ts.URL, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -3196,7 +3195,7 @@ func testTransportRequestsStallAtServerLimit(t *testing.T) {
|
||||
// Start maxConcurrent+2 requests.
|
||||
// The server does not respond to any of them yet.
|
||||
var rts []*testRoundTrip
|
||||
for k := 0; k < maxConcurrent+2; k++ {
|
||||
for k := range maxConcurrent + 2 {
|
||||
req, _ := http.NewRequest("GET", fmt.Sprintf("https://dummy.tld/%d", k), nil)
|
||||
if k == maxConcurrent {
|
||||
req.Cancel = cancelClientRequest
|
||||
@@ -3378,7 +3377,7 @@ func benchSimpleRoundTrip(b *testing.B, nReqHeaders, nResHeader int) {
|
||||
b.ReportAllocs()
|
||||
ts := newTestServer(b,
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
for i := 0; i < nResHeader; i++ {
|
||||
for i := range nResHeader {
|
||||
name := fmt.Sprint("A-", i)
|
||||
w.Header().Set(name, "*")
|
||||
}
|
||||
@@ -3393,7 +3392,7 @@ func benchSimpleRoundTrip(b *testing.B, nReqHeaders, nResHeader int) {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
for i := 0; i < nReqHeaders; i++ {
|
||||
for i := range nReqHeaders {
|
||||
name := fmt.Sprint("A-", i)
|
||||
req.Header.Set(name, "*")
|
||||
}
|
||||
@@ -3496,7 +3495,7 @@ func benchLargeDownloadRoundTrip(b *testing.B, frameSize uint32) {
|
||||
w.Header().Set("Content-Length", strconv.Itoa(transferSize))
|
||||
w.Header().Set("Content-Transfer-Encoding", "binary")
|
||||
var data [1024 * 1024]byte
|
||||
for i := 0; i < transferSize/(1024*1024); i++ {
|
||||
for range transferSize / (1024 * 1024) {
|
||||
w.Write(data[:])
|
||||
}
|
||||
}, optQuiet,
|
||||
@@ -3922,7 +3921,7 @@ func TestTransportBodyRewindRace(t *testing.T) {
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(clients)
|
||||
for i := 0; i < clients; i++ {
|
||||
for range clients {
|
||||
req, err := http.NewRequest("POST", ts.URL, bytes.NewBufferString("abcdef"))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected new request error: %v", err)
|
||||
@@ -4164,10 +4163,8 @@ func TestTransportFrameBufferReuse(t *testing.T) {
|
||||
|
||||
var wg sync.WaitGroup
|
||||
defer wg.Wait()
|
||||
for i := 0; i < 10; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for range 10 {
|
||||
wg.Go(func() {
|
||||
req, err := http.NewRequest("POST", ts.URL, strings.NewReader(filler))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
@@ -4187,7 +4184,7 @@ func TestTransportFrameBufferReuse(t *testing.T) {
|
||||
if res != nil && res.Body != nil {
|
||||
res.Body.Close()
|
||||
}
|
||||
}()
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4232,7 +4229,6 @@ func TestTransportBlockingRequestWrite(t *testing.T) {
|
||||
return req, err
|
||||
},
|
||||
}} {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
if v := r.Header.Get("Big"); v != "" && v != filler {
|
||||
@@ -4880,8 +4876,7 @@ func TestDialRaceResumesDial(t *testing.T) {
|
||||
ctx1, cancel1 := context.WithCancel(context.Background())
|
||||
defer cancel1()
|
||||
req1 := req.WithContext(ctx1)
|
||||
ctx2, cancel2 := context.WithCancel(context.Background())
|
||||
defer cancel2()
|
||||
ctx2 := t.Context()
|
||||
req2 := req.WithContext(ctx2)
|
||||
errCh := make(chan error)
|
||||
go func() {
|
||||
@@ -4994,7 +4989,7 @@ func TestIssue67671(t *testing.T) {
|
||||
tr.Protocols = protocols("h2c")
|
||||
req, _ := http.NewRequest("GET", ts.URL, nil)
|
||||
req.Close = true
|
||||
for i := 0; i < 2; i++ {
|
||||
for range 2 {
|
||||
res, err := tr.RoundTrip(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -5289,7 +5284,7 @@ func testTransportConnBecomesUnresponsive(t testing.TB) {
|
||||
// Send more requests.
|
||||
// None receive a response.
|
||||
// Each is canceled.
|
||||
for i := 0; i < maxConcurrent; i++ {
|
||||
for i := range maxConcurrent {
|
||||
t.Logf("request %v receives no response and is canceled", i)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
req := Must(http.NewRequestWithContext(ctx, "GET", "https://dummy.tld/", nil))
|
||||
|
||||
@@ -115,10 +115,7 @@ func (wr FrameWriteRequest) Consume(n int32) (FrameWriteRequest, FrameWriteReque
|
||||
}
|
||||
|
||||
// Might need to split after applying limits.
|
||||
allowed := wr.stream.flow.available()
|
||||
if n < allowed {
|
||||
allowed = n
|
||||
}
|
||||
allowed := min(n, wr.stream.flow.available())
|
||||
if wr.stream.sc.maxFrameSize < allowed {
|
||||
allowed = wr.stream.sc.maxFrameSize
|
||||
}
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
package http2
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
"slices"
|
||||
)
|
||||
|
||||
// RFC 7540, Section 5.3.5: the default weight is 16.
|
||||
@@ -199,7 +200,19 @@ func (n *priorityNodeRFC7540) walkReadyInOrder(openParent bool, tmp *[]*priority
|
||||
*tmp = append(*tmp, n.kids)
|
||||
n.kids.setParent(nil)
|
||||
}
|
||||
sort.Sort(sortPriorityNodeSiblingsRFC7540(*tmp))
|
||||
slices.SortFunc(*tmp, func(i, k *priorityNodeRFC7540) int {
|
||||
// Prefer the subtree that has sent fewer bytes relative to its weight.
|
||||
// See sections 5.3.2 and 5.3.4.
|
||||
wi, bi := float64(i.weight)+1, float64(i.subtreeBytes)
|
||||
wk, bk := float64(k.weight)+1, float64(k.subtreeBytes)
|
||||
if bi == 0 && bk == 0 {
|
||||
return cmp.Compare(wk, wi)
|
||||
}
|
||||
if bk == 0 {
|
||||
return 0
|
||||
}
|
||||
return cmp.Compare(bi/bk, wi/wk)
|
||||
})
|
||||
for i := len(*tmp) - 1; i >= 0; i-- {
|
||||
(*tmp)[i].setParent(n) // setParent inserts at the head of n.kids
|
||||
}
|
||||
@@ -211,24 +224,6 @@ func (n *priorityNodeRFC7540) walkReadyInOrder(openParent bool, tmp *[]*priority
|
||||
return false
|
||||
}
|
||||
|
||||
type sortPriorityNodeSiblingsRFC7540 []*priorityNodeRFC7540
|
||||
|
||||
func (z sortPriorityNodeSiblingsRFC7540) Len() int { return len(z) }
|
||||
func (z sortPriorityNodeSiblingsRFC7540) Swap(i, k int) { z[i], z[k] = z[k], z[i] }
|
||||
func (z sortPriorityNodeSiblingsRFC7540) Less(i, k int) bool {
|
||||
// Prefer the subtree that has sent fewer bytes relative to its weight.
|
||||
// See sections 5.3.2 and 5.3.4.
|
||||
wi, bi := float64(z[i].weight)+1, float64(z[i].subtreeBytes)
|
||||
wk, bk := float64(z[k].weight)+1, float64(z[k].subtreeBytes)
|
||||
if bi == 0 && bk == 0 {
|
||||
return wi >= wk
|
||||
}
|
||||
if bk == 0 {
|
||||
return false
|
||||
}
|
||||
return bi/bk <= wi/wk
|
||||
}
|
||||
|
||||
type priorityWriteSchedulerRFC7540 struct {
|
||||
// root is the root of the priority tree, where root.id = 0.
|
||||
// The root queues control frames that are not associated with any stream.
|
||||
|
||||
@@ -33,12 +33,12 @@ func TestRoundRobinScheduler(t *testing.T) {
|
||||
ws.Push(wr)
|
||||
}
|
||||
const controlFrames = 2
|
||||
for i := 0; i < controlFrames; i++ {
|
||||
for range controlFrames {
|
||||
ws.Push(makeWriteNonStreamRequest())
|
||||
}
|
||||
|
||||
// We should get the control frames first.
|
||||
for i := 0; i < controlFrames; i++ {
|
||||
for range controlFrames {
|
||||
wr, ok := ws.Pop()
|
||||
if !ok || wr.StreamID() != 0 {
|
||||
t.Fatalf("wr.Pop() = stream %v, %v; want 0, true", wr.StreamID(), ok)
|
||||
|
||||
Reference in New Issue
Block a user