mrdg opened a new issue, #8951:
URL: https://github.com/apache/trafficserver/issues/8951
When a client sends a conditonal GET request with a body and the server
responds with a cache hit, the request body isn't drained. This results in the
next request on that connection getting a 400 response. It's arguably weird to
send a conditional GET with a body, but we're seeing requests like this pretty
regularly. It's especially problematic with a proxy in front of ATS, because
some other client might see the 400 if its request was sent over the same
connection.
The program below shows the issue. I tested it against master.
```go
package main
import (
"io"
"io/ioutil"
"log"
"net/http"
"strings"
)
func main() {
tr := http.Transport{
MaxConnsPerHost: 1,
}
// First request puts object in cache
req, _ := http.NewRequest("GET", "http://localhost:8080/cached", nil)
rsp, err := tr.RoundTrip(req)
if err != nil {
log.Fatal(err)
}
io.Copy(ioutil.Discard, rsp.Body)
log.Printf("%d", rsp.StatusCode)
// Conditional GET request with a body
req, _ = http.NewRequest("GET", "http://localhost:8080/cached",
strings.NewReader("\n"))
req.Header.Add("If-None-Match", rsp.Header.Get("ETag"))
rsp, err = tr.RoundTrip(req)
if err != nil {
log.Fatal(err)
}
log.Printf("%d", rsp.StatusCode)
// Server reads the body from the previous request as part of the next
request and returns
// a 400
req, _ = http.NewRequest("GET", "http://localhost:8080/cached", nil)
rsp, err = tr.RoundTrip(req)
if err != nil {
log.Fatal(err)
}
body, _ := ioutil.ReadAll(rsp.Body)
log.Printf("%d - %s", rsp.StatusCode, string(body))
}
```
This prints the following:
```
2022/07/09 13:03:52 200
2022/07/09 13:03:52 304
2022/07/09 13:03:52 400 - <HTML>
<HEAD>
<TITLE>Bad Request</TITLE>
</HEAD>
<BODY BGCOLOR="white" FGCOLOR="black">
<H1>Bad Request</H1>
<HR>
<FONT FACE="Helvetica,Arial"><B>
Description: Could not process this request.
</B></FONT>
<HR>
</BODY>
```
--------------------------------------------------
Looking at the code, it seems we're hitting this
[case](https://github.com/apache/trafficserver/blob/15bea4dd946c8cb6fc2000a4b31cf4f2f261b29d/proxy/http/HttpSM.cc#L7810)
on the second request. If I add a call to `do_drain_request_body` there, the
issue goes away, but I don't understand the code well enough to say if that's a
sensible fix.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]