lua-http-parser icon indicating copy to clipboard operation
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.