Closed deadtrickster closed 9 years ago
Though Woo resets the parser by just making a new parser, providing a way to reset it would be better.
Values need to reset is not only completedp
, but also parser
. Low-level parser saves the status which part of HTTP request/response is reading.
(T
;; No Content-Length, no chunking, probably a request with no body
(setq completedp t))
This setq
can be omitted, I think.
I'm sorry what is Woo? :-) What if next message starts in the middle of the current chunk(think about HTTP 1.1 pipelining)?
(let* ((response (list #?"HTTP/1.1 200 OK\r\n"
#?"Content-Length: 2 \r\n"
#?"Content-Type: application/json \r\n"
#?"\r\n"
#?"qwHTTP/1.1 499 second response status?\r\n"
#?"Content-Length: 2 \r\n"
#?"\r\n"
#?"qw"))
(http (fast-http:make-http-response))
(parser (fast-http:make-parser http :header-callback (lambda (_)) :finish-callback (lambda () (print http)))))
(loop for res-chunk in response do
(funcall parser (trivial-utf-8:string-to-utf-8-bytes res-chunk))))
#S(FAST-HTTP.HTTP:HTTP-RESPONSE
:VERSION 11/10
:HEADERS {
"content-length" 2
"content-type" "application/json "
}
:STORE-BODY NIL
:FORCE-STREAM NIL
:BODY NIL
:STATUS 499
:STATUS-TEXT "second response status?")
#S(FAST-HTTP.HTTP:HTTP-RESPONSE
:VERSION 11/10
:HEADERS {
"content-length" "2, 2"
"content-type" "application/json "
}
:STORE-BODY NIL
:FORCE-STREAM NIL
:BODY NIL
:STATUS 499
:STATUS-TEXT "second response status?")
Also what you think about :store-body
part?
Woo is a web server I'm working on: https://github.com/fukamachi/woo
What if next message starts in the middle of the current chunk(think about HTTP 1.1 pipelining)?
That's tough. Current fast-http doesn't even call :message-begin
callback in this case.
Also what you think about :store-body part?
I'm not sure I could get which part is you're saying, but if it's about this example, deleting (setq completedp t)
in cond
would work.
(let* ((request (list #?"POST / HTTP/1.1\r\n"
#?"Host: www.example.com\r\n"
#?"Content-Type: application/x-www-form-urlencoded\r\n"
#?"Content-Length: 4 \r\n"
#?"\r\n"
#?"q=42\r\n"))
(http (fast-http:make-http-request :store-body t ))
(parser (fast-http:make-parser http :store-body t )))
(loop for req-chunk in request do
(when (nth-value 2 (funcall parser (trivial-utf-8:string-to-utf-8-bytes req-chunk)))
(print "Message Completed!"))))
"Message Completed!"
"Message Completed!"
I think this is resolved in different way. If there's still a problem, don't hesitate to reopen this.
_Keep-alive and completedp_
completedp
should be reset to nil immediately after it returned as T. Or all subsequent parser invocations will invokefinish-callback
and of course return T as third valueResponse:
Request:
_:store-body t_
While exploring
completedp
problem I noticed this:Here we have just single request, however "Message Completed!" printed twice. Because there no callbacks, headers in highlevel parser were not parsed at all and the following
cond
clause executed and resetcompletedp
toT
: