/lua-http-parser

Lua binding to Ryan Dahl's "http-parser".

Primary LanguageLuaMIT LicenseMIT

**********************************************************************
* Author  : Brian Maher <maherb at brimworks dot com>
* 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 joyent's http-parser, get it here:
    git clone git://github.com/joyent/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
    }
    parser = lhp.response { ... }

        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:status_code()

        Returns the HTTP status code of a response.  This is only valid
        on HTTP responses.