script/fmt now runs golines -m 77 after gofmt, repeating golines until it changes nothing, since one pass can leave a line the next splits. script/fmt-check fails when either would change a file. script/bootstrap installs golines v0.13.0 with go install, pinned to its commit, and checks the installed version with go version -m. The tree is reformatted. The longer lines this makes are fixed by hand: nolint directives moved onto their own line above the statement, one string split, and 20 functions over funlen's 80 lines shortened or split, RunWAF and limitPercentages among them. Model: opus-5-5
This commit was merged in pull request #363.
This commit is contained in:
1 parent
63e58e326b
commit
0b23352767
118 files changed
+9447
-2670
No files matched your search
+256
-80
@@ -34,13 +34,15 @@ func announcedLength(size int) string {
|
||||
func TestServerHasTheFixedLimits(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cfg, err := config.RProxyFromEnvironment(func(name string) (string, bool) {
|
||||
if name == "SWRP_WAF_BACKEND" {
|
||||
return nowhere, true
|
||||
}
|
||||
cfg, err := config.RProxyFromEnvironment(
|
||||
func(name string) (string, bool) {
|
||||
if name == "SWRP_WAF_BACKEND" {
|
||||
return nowhere, true
|
||||
}
|
||||
|
||||
return "", false
|
||||
})
|
||||
return "", false
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("settings: %v", err)
|
||||
}
|
||||
@@ -48,14 +50,23 @@ func TestServerHasTheFixedLimits(t *testing.T) {
|
||||
server := rproxy.New(rproxy.Params{
|
||||
Config: cfg,
|
||||
RequestLog: io.Discard,
|
||||
ProcessLog: requestlog.NewProcessLogger(io.Discard, "test", slog.LevelInfo),
|
||||
ProcessLog: requestlog.NewProcessLogger(
|
||||
io.Discard,
|
||||
"test",
|
||||
slog.LevelInfo,
|
||||
),
|
||||
})
|
||||
|
||||
if server.Addr != ":8080" || server.MaxHeaderBytes != 28<<10 ||
|
||||
server.IdleTimeout != 2*time.Minute || server.ReadHeaderTimeout != time.Minute {
|
||||
t.Errorf("server listens on %q with header limit %d, idle time %s and "+
|
||||
"header timeout %s", server.Addr, server.MaxHeaderBytes,
|
||||
server.IdleTimeout, server.ReadHeaderTimeout)
|
||||
t.Errorf(
|
||||
"server listens on %q with header limit %d, idle time %s and "+
|
||||
"header timeout %s",
|
||||
server.Addr,
|
||||
server.MaxHeaderBytes,
|
||||
server.IdleTimeout,
|
||||
server.ReadHeaderTimeout,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,9 +87,14 @@ func TestABodyAnnouncedOverItsLimitIsRefusedOnceWAFAllowsIt(t *testing.T) {
|
||||
app := startApp(t, func(http.ResponseWriter, *http.Request) {
|
||||
t.Error("the app was asked")
|
||||
})
|
||||
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
|
||||
maxRequestSize: tc.limit,
|
||||
})
|
||||
addr, _ := startRProxy(
|
||||
t,
|
||||
standIn.URL,
|
||||
app.URL,
|
||||
map[string]string{
|
||||
maxRequestSize: tc.limit,
|
||||
},
|
||||
)
|
||||
|
||||
got := visit(t, newRequest(t, http.MethodPost, addr, "/",
|
||||
bytes.NewReader(make([]byte, tc.size))))
|
||||
@@ -87,7 +103,11 @@ func TestABodyAnnouncedOverItsLimitIsRefusedOnceWAFAllowsIt(t *testing.T) {
|
||||
}
|
||||
|
||||
if asked := standIn.question(t); len(asked.body) != tc.asked {
|
||||
t.Errorf("the question carries %d bytes, want %d", len(asked.body), tc.asked)
|
||||
t.Errorf(
|
||||
"the question carries %d bytes, want %d",
|
||||
len(asked.body),
|
||||
tc.asked,
|
||||
)
|
||||
}
|
||||
|
||||
report := standIn.report(t)
|
||||
@@ -138,13 +158,21 @@ func TestABodyNotAnnouncedOverItsLimitIsRefused(t *testing.T) {
|
||||
asked.Store(true)
|
||||
greet(w, r)
|
||||
})
|
||||
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
|
||||
maxRequestSize: tc.limit,
|
||||
})
|
||||
addr, _ := startRProxy(
|
||||
t,
|
||||
standIn.URL,
|
||||
app.URL,
|
||||
map[string]string{
|
||||
maxRequestSize: tc.limit,
|
||||
},
|
||||
)
|
||||
|
||||
conn := dial(t, addr)
|
||||
send(t, conn, post+"Transfer-Encoding: chunked\r\n\r\n"+
|
||||
strconv.FormatInt(int64(tc.size), 16)+"\r\n"+strings.Repeat("x", tc.size)+
|
||||
strconv.FormatInt(
|
||||
int64(tc.size),
|
||||
16,
|
||||
)+"\r\n"+strings.Repeat("x", tc.size)+
|
||||
"\r\n0\r\n\r\n")
|
||||
|
||||
if status := readStatus(t, conn); status != http.StatusRequestEntityTooLarge {
|
||||
@@ -203,17 +231,26 @@ func TestAResponseOverItsLimit(t *testing.T) {
|
||||
|
||||
text, err := io.ReadAll(conn)
|
||||
if err != nil || bytes.Contains(text, []byte(large)) {
|
||||
t.Errorf("read %d bytes (%v), want the answer cut off", len(text), err)
|
||||
t.Errorf(
|
||||
"read %d bytes (%v), want the answer cut off",
|
||||
len(text),
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
report := standIn.report(t)
|
||||
if report.Status != http.StatusOK || report.ResponseBytes > 1<<10 {
|
||||
t.Errorf("report %+v, want status 200 and at most 1K of the answer", report)
|
||||
t.Errorf(
|
||||
"report %+v, want status 200 and at most 1K of the answer",
|
||||
report,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestAHeadWhoseAnswerAnnouncesMoreThanTheResponseLimitIsPassedOn(t *testing.T) {
|
||||
func TestAHeadWhoseAnswerAnnouncesMoreThanTheResponseLimitIsPassedOn(
|
||||
t *testing.T,
|
||||
) {
|
||||
t.Parallel()
|
||||
|
||||
const announced = "2048"
|
||||
@@ -227,8 +264,13 @@ func TestAHeadWhoseAnswerAnnouncesMoreThanTheResponseLimitIsPassedOn(t *testing.
|
||||
})
|
||||
|
||||
got := visit(t, newRequest(t, http.MethodHead, addr, "/", http.NoBody))
|
||||
if got.status != http.StatusOK || got.header.Get(contentLengthHeader) != announced {
|
||||
t.Errorf("answered %+v, want the app's 200 announcing %s bytes", got, announced)
|
||||
if got.status != http.StatusOK ||
|
||||
got.header.Get(contentLengthHeader) != announced {
|
||||
t.Errorf(
|
||||
"answered %+v, want the app's 200 announcing %s bytes",
|
||||
got,
|
||||
announced,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,14 +285,22 @@ func TestASettingOfOffSetsNoLimit(t *testing.T) {
|
||||
|
||||
standIn := startWAF(t, allow)
|
||||
app := startApp(t, greet)
|
||||
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
|
||||
setting: "off",
|
||||
})
|
||||
addr, _ := startRProxy(
|
||||
t,
|
||||
standIn.URL,
|
||||
app.URL,
|
||||
map[string]string{
|
||||
setting: "off",
|
||||
},
|
||||
)
|
||||
|
||||
// A body and an answer that a limit of zero would cut off, as it would the
|
||||
// next answer, which rproxy gives itself.
|
||||
wantGreeting(t, visit(t, newRequest(t, http.MethodPost, addr, "/",
|
||||
strings.NewReader("a body"))))
|
||||
wantGreeting(
|
||||
t,
|
||||
visit(t, newRequest(t, http.MethodPost, addr, "/",
|
||||
strings.NewReader("a body"))),
|
||||
)
|
||||
|
||||
if got := get(t, addr, waf.HealthPath); got.status != http.StatusOK {
|
||||
t.Errorf("answered %+v, want rproxy's own 200", got)
|
||||
@@ -273,9 +323,14 @@ func TestAVisitorTooSlowToSendTheFirstPartIsAnswered408(t *testing.T) {
|
||||
|
||||
standIn := startWAF(t, allow)
|
||||
app := startApp(t, greet)
|
||||
addr, out := startRProxy(t, standIn.URL, app.URL, map[string]string{
|
||||
maxRequestTime: "500",
|
||||
})
|
||||
addr, out := startRProxy(
|
||||
t,
|
||||
standIn.URL,
|
||||
app.URL,
|
||||
map[string]string{
|
||||
maxRequestTime: "500",
|
||||
},
|
||||
)
|
||||
|
||||
conn := dial(t, addr)
|
||||
send(t, conn, post+tc.rest)
|
||||
@@ -319,7 +374,9 @@ func TestAVisitorThatGoesAwayBeforeTheFirstPartIsNotAsked(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestABodyThatCannotBeReadClosesTheConnectionWithoutAnAnswer(t *testing.T) {
|
||||
func TestABodyThatCannotBeReadClosesTheConnectionWithoutAnAnswer(
|
||||
t *testing.T,
|
||||
) {
|
||||
t.Parallel()
|
||||
|
||||
for _, tc := range []struct {
|
||||
@@ -356,8 +413,11 @@ func TestABodyThatCannotBeReadClosesTheConnectionWithoutAnAnswer(t *testing.T) {
|
||||
|
||||
text, err := io.ReadAll(conn)
|
||||
if err != nil || len(text) != 0 {
|
||||
t.Errorf("read %q (%v), want the connection closed without an answer",
|
||||
text, err)
|
||||
t.Errorf(
|
||||
"read %q (%v), want the connection closed without an answer",
|
||||
text,
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
line := out.requestLine(t)
|
||||
@@ -402,7 +462,8 @@ func (w *deadlineRecorder) FlushError() error {
|
||||
func (w *deadlineRecorder) SetReadDeadline(deadline time.Time) error {
|
||||
w.readDeadline = deadline
|
||||
|
||||
if w.stalled != nil && !deadline.IsZero() && !deadline.After(time.Now()) {
|
||||
if w.stalled != nil && !deadline.IsZero() &&
|
||||
!deadline.After(time.Now()) {
|
||||
_ = w.stalled.CloseWithError(os.ErrDeadlineExceeded)
|
||||
}
|
||||
|
||||
@@ -439,12 +500,22 @@ func TestABodyLeftUnreadIsReadOnlyUntilTheRequestTimeLimit(t *testing.T) {
|
||||
|
||||
t.Cleanup(func() { _ = stop.Close() })
|
||||
|
||||
req := httptest.NewRequestWithContext(t.Context(), http.MethodPost, "/",
|
||||
io.MultiReader(bytes.NewReader(make([]byte, questionBodyMaxBytes+1)), stalled))
|
||||
req := httptest.NewRequestWithContext(
|
||||
t.Context(),
|
||||
http.MethodPost,
|
||||
"/",
|
||||
io.MultiReader(
|
||||
bytes.NewReader(make([]byte, questionBodyMaxBytes+1)),
|
||||
stalled,
|
||||
),
|
||||
)
|
||||
req.ContentLength = announced
|
||||
req.Header.Set(contentLengthHeader, strconv.Itoa(announced))
|
||||
|
||||
w := &deadlineRecorder{ResponseRecorder: httptest.NewRecorder(), stalled: stop}
|
||||
w := &deadlineRecorder{
|
||||
ResponseRecorder: httptest.NewRecorder(),
|
||||
stalled: stop,
|
||||
}
|
||||
|
||||
before := time.Now()
|
||||
|
||||
@@ -456,12 +527,17 @@ func TestABodyLeftUnreadIsReadOnlyUntilTheRequestTimeLimit(t *testing.T) {
|
||||
|
||||
if w.readDeadline.Before(before.Add(limit)) ||
|
||||
w.readDeadline.After(time.Now().Add(limit)) {
|
||||
t.Errorf("the reading of the body ends at %s, want %s from the request",
|
||||
w.readDeadline, limit)
|
||||
t.Errorf(
|
||||
"the reading of the body ends at %s, want %s from the request",
|
||||
w.readDeadline,
|
||||
limit,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestABodyLeftUnreadIsReadNoMoreOnceTheTimeToSendTheAnswerRunsOut(t *testing.T) {
|
||||
func TestABodyLeftUnreadIsReadNoMoreOnceTheTimeToSendTheAnswerRunsOut(
|
||||
t *testing.T,
|
||||
) {
|
||||
t.Parallel()
|
||||
|
||||
standIn := startWAF(t, allow)
|
||||
@@ -473,8 +549,15 @@ func TestABodyLeftUnreadIsReadNoMoreOnceTheTimeToSendTheAnswerRunsOut(t *testing
|
||||
|
||||
t.Cleanup(func() { _ = stop.Close() })
|
||||
|
||||
req := httptest.NewRequestWithContext(t.Context(), http.MethodPost, "/",
|
||||
io.MultiReader(bytes.NewReader(make([]byte, questionBodyMaxBytes+1)), stalled))
|
||||
req := httptest.NewRequestWithContext(
|
||||
t.Context(),
|
||||
http.MethodPost,
|
||||
"/",
|
||||
io.MultiReader(
|
||||
bytes.NewReader(make([]byte, questionBodyMaxBytes+1)),
|
||||
stalled,
|
||||
),
|
||||
)
|
||||
req.ContentLength = 2 * questionBodyMaxBytes
|
||||
req.Header.Set(contentLengthHeader, strconv.Itoa(2*questionBodyMaxBytes))
|
||||
|
||||
@@ -496,7 +579,10 @@ func TestABodyLeftUnreadIsReadNoMoreOnceTheTimeToSendTheAnswerRunsOut(t *testing
|
||||
}
|
||||
|
||||
if w.readDeadline.Before(before) || w.readDeadline.After(time.Now()) {
|
||||
t.Errorf("the reading of the body ends at %s, want now", w.readDeadline)
|
||||
t.Errorf(
|
||||
"the reading of the body ends at %s, want now",
|
||||
w.readDeadline,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,12 +603,24 @@ func TestAnAnswerRProxyGivesItselfHasTheResponseTimeToBeSent(t *testing.T) {
|
||||
|
||||
standIn := startWAF(t, deny)
|
||||
app := startApp(t, greet)
|
||||
_, _, server := startServer(t, standIn.URL, app.URL, map[string]string{
|
||||
maxResponseTime: strconv.FormatInt(limit.Milliseconds(), 10),
|
||||
})
|
||||
_, _, server := startServer(
|
||||
t,
|
||||
standIn.URL,
|
||||
app.URL,
|
||||
map[string]string{
|
||||
maxResponseTime: strconv.FormatInt(
|
||||
limit.Milliseconds(),
|
||||
10,
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
req := httptest.NewRequestWithContext(t.Context(), http.MethodGet, tc.target,
|
||||
http.NoBody)
|
||||
req := httptest.NewRequestWithContext(
|
||||
t.Context(),
|
||||
http.MethodGet,
|
||||
tc.target,
|
||||
http.NoBody,
|
||||
)
|
||||
w := &deadlineRecorder{ResponseRecorder: httptest.NewRecorder()}
|
||||
|
||||
before := time.Now()
|
||||
@@ -535,14 +633,19 @@ func TestAnAnswerRProxyGivesItselfHasTheResponseTimeToBeSent(t *testing.T) {
|
||||
|
||||
if w.writeDeadline.Before(before.Add(limit)) ||
|
||||
w.writeDeadline.After(time.Now().Add(limit)) {
|
||||
t.Errorf("the time limit on sending ends at %s, want %s from the answer",
|
||||
w.writeDeadline, limit)
|
||||
t.Errorf(
|
||||
"the time limit on sending ends at %s, want %s from the answer",
|
||||
w.writeDeadline,
|
||||
limit,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnAnswerRProxyGivesItselfHasTenSecondsToBeSentAtLeast(t *testing.T) {
|
||||
func TestAnAnswerRProxyGivesItselfHasTenSecondsToBeSentAtLeast(
|
||||
t *testing.T,
|
||||
) {
|
||||
t.Parallel()
|
||||
|
||||
const least = 10 * time.Second
|
||||
@@ -553,7 +656,12 @@ func TestAnAnswerRProxyGivesItselfHasTenSecondsToBeSentAtLeast(t *testing.T) {
|
||||
maxResponseTime: "300",
|
||||
})
|
||||
|
||||
req := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/", http.NoBody)
|
||||
req := httptest.NewRequestWithContext(
|
||||
t.Context(),
|
||||
http.MethodGet,
|
||||
"/",
|
||||
http.NoBody,
|
||||
)
|
||||
w := &deadlineRecorder{ResponseRecorder: httptest.NewRecorder()}
|
||||
|
||||
before := time.Now()
|
||||
@@ -561,8 +669,11 @@ func TestAnAnswerRProxyGivesItselfHasTenSecondsToBeSentAtLeast(t *testing.T) {
|
||||
server.Handler.ServeHTTP(w, req)
|
||||
|
||||
if w.writeDeadline.Before(before.Add(least)) {
|
||||
t.Errorf("the time limit on sending ends at %s, want %s from the answer at least",
|
||||
w.writeDeadline, least)
|
||||
t.Errorf(
|
||||
"the time limit on sending ends at %s, want %s from the answer at least",
|
||||
w.writeDeadline,
|
||||
least,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,7 +694,9 @@ func TestAVisitorTooSlowToSendTheRestIsAnswered408(t *testing.T) {
|
||||
t.Errorf("status %d, want 408", status)
|
||||
}
|
||||
|
||||
if asked := standIn.question(t); len(asked.body) != questionBodyMaxBytes {
|
||||
if asked := standIn.question(t); len(
|
||||
asked.body,
|
||||
) != questionBodyMaxBytes {
|
||||
t.Errorf("the question carries %d bytes", len(asked.body))
|
||||
}
|
||||
|
||||
@@ -597,7 +710,11 @@ func TestAVisitorTooSlowToSendTheRestIsAnswered408(t *testing.T) {
|
||||
func startAppThatTakesNothing(t *testing.T) string {
|
||||
t.Helper()
|
||||
|
||||
listener, err := (&net.ListenConfig{}).Listen(t.Context(), "tcp", localhost+":0")
|
||||
listener, err := (&net.ListenConfig{}).Listen(
|
||||
t.Context(),
|
||||
"tcp",
|
||||
localhost+":0",
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("listen: %v", err)
|
||||
}
|
||||
@@ -686,7 +803,9 @@ func TestAnAppTooSlowToAnswerIsAnswered504(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAVisitorGetsAnAnswerWhenTheAppAnswersAsTheTimeRunsOut(t *testing.T) {
|
||||
func TestAVisitorGetsAnAnswerWhenTheAppAnswersAsTheTimeRunsOut(
|
||||
t *testing.T,
|
||||
) {
|
||||
t.Parallel()
|
||||
|
||||
// Four visitors at a time, each with an app and rproxy of its own, send more
|
||||
@@ -785,8 +904,13 @@ func TestAnAppTooSlowToFinishItsAnswerIsCutOff(t *testing.T) {
|
||||
|
||||
if res.StatusCode != http.StatusOK || string(body) != start ||
|
||||
!errors.Is(err, io.ErrUnexpectedEOF) {
|
||||
t.Errorf("answered %d %q (%v), want the app's 200 %q, then the connection closed",
|
||||
res.StatusCode, body, err, start)
|
||||
t.Errorf(
|
||||
"answered %d %q (%v), want the app's 200 %q, then the connection closed",
|
||||
res.StatusCode,
|
||||
body,
|
||||
err,
|
||||
start,
|
||||
)
|
||||
}
|
||||
|
||||
if report := standIn.report(t); report.Status != http.StatusOK {
|
||||
@@ -827,13 +951,17 @@ func TestAVisitorTooSlowToTakeTheAnswerIsCutOff(t *testing.T) {
|
||||
line := out.requestLine(t)
|
||||
|
||||
responseBytes, _ := line["response_bytes"].(float64)
|
||||
if line["status"] != float64(http.StatusOK) || responseBytes >= bodySize {
|
||||
if line["status"] != float64(http.StatusOK) ||
|
||||
responseBytes >= bodySize {
|
||||
t.Errorf("line %v, want status 200 and the answer cut off", line)
|
||||
}
|
||||
|
||||
report := standIn.report(t)
|
||||
if report.Status != http.StatusOK || report.ResponseBytes >= bodySize {
|
||||
t.Errorf("report %+v, want status 200 and the answer cut off", report)
|
||||
t.Errorf(
|
||||
"report %+v, want status 200 and the answer cut off",
|
||||
report,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -853,7 +981,9 @@ func TestAnAppThatCannotBeReachedIsAnswered502WithAReport(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAVisitorThatStopsSendingAfterTheAppHasAnsweredGetsTheAnswer(t *testing.T) {
|
||||
func TestAVisitorThatStopsSendingAfterTheAppHasAnsweredGetsTheAnswer(
|
||||
t *testing.T,
|
||||
) {
|
||||
t.Parallel()
|
||||
|
||||
standIn := startWAF(t, allow)
|
||||
@@ -937,7 +1067,9 @@ func TestAVisitorThatStopsALittleShortGetsTheAppsAnswerAtOnce(t *testing.T) {
|
||||
wantGreeting(t, readAnswer(t, conn))
|
||||
}
|
||||
|
||||
func TestAVisitorThatStopsALittleShortIsReadUntilTheRequestTimeLimit(t *testing.T) {
|
||||
func TestAVisitorThatStopsALittleShortIsReadUntilTheRequestTimeLimit(
|
||||
t *testing.T,
|
||||
) {
|
||||
t.Parallel()
|
||||
|
||||
const limit = 2 * time.Second
|
||||
@@ -961,7 +1093,11 @@ func TestAVisitorThatStopsALittleShortIsReadUntilTheRequestTimeLimit(t *testing.
|
||||
}
|
||||
|
||||
if closed := time.Since(start); closed < limit {
|
||||
t.Errorf("the connection closed after %s, want %s at least", closed, limit)
|
||||
t.Errorf(
|
||||
"the connection closed after %s, want %s at least",
|
||||
closed,
|
||||
limit,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -992,7 +1128,8 @@ func TestAVisitorThatStopsALittleShortHasTheConnectionClosedWhenTheAnswerIsCutOf
|
||||
rc := http.NewResponseController(w)
|
||||
_ = rc.EnableFullDuplex()
|
||||
|
||||
w.Header().Set(contentLengthHeader, strconv.Itoa(len(greeting)))
|
||||
w.Header().
|
||||
Set(contentLengthHeader, strconv.Itoa(len(greeting)))
|
||||
|
||||
for _, part := range tc.atOnce {
|
||||
_, _ = io.WriteString(w, part)
|
||||
@@ -1010,10 +1147,18 @@ func TestAVisitorThatStopsALittleShortHasTheConnectionClosedWhenTheAnswerIsCutOf
|
||||
})
|
||||
|
||||
// The request time limit is far longer than dial's deadline.
|
||||
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
|
||||
maxRequestTime: "120000",
|
||||
maxResponseTime: strconv.FormatInt(limit.Milliseconds(), 10),
|
||||
})
|
||||
addr, _ := startRProxy(
|
||||
t,
|
||||
standIn.URL,
|
||||
app.URL,
|
||||
map[string]string{
|
||||
maxRequestTime: "120000",
|
||||
maxResponseTime: strconv.FormatInt(
|
||||
limit.Milliseconds(),
|
||||
10,
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
conn := dial(t, addr)
|
||||
sendAllButALittle(t, conn)
|
||||
@@ -1030,7 +1175,12 @@ func TestAVisitorThatStopsALittleShortHasTheConnectionClosedWhenTheAnswerIsCutOf
|
||||
|
||||
want := strings.Join(tc.atOnce, "")
|
||||
if string(body) != want || !errors.Is(err, io.ErrUnexpectedEOF) {
|
||||
t.Errorf("read %q (%v), want %q and the connection closed", body, err, want)
|
||||
t.Errorf(
|
||||
"read %q (%v), want %q and the connection closed",
|
||||
body,
|
||||
err,
|
||||
want,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -1068,7 +1218,11 @@ func TestAVisitorThatStopsSendingWhileTheAppWorksGetsNoAnswer(t *testing.T) {
|
||||
|
||||
text, err := io.ReadAll(conn)
|
||||
if err != nil || len(text) != 0 {
|
||||
t.Errorf("read %q (%v), want the connection closed without an answer", text, err)
|
||||
t.Errorf(
|
||||
"read %q (%v), want the connection closed without an answer",
|
||||
text,
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
if line := out.requestLine(t); line["status"] != 0.0 {
|
||||
@@ -1076,7 +1230,9 @@ func TestAVisitorThatStopsSendingWhileTheAppWorksGetsNoAnswer(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTheRequestTimeLimitDoesNotCutAnAnswerOnceTheAppHasTheRequest(t *testing.T) {
|
||||
func TestTheRequestTimeLimitDoesNotCutAnAnswerOnceTheAppHasTheRequest(
|
||||
t *testing.T,
|
||||
) {
|
||||
t.Parallel()
|
||||
|
||||
const answer = "the end of a long answer"
|
||||
@@ -1094,13 +1250,28 @@ func TestTheRequestTimeLimitDoesNotCutAnAnswerOnceTheAppHasTheRequest(t *testing
|
||||
maxRequestTime: "2000",
|
||||
})
|
||||
|
||||
got := visit(t, newRequest(t, http.MethodPost, addr, "/", strings.NewReader("a body")))
|
||||
got := visit(
|
||||
t,
|
||||
newRequest(
|
||||
t,
|
||||
http.MethodPost,
|
||||
addr,
|
||||
"/",
|
||||
strings.NewReader("a body"),
|
||||
),
|
||||
)
|
||||
if got.status != http.StatusOK || got.body != answer {
|
||||
t.Errorf("answered %d %q, want the app's whole answer", got.status, got.body)
|
||||
t.Errorf(
|
||||
"answered %d %q, want the app's whole answer",
|
||||
got.status,
|
||||
got.body,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAVisitorThatStopsALittleShortGetsAnAnswerRProxyGivesAtOnce(t *testing.T) {
|
||||
func TestAVisitorThatStopsALittleShortGetsAnAnswerRProxyGivesAtOnce(
|
||||
t *testing.T,
|
||||
) {
|
||||
t.Parallel()
|
||||
|
||||
for _, tc := range []struct {
|
||||
@@ -1121,10 +1292,15 @@ func TestAVisitorThatStopsALittleShortGetsAnAnswerRProxyGivesAtOnce(t *testing.T
|
||||
app := startApp(t, greet)
|
||||
// The request time limit is longer than the 10 seconds an answer rproxy
|
||||
// gives itself has to be sent, and than dial's deadline.
|
||||
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
|
||||
maxRequestTime: "15000",
|
||||
maxResponseTime: "300",
|
||||
})
|
||||
addr, _ := startRProxy(
|
||||
t,
|
||||
standIn.URL,
|
||||
app.URL,
|
||||
map[string]string{
|
||||
maxRequestTime: "15000",
|
||||
maxResponseTime: "300",
|
||||
},
|
||||
)
|
||||
|
||||
// The body stops 100 bytes short, less than Go's server reads of a body
|
||||
// left unread before it answers.
|
||||
|
||||
Reference in new issue
Block a user