Subclass should refine read_full_request
and avoid read_callback
.
nitcorn :: HTTPConnection :: defaultinit
nitcorn :: HTTPConnection :: read_http_request
Callback when a full HTTP request is receivednitcorn $ HTTPConnection :: SELF
Type of this instance, automatically specialized in every classnitcorn $ HTTPConnection :: read_callback
FIXME will not work if the header/body delimiter falls between two watermarks windows.binary :: BinaryStream :: big_endian
Use the big-endian convention? otherwise use little-endian.binary :: BinaryStream :: big_endian=
Use the big-endian convention? otherwise use little-endian.core :: Object :: class_factory
Implementation used byget_class
to create the specific class.
libevent :: Connection :: close_requested
Closing this connection has been requested, but may not yet beclosed
libevent :: Connection :: close_requested=
Closing this connection has been requested, but may not yet beclosed
libevent :: Connection :: defaultinit
core :: Stream :: defaultinit
nitcorn :: HTTPConnection :: defaultinit
core :: Object :: defaultinit
binary :: BinaryStream :: defaultinit
core :: Writer :: defaultinit
libevent :: Connection :: event_callback
Callback method on events: EOF, user-defined timeout and unrecoverable errorslibevent :: Connection :: force_close
Force closing this connection and freeingnative_buffer_event
core :: Object :: is_same_instance
Return true ifself
and other
are the same instance (i.e. same identity).
core :: Object :: is_same_serialized
Isself
the same as other
in a serialization context?
core :: Object :: is_same_type
Return true ifself
and other
have the same dynamic type.
core :: Stream :: last_error=
Error produced by the file streamcore :: Stream :: lookahead=
Lookahead buffer for codecscore :: Stream :: lookahead_capacity
Capacity of the lookaheadcore :: Stream :: lookahead_capacity=
Capacity of the lookaheadcore :: Stream :: lookahead_length
Current occupation of the lookaheadcore :: Stream :: lookahead_length=
Current occupation of the lookaheadlibevent :: Connection :: native_buffer_event
The native libevent linked toself
libevent :: Connection :: native_buffer_event=
The native libevent linked toself
core :: Object :: output_class_name
Display class name on stdout (debug only).libevent :: Connection :: read_callback
Callback method when data is available to readnitcorn :: HTTPConnection :: read_http_request
Callback when a full HTTP request is receivedcore :: Writer :: serialize_msgpack
Serializevalue
in MessagePack format
core :: Writer :: write_block
Write the length as a 64 bits integer, then the content oftext
core :: Writer :: write_bool
Write a booleanvalue
on a byte, using 0 for false
and 1 for true
core :: Stream :: write_buffer
Buffer for writing data to a streamcore :: Stream :: write_buffer=
Buffer for writing data to a streamcore :: Writer :: write_bytes_from_cstring
Writelen
bytes from ns
core :: Writer :: write_double
Write a floating pointvalue
on 64 bits
core :: Writer :: write_int64
Writevalue
as a signed integer on 64 bits
core :: Writer :: write_msgpack_array
Write an array header forlen
items in the shortest possible MessagePack array format
core :: Writer :: write_msgpack_array16
Write an array header forlen
items, max of 0xFFFF items
core :: Writer :: write_msgpack_array32
Write an array header forlen
items, max of 0xFFFF_FFFF items
core :: Writer :: write_msgpack_bin
Writedata
in the shortest possible MessagePack bin format
core :: Writer :: write_msgpack_bin16
Writedata
in bin16 format, max of 0xFFFF bytes
core :: Writer :: write_msgpack_bin32
Writedata
in bin32 format, max of 0xFFFF_FFFF bytes
core :: Writer :: write_msgpack_bin8
Writedata
in bin8 format, max of 0xFF bytes
core :: Writer :: write_msgpack_bool
Writebool
in MessagePack format
core :: Writer :: write_msgpack_double
Writevalue
as a MessagePack double
core :: Writer :: write_msgpack_ext
Write an application-specific extension fortyp
and bytes
in the shortest possible MessagePack ext format
core :: Writer :: write_msgpack_ext16
Write the header for an application-specific extension oflen
data bytes
core :: Writer :: write_msgpack_ext32
Write the header for an application-specific extension oflen
data bytes
core :: Writer :: write_msgpack_ext8
Write the header for an application-specific extension oflen
data bytes
core :: Writer :: write_msgpack_fixarray
Write an array header forlen
items, max of 0x0F items
core :: Writer :: write_msgpack_fixext1
Write the header for an application-specific extension of one data bytecore :: Writer :: write_msgpack_fixext16
Write the header for an application-specific extension of 16 data bytescore :: Writer :: write_msgpack_fixext2
Write the header for an application-specific extension of two data bytescore :: Writer :: write_msgpack_fixext4
Write the header for an application-specific extension of 4 data bytescore :: Writer :: write_msgpack_fixext8
Write the header for an application-specific extension of 8 data bytescore :: Writer :: write_msgpack_fixint
Writevalue
as a single byte with metadata
core :: Writer :: write_msgpack_fixmap
Write a map header forlen
key/value pairs, max of 0x0F pairs
core :: Writer :: write_msgpack_fixstr
Writetext
in fixstr format, max of 0x1F bytes
core :: Writer :: write_msgpack_float
Writevalue
as a MessagePack float (losing precision)
core :: Writer :: write_msgpack_int
Write the integervalue
either as the shortest possible MessagePack int
core :: Writer :: write_msgpack_int16
Writevalue
over two signed bytes, following 1 metadata byte
core :: Writer :: write_msgpack_int32
Writevalue
over 4 signed bytes, following 1 metadata byte
core :: Writer :: write_msgpack_int64
Writevalue
over 8 signed bytes, following 1 metadata byte
core :: Writer :: write_msgpack_int8
Writevalue
over one signed byte, following 1 metadata byte
core :: Writer :: write_msgpack_map
Write a map header forlen
keys/value pairs in the shortest possible MessagePack map format
core :: Writer :: write_msgpack_map16
Write a map header forlen
key/value pairs, max of 0xFFFF pairs
core :: Writer :: write_msgpack_map32
Write a map header forlen
key/value pairs, max of 0xFFFF_FFFF pairs
core :: Writer :: write_msgpack_null
Writenull
, or nil, in MessagePack format
core :: Writer :: write_msgpack_str
Writetext
in the shortest possible MessagePack format
core :: Writer :: write_msgpack_str16
Writetext
in str16 format, max of 0xFFFF bytes
core :: Writer :: write_msgpack_str32
Writetext
in str32 format, max of 0xFFFF_FFFF bytes
core :: Writer :: write_msgpack_str8
Writetext
in str8 format, max of 0xFF bytes
core :: Writer :: write_msgpack_uint16
Writevalue
over two unsigned bytes, following 1 metadata byte
core :: Writer :: write_msgpack_uint32
Writevalue
over 4 unsigned bytes, following 1 metadata byte
core :: Writer :: write_msgpack_uint64
Writevalue
over 8 unsigned bytes, following 1 metadata byte
core :: Writer :: write_msgpack_uint8
Writevalue
over one unsigned byte, following 1 metadata byte
# Connection rebuilding HTTP requests
#
# Subclass should refine `read_full_request` and avoid `read_callback`.
class HTTPConnection
super Connection
private var in_request = false
private var in_header = false
private var in_body = false
private var current_header = new Array[Writable]
private var current_body = new Array[Writable]
private var content_length = 0
private var current_length = 0
# FIXME will not work if the header/body delimiter falls between two watermarks windows.
redef fun read_callback(str)
do
# is this the start of a request?
if not in_request then parse_start
var body: String
# parsing header
if in_header then
body = parse_header(str)
else
body = str
end
# parsing body
if in_body then parse_body(body)
end
# Callback when a full HTTP request is received
fun read_http_request(str: String) do end
# Prepare for a new request
private fun parse_start do
in_request = true
# reset values
current_header.clear
current_body.clear
current_length = 0
content_length = 0
# next step is to find the header part
in_header = true
in_body = false
end
# We are receiving the header of a request
#
# Return parsed body found in header window
private fun parse_header(str: String): String do
# split in CRLF
var parts = str.split("\r\n\r\n")
# first part go in the header
current_header.add parts.shift
# if there is more part we are done with headers
if not parts.is_empty then
# get content-length
parse_content_length current_header.join
# next step if to parse body
in_header = false
in_body = true
# return rest of the body
return parts.join("\r\n")
end
return ""
end
# Extract and set `content_length` from header.
private fun parse_content_length(head: String) do
var hlines = head.split("\r\n")
for hline in hlines do
var hparts = hline.split(": ")
if hparts.first == "Content-Length" then
content_length = hparts[1].to_i
end
end
end
# We are receiving body parts.
private fun parse_body(str: String) do
current_length += str.byte_length
current_body.add str
if current_length >= content_length then
parse_end
end
end
# We have reached the end of the body
private fun parse_end do
var res = new FlatBuffer.with_capacity(content_length)
for ch in current_header do res.append ch.write_to_string
res.append "\r\n\r\n"
for cb in current_body do res.append cb.write_to_string
read_http_request res.to_s
in_request = false
end
end
lib/nitcorn/http_request_buffer.nit:20,1--119,3