lua-http-parser
lua-http-parser copied to clipboard
Lua binding to Ryan Dahl's "http-parser".
- Author : Brian Maher
- Library : lua-http-parser - Lua 5.1 interface to ry's http-parser
- The MIT License
- Copyright (c) 2009-1010 Brian Maher
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
To use this library, you need nodejs http-parser, get it here: git clone git://github.com/nodejs/http-parser.git
To build this library, you need luarocks, get it here: http://www.luarocks.org/en/Download
Then build it like this:
luarocks make CFLAGS=-g
Loading the library:
If you built the library as a loadable package
[local] lhp = require 'http.parser'
If you compiled the package statically into your application, call
the function "luaopen_http_parser(L)". It will create a table with the
http parser functions and leave it on the top of the stack.
To test the library run:
./test.lua
...assuming that the `lua` on your PATH properly uses the luarocks
installed module.
API:
parser = lhp.request {
on_url = function(url) ... end
on_header = function(hkey, hval) ... end
on_body = function(body) ... end
on_message_begin = function() ... end
on_message_complete = function() ... end
on_headers_complete = function() ... end
on_chunk_header = function(content_length) ... end
on_chunk_complete = function() ... end
}
parser = lhp.response { -- same as request except `on_url`. Plus
on_status = function(code, text) ... end
}
Create a new HTTP parser to handle either an HTTP request or
HTTP response respectively. Pass in a table of callbacks that
are ran when the parser encounters the various fields. All
callbacks will be ran with the full value for that field with
on_body being the notible exception.
You can treat the on_body handler as an LTN12 "source" since
it is always garanteed to send a terminating on_body(nil)
event when the complete body has been read. Note that the
on_body(nil) event will even be sent if there is an empty
body.
NOTE: Ry's http parser may call any of these callbacks with a
partial value if the input_bytes are split on a "token"
boundary. At this point we always assume that you will want
everything except the body to be buffered, but if you have a
valid use case for manually setting which callbacks are
buffered, please send an email to the author.
bytes_read = parser:execute(input_bytes)
Feed the parser some partial input. Returns how many bytes
where read. A short read may happen if a request is being
"upgraded" or was an invalid format. See parser:is_upgrade()
below to differentiate between these two events (if you want
to support an upgraded protocol).
NOTE: If the input_bytes causes more than about 2000 event
callbacks to be executed a short read will occur and any
attempt to continue the parse will fail. If this is a
problem, restrict your input to < 8K input_bytes at a time,
although in general this is probaly more of a symptom of a
DDoS attack and therefore returning status 400 (Bad Request)
is probably the best thing to do anyways.
parser:should_keep_alive()
Returns true if this TCP connection should be "kept alive"
so that it can be re-used for a future request/response.
If this returns false and you are the server, then respond
with the "Connection: close" header. If you are the client,
then simply close the connection.
parser:is_upgrade()
Returns true if the input request wants to "upgrade" to a
different protocol.
parser:version()
Returns HTTP version as two numbers (major, minor).
parser:method()
Returns the name of the request method. This is only valid
on HTTP requests.
parser:error()
Returns errno(number), error name(string), error description(string).
parser:reset([callbacks])
Re-initialize HTTP parser clearing any previous error/state.
parser:status_code()
Returns the HTTP status code of a response. This is only valid
on HTTP responses.