fukamachi / woo

A fast non-blocking HTTP server on top of libev
http://ultra.wikia.com/wiki/Woo_(kaiju)
MIT License
1.27k stars 96 forks source link

Server hangs with certain GET request #109

Closed tetrazolium closed 7 months ago

tetrazolium commented 7 months ago

Environment Info:

Machine: Linux 5.15.0-200.131.27.el8uek.aarch64
Lisp: SBCL 2.3.10
ASDF: 3.3.1
; Fetching #<URL "http://beta.quicklisp.org/dist/quicklisp-versions.txt">
; 9.50KB
==================================================
9,728 bytes in 0.00 seconds (0.00KB/sec)
Quicklisp: 2023-10-21 (latest)
NIL

The OS is Oracle Linux 8

Reproduction steps: Run

(woo:run
  (lambda (env)
    (declare (ignore env))
    '(200 (:content-type "text/plain") ("Hello, World"))))

Then, outside of sbcl, do "ncat \ \", then type GET / #.(+ 1 1) This causes the server to hang. I've tested on both a server running Oracle Linux and on a x64 laptop, and this get request causes the server to hang on both, regardless of whether the request originates remotely or locally. Another get request that causes this is GET / #`(+ 1 1) Backtrace: Not available, because the server hangs and nothing is output

fukamachi commented 7 months ago

Thank you for reporting. It appears that fast-http is stuck in an infinite loop for an invalid HTTP version. I'll work on fixing it.

fukamachi commented 7 months ago

I made changes in fast-http to fix it. Please confirm it with the HEAD of fast-http.

tetrazolium commented 7 months ago

That fixed it, thank you!

tetrazolium commented 7 months ago

Actually, there still is an issue, albeit a different one. I'm using ncat to test my server, and Ncat doesn't automatically convert LF into CRLF unless given the -C flag. Since I was running ncat from linux and sending LFs, this resulted in 400 errors. Previously it was still hanging before it could return a 400 error - that issue is fixed, but if I send GET / XMPP/-1.0 via ncat -C <ip> <port>, it gives me the error:

debugger invoked on a FAST-HTTP.ERROR:CB-MESSAGE-COMPLETE in thread
#<THREAD tid=338538 "main thread" RUNNING {10051F0423}>:
  Callback Error: the message-complete callback failed
  INVALID-HTTP-VERSION: major 0 minor 9

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

((LAMBDA (#:E7) :IN FAST-HTTP.PARSER::PARSE-BODY) #<unavailable argument>)
   source: (MESSAGE-COMPLETE)

I'm still running the same example code from earlier,

(woo:run
  (lambda (env)
    (declare (ignore env))
    '(200 (:content-type "text/plain") ("Hello, World"))))
fukamachi commented 7 months ago

It’s intended. If it finds a character which isn’t allowed in a URL path and the HTTP version either, it will raise an error beacuse every line is supposed to end with CRLF in HTTP.

tetrazolium commented 7 months ago

Sorry, I might have been unclear. The issue I'm reporting is unrelated to CRLF/LF. Sending a GET like GET / HTTP/0.9 will make the server enter the debugger with the INVALID-HTTP-VERSION: major 0 minor 9 error. Similarly, GET / TEST/-1.0 and GET / TEST/0.9 will also do this.

fukamachi commented 7 months ago

I got your point. But, it is still intended because Woo accepts only HTTP/1.0 or HTTP/1.1 since it's an HTTP/1 server.

tetrazolium commented 7 months ago

Ah, I see. I mostly submitted it since I've been trying to run clack with woo on a public server, but it kept triggering the debugger from random internet traffic. I'll just try to work around it then.

fukamachi commented 7 months ago

You can disable the CL debugger by passing :debug nil to woo:run.

tetrazolium commented 7 months ago

Oh, okay! Thanks!