Compare commits
1
Commits
next
...
27835a703f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27835a703f |
No files matched your search
@@ -2245,7 +2245,8 @@ These limits apply per request, in both directions:
|
|||||||
- `SWRP_MAX_RESPONSE_TIME_MS` runs from the end of the request to the last byte
|
- `SWRP_MAX_RESPONSE_TIME_MS` runs from the end of the request to the last byte
|
||||||
of the answer reaching the visitor. The request ends when the app has been
|
of the answer reaching the visitor. The request ends when the app has been
|
||||||
sent all of it, or when the app's answer arrives if that is sooner. An answer
|
sent all of it, or when the app's answer arrives if that is sooner. An answer
|
||||||
`rproxy` gives itself has the whole time from when it starts.
|
`rproxy` gives itself has the whole time from when it starts, and never less
|
||||||
|
than 10 seconds.
|
||||||
|
|
||||||
The largest request line and headers is 32 KiB. A kept-open connection is closed
|
The largest request line and headers is 32 KiB. A kept-open connection is closed
|
||||||
after 120 seconds idle. Neither has a setting. traefik, by default, closes an
|
after 120 seconds idle. Neither has a setting. traefik, by default, closes an
|
||||||
|
|||||||
+2
-1
@@ -436,7 +436,8 @@ A time here is a whole number of milliseconds above zero, such as `2000`.
|
|||||||
headers, the time until the app has been sent the whole request. A time or
|
headers, the time until the app has been sent the whole request. A time or
|
||||||
`off`.
|
`off`.
|
||||||
- `SWRP_MAX_RESPONSE_TIME_MS` (default `1800000`): how long the answer may take,
|
- `SWRP_MAX_RESPONSE_TIME_MS` (default `1800000`): how long the answer may take,
|
||||||
from the end of the request to its last byte reaching the visitor. A time or
|
from the end of the request to its last byte reaching the visitor. An answer
|
||||||
|
`rproxy` gives itself always has at least 10 seconds to be sent. A time or
|
||||||
`off`.
|
`off`.
|
||||||
- `SWRP_LISTEN_ADDR` (default `:8080`): where `rproxy` listens, such as `:9000`.
|
- `SWRP_LISTEN_ADDR` (default `:8080`): where `rproxy` listens, such as `:9000`.
|
||||||
- `SWRP_UPSTREAM_URL` (default `http://127.0.0.1:8081`): the app. An `http` or
|
- `SWRP_UPSTREAM_URL` (default `http://127.0.0.1:8081`): the app. An `http` or
|
||||||
|
|||||||
@@ -481,6 +481,30 @@ func TestAnAnswerRProxyGivesItselfHasTheResponseTimeToBeSent(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAnAnswerRProxyGivesItselfHasTenSecondsToBeSentAtLeast(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
const least = 10 * time.Second
|
||||||
|
|
||||||
|
standIn := startDiscriminator(t, deny)
|
||||||
|
app := startApp(t, greet)
|
||||||
|
_, _, server := startServer(t, standIn.URL, app.URL, map[string]string{
|
||||||
|
maxResponseTime: "300",
|
||||||
|
})
|
||||||
|
|
||||||
|
req := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/", http.NoBody)
|
||||||
|
w := &deadlineRecorder{ResponseRecorder: httptest.NewRecorder()}
|
||||||
|
|
||||||
|
before := time.Now()
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAVisitorTooSlowToSendTheRestIsAnswered408(t *testing.T) {
|
func TestAVisitorTooSlowToSendTheRestIsAnswered408(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,11 @@ const reportStatusMax = 599
|
|||||||
// plainText is the Content-Type of the answers rproxy gives itself.
|
// plainText is the Content-Type of the answers rproxy gives itself.
|
||||||
const plainText = "text/plain; charset=utf-8"
|
const plainText = "text/plain; charset=utf-8"
|
||||||
|
|
||||||
|
// ownAnswerMinSendTime is the least time an answer rproxy gives itself has to be
|
||||||
|
// sent. A shorter time can run out on a busy host before the first byte is
|
||||||
|
// written, and the visitor then gets a closed connection and no answer.
|
||||||
|
const ownAnswerMinSendTime = 10 * time.Second
|
||||||
|
|
||||||
// request is one request on its way through rproxy, from the moment its headers
|
// request is one request on its way through rproxy, from the moment its headers
|
||||||
// have been read to its log line and report.
|
// have been read to its log line and report.
|
||||||
type request struct {
|
type request struct {
|
||||||
@@ -326,14 +331,14 @@ func (rq *request) send(status int, body []byte) {
|
|||||||
// prepareOwnAnswer readies the connection for an answer rproxy gives itself: the
|
// prepareOwnAnswer readies the connection for an answer rproxy gives itself: the
|
||||||
// reading of a body that has not arrived whole ends at deadline, and the answer
|
// reading of a body that has not arrived whole ends at deadline, and the answer
|
||||||
// has SWRP_MAX_RESPONSE_TIME_MS from now to reach the visitor, even when the app
|
// has SWRP_MAX_RESPONSE_TIME_MS from now to reach the visitor, even when the app
|
||||||
// used that time up first.
|
// used that time up first, and at least ownAnswerMinSendTime.
|
||||||
func (rq *request) prepareOwnAnswer(deadline time.Time) {
|
func (rq *request) prepareOwnAnswer(deadline time.Time) {
|
||||||
rq.stopReadingBody(deadline)
|
rq.stopReadingBody(deadline)
|
||||||
rq.endRequest()
|
rq.endRequest()
|
||||||
|
|
||||||
limit := rq.h.config.MaxResponseTime
|
limit := rq.h.config.MaxResponseTime
|
||||||
if limit > 0 {
|
if limit > 0 {
|
||||||
_ = rq.rc.SetWriteDeadline(time.Now().Add(limit))
|
_ = rq.rc.SetWriteDeadline(time.Now().Add(max(limit, ownAnswerMinSendTime)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user