-
Notifications
You must be signed in to change notification settings - Fork 243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve error message for non compliant http servers missing \r\n (was Read error reported by fortio, but not curl/wrk) #913
Comments
Thanks, interesting, will try - can you check whether you get the same behavior with and without -stdclient ? |
well reading the code of the server: one issue is your server isn't http protocol compliant: "Server: webserver-c\n" should be \r\n for headers but looks like curl is lenient about that, let me see if I can make fortio just warn about it |
You're right, that actually fixes it! |
Interestingly, when running with
This does not happen when leaving |
I simplified the bad server code to: package main
import (
"fmt"
"log"
"net"
"os"
)
const maxNumConn = 1000
func main() {
if len(os.Args) < 2 {
fmt.Fprintf(os.Stderr, "Usage: %s <listen:port>\n", os.Args[0])
os.Exit(1)
}
laddr, err := net.ResolveTCPAddr("tcp", os.Args[1])
if err != nil {
log.Fatalf("Failed to resolve address: %v", err)
}
listener, err := net.ListenTCP("tcp", laddr)
if err != nil {
log.Fatalf("Failed to listen on %s: %v", laddr, err)
}
defer listener.Close()
fmt.Printf("Listening on %s\n", listener.Addr())
for {
conn, err := listener.AcceptTCP()
if err != nil {
log.Printf("Failed to accept connection: %v", err)
continue
}
fmt.Printf("New connection accepted: %s\n", conn.RemoteAddr())
go handleConnection(conn)
}
}
func handleConnection(conn *net.TCPConn) {
defer conn.Close()
buf := make([]byte, 1024)
for {
read, err := conn.Read(buf)
if err != nil {
log.Printf("Error reading from connection: %v", err)
return
}
fmt.Printf("Received request: %s\n", string(buf[:read]))
// \r missing on purpose
response := "HTTP/1.1 200 OK\n" +
"Server: webserver-go\n" +
"Content-Length: 26\n" +
"Content-type: text/html\n\n" +
"<html>hello, world</html>\n"
n, err := conn.Write([]byte(response))
if err != nil {
log.Printf("Error sending response: %v", err)
return
}
fmt.Printf("Response sent %d bytes\n", n)
}
} with which the error reproduces, including explanation when in debug logging: $ fortio curl -loglevel debug http://localhost:3000/foo
[...]
10:01:00.407 [DBG] [0] Read ok 107 total 107 so far (-0 headers = 107 data) HTTP/1.1 200 OK\nServer: webserver-go\nContent-Length: 26\nContent-type: text/html\n\n<html>hello, world</html>\n
10:01:00.407 [DBG] [0] Code 200, looking for end of headers at 12 / 107, last CRLF 0
10:01:03.409 [ERR] Read error, err={"Op":"read","Net":"tcp","Source":{"IP":"127.0.0.1","Port":59061,"Zone":""},"Addr":{"IP":"127.0.0.1","Port":3000,"Zone":""},"Err":{}}, size=107, dest={"IP":"127.0.0.1","Port":3000,"Zone":""}, url="http://localhost:3000/foo", thread=0, run=0 the key there is which could be in the error printout |
Thanks for the quick fix! I have also noticed that |
fortio does reuse sockets unless you tell it not to or the server closes them. I'd like to see the output when/if it does. It does tell you the exact number of sockets used at the end |
Hi,
I noticed that
fortio
reports lots of read errors when benchmarking a project of mine. Since I couldn't find the cause in my code, I double checked usingcurl
andwrk
. Both tools work fine, i.e. no read errors are reported. I threw together a little server written in C that makes the problem apparent. Here are some of the results:curl:
wrk:
But for fortio I get:
basic http server source code (note that it doesn't close any connections, so it caps out at 1000 conns):
You can compile and run it as follows:
I firs thought that I do something wrong while handling the sockets, but since
curl
andwrk
both seem to work fine, I'm not sure iffortio
might be the problem? Either way, I'd really appreciate your thoughts on this :)Cheers!
The text was updated successfully, but these errors were encountered: