7.8. Http

Http dissector module.

Usage:

local http = require('protocol/http')

7.8.1. Dissector

dissector HttpDissector
Name :'http'
Extend :haka.helper.FlowDissector 

HTTP protocol dissector supporting the following features:

  • HTTP 1.0 and 1.1
  • Chunked transfer mode
  • Request analysis
  • Reponse analysis
  • Keep-alive connections
http.install_tcp_rule(port)
Parameters:
  • port (number) – TCP port number.

Install a rule on TCP to enable HTTP dissection on the given port number.

http.dissect(flow)
Parameters:

Activate HTTP dissection on the given flow.

<HttpDissector>.flow

Flow from which HTTP is built.

<HttpDissector>:enable_data_modification()

Activate data modification for all data received along with the current request or response. This mode allow to modify on the fly any data without having to handle chunk sizes or the content-length header.

<HttpDissector>:drop()

Drop the associated flow.

<HttpDissector>:reset()

Reset the current HTTP connection. The client and the server will be notified with RST tcp packets.

7.8.2. Protocol elements

object http.HttpHeaders

Parsed headers information for HTTP.

<HttpHeaders>[name] → value
<HttpHeaders>[name] = newvalue
Parameters:
  • name (string) – Header name.
  • newvalue (string) – New header value.
Returns:
  • value (string) – Current header value.

Access and modify any HTTP header.

pairs(<HttpHeaders>) → key,value
Returns:
  • key (string) – Header key.
  • value (string) – Header value.

Return an iterator over all headers.

object http.HttpRequest

Parsed information about a request.

<HttpRequest>.method
<HttpRequest>.uri
<HttpRequest>.version
Type:string

Request line elements.

<HttpRequest>.headers
Type:HttpHeaders 

Headers table.

object http.HttpResponse

Parsed information about a response.

<HttpRequest>.version
<HttpRequest>.status
<HttpRequest>.reason
Type:string

Response line elements.

<HttpRequest>.headers
Type:HttpHeaders 

Headers table.

7.8.3. Events

event http.events.request(http, request)
Parameters:

Event triggered whenever a new HTTP request is received.

event http.events.response(http, response)
Parameters:

Event triggered whenever a new HTTP response is received.

event http.events.receive_data(http, stream, current, direction)

Event options:

streamed
Type:boolean

Run the event listener as a streamed function.

Parameters:

Event triggered when some data are available on either a request or a response.

event http.events.request_data(http, stream, current)

Event options:

streamed
Type:boolean

Run the event listener as a streamed function.

Parameters:

Event triggered when some data are available on a request.

event http.events.response_data(http, stream, current)

Event options:

streamed
Type:boolean

Run the event listener as a streamed function.

Parameters:

Event triggered when some data are available on a response.

7.8.4. Utilities

object HttpUriSplit
http.uri.split(uri) → split
Parameters:
  • uri (string) – Uri to split.
Returns:

Split uri into subparts.

Example:

http.uri.split('http://www.example.com:8888/foo/page.php')
<HttpUriSplit>.scheme
Type:string

Uri scheme.

<HttpUriSplit>.authority
Type:string

Uri authority.

<HttpUriSplit>.host
Type:string

Uri host.

<HttpUriSplit>.userinfo
Type:string

Uri user information.

<HttpUriSplit>.user
Type:string

Uri user (from userinfo).

<HttpUriSplit>.pass
Type:string

Uri password (from userinfo).

Note

rfc 3986 states that the format “user:password” in the userinfo field is deprecated.

<HttpUriSplit>.port
Type:string

Uri port.

<HttpUriSplit>.path
Type:string

Uri path.

<HttpUriSplit>.query
Type:string

Uri query.

<HttpUriSplit>.args
Type:table

Uri query’s parameters.

<HttpUriSplit>.fragment
Type:string

Uri fragment.

tostring(<HttpUriSplit>) → str
Returns:
  • str (string) – Full uri.

Recreate the uri full string.

<HttpUriSplit>:normalize()

Normalize URI according to rfc 3986: remove dot-segments in path, capitalize letters in escape sequences, decode percent-encoded octets (safe decoding), remove default port, etc.

http.uri.normalize(uri) → norm_uri
Parameters:
  • uri (string) – Uri.
Returns:
  • norm_uri (string) – Normalized uri.

Normalize URI according to rfc 3986.

object http.cookies.HttpCookiesSplit

Store the cookies as a table of key-value pairs.

http.cookies.split(cookies) → split_cookies
Parameters:
  • cookies (string) – Cookies line extracted from the HTTP headers.
Returns:

Parse the cookies and split them.

tostring(<HttpCookiesSplit>) → str
Returns:
  • str (string) – String containing all cookies.

Return all cookies as a string.

<HttpCookiesSplit>[key] → value
<HttpCookiesSplit>[key] = newvalue
Parameters:
  • name (string) – Cookie name.
  • newvalue (string) – New cookie value.
Returns:
  • value (string) – Current cookie value.

Access and modify any cookies in the table.

7.8.5. Example

------------------------------------
---- Loading regex engine
--------------------------------------

local rem = require("regexp/pcre")


--local http_methods = '^get$|^post$|^head$|^put$|^trace$|^delete$|^options$'
--local re = rem.re:compile(http_methods, rem.re.CASE_INSENSITIVE)
--

------------------------------------
-- HTTP Policy
------------------------------------

-- add custom user-agent
haka.rule {
    hook = http.events.request,
    eval = function (http, request)
        request.headers["User-Agent"] = "Haka User-Agent"
    end
}

-- report and alert if method is different than get and post
haka.rule {
    hook = http.events.request,
    eval = function (http, request)
        local method = request.method
        if not rem.re:match('^get$|^post$', method, rem.re.CASE_INSENSITIVE) then
            haka.alert{
                description = string.format("forbidden http method '%s'", method),
                sources = haka.alert.address(http.flow.srcip),
                targets = {
                    haka.alert.address(http.flow.dstip),
                    haka.alert.service(string.format("tcp/%d", http.flow.dstport), "http")
                },
            }
        end
    end
}