2006-12-04 01:26:12 +00:00
|
|
|
|
--- Relevant portions of RFC2616 ---
|
|
|
|
|
|
|
|
|
|
OCTET = <any 8-bit sequence of data>
|
|
|
|
|
CHAR = <any US-ASCII character (octets 0 - 127)>
|
|
|
|
|
UPALPHA = <any US-ASCII uppercase letter "A".."Z">
|
|
|
|
|
LOALPHA = <any US-ASCII lowercase letter "a".."z">
|
|
|
|
|
ALPHA = UPALPHA | LOALPHA
|
|
|
|
|
DIGIT = <any US-ASCII digit "0".."9">
|
|
|
|
|
CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
|
|
|
|
|
CR = <US-ASCII CR, carriage return (13)>
|
|
|
|
|
LF = <US-ASCII LF, linefeed (10)>
|
|
|
|
|
SP = <US-ASCII SP, space (32)>
|
|
|
|
|
HT = <US-ASCII HT, horizontal-tab (9)>
|
|
|
|
|
<"> = <US-ASCII double-quote mark (34)>
|
|
|
|
|
CRLF = CR LF
|
|
|
|
|
LWS = [CRLF] 1*( SP | HT )
|
|
|
|
|
TEXT = <any OCTET except CTLs, but including LWS>
|
|
|
|
|
HEX = "A" | "B" | "C" | "D" | "E" | "F"
|
|
|
|
|
| "a" | "b" | "c" | "d" | "e" | "f" | DIGIT
|
|
|
|
|
separators = "(" | ")" | "<" | ">" | "@"
|
|
|
|
|
| "," | ";" | ":" | "\" | <">
|
|
|
|
|
| "/" | "[" | "]" | "?" | "="
|
|
|
|
|
| "{" | "}" | SP | HT
|
|
|
|
|
token = 1*<any CHAR except CTLs or separators>
|
|
|
|
|
|
|
|
|
|
quoted-pair = "\" CHAR
|
|
|
|
|
ctext = <any TEXT excluding "(" and ")">
|
|
|
|
|
qdtext = <any TEXT except <">>
|
|
|
|
|
quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
|
|
|
|
|
comment = "(" *( ctext | quoted-pair | comment ) ")"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 HTTP Message
|
|
|
|
|
4.1 Message Types
|
|
|
|
|
|
|
|
|
|
HTTP messages consist of requests from client to server and responses from
|
|
|
|
|
server to client. Request (section 5) and Response (section 6) messages use the
|
|
|
|
|
generic message format of RFC 822 [9] for transferring entities (the payload of
|
|
|
|
|
the message). Both types of message consist of :
|
|
|
|
|
|
|
|
|
|
- a start-line
|
|
|
|
|
- zero or more header fields (also known as "headers")
|
|
|
|
|
- an empty line (i.e., a line with nothing preceding the CRLF) indicating the
|
|
|
|
|
end of the header fields
|
|
|
|
|
- and possibly a message-body.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HTTP-message = Request | Response
|
|
|
|
|
|
|
|
|
|
start-line = Request-Line | Status-Line
|
|
|
|
|
generic-message = start-line
|
|
|
|
|
*(message-header CRLF)
|
|
|
|
|
CRLF
|
|
|
|
|
[ message-body ]
|
|
|
|
|
|
|
|
|
|
In the interest of robustness, servers SHOULD ignore any empty line(s) received
|
|
|
|
|
where a Request-Line is expected. In other words, if the server is reading the
|
|
|
|
|
protocol stream at the beginning of a message and receives a CRLF first, it
|
|
|
|
|
should ignore the CRLF.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4.2 Message headers
|
|
|
|
|
|
|
|
|
|
- Each header field consists of a name followed by a colon (":") and the field
|
|
|
|
|
value.
|
|
|
|
|
- Field names are case-insensitive.
|
|
|
|
|
- The field value MAY be preceded by any amount of LWS, though a single SP is
|
|
|
|
|
preferred.
|
|
|
|
|
- Header fields can be extended over multiple lines by preceding each extra
|
|
|
|
|
line with at least one SP or HT.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
message-header = field-name ":" [ field-value ]
|
|
|
|
|
field-name = token
|
|
|
|
|
field-value = *( field-content | LWS )
|
|
|
|
|
field-content = <the OCTETs making up the field-value and consisting of
|
|
|
|
|
either *TEXT or combinations of token, separators, and
|
|
|
|
|
quoted-string>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The field-content does not include any leading or trailing LWS occurring before
|
|
|
|
|
the first non-whitespace character of the field-value or after the last
|
|
|
|
|
non-whitespace character of the field-value. Such leading or trailing LWS MAY
|
|
|
|
|
be removed without changing the semantics of the field value. Any LWS that
|
|
|
|
|
occurs between field-content MAY be replaced with a single SP before
|
|
|
|
|
interpreting the field value or forwarding the message downstream.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
=> format des headers = 1*(CHAR & !ctl & !sep) ":" *(OCTET & (!ctl | LWS))
|
|
|
|
|
=> les regex de matching de headers s'appliquent sur field-content, et peuvent
|
|
|
|
|
utiliser field-value comme espace de travail (mais de pr<70>f<EFBFBD>rence apr<70>s le
|
|
|
|
|
premier SP).
|
|
|
|
|
|
|
|
|
|
(19.3) The line terminator for message-header fields is the sequence CRLF.
|
|
|
|
|
However, we recommend that applications, when parsing such headers, recognize
|
|
|
|
|
a single LF as a line terminator and ignore the leading CR.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
message-body = entity-body
|
|
|
|
|
| <entity-body encoded as per Transfer-Encoding>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 Request
|
|
|
|
|
|
|
|
|
|
Request = Request-Line
|
|
|
|
|
*(( general-header
|
|
|
|
|
| request-header
|
|
|
|
|
| entity-header ) CRLF)
|
|
|
|
|
CRLF
|
|
|
|
|
[ message-body ]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5.1 Request line
|
|
|
|
|
|
|
|
|
|
The elements are separated by SP characters. No CR or LF is allowed except in
|
|
|
|
|
the final CRLF sequence.
|
|
|
|
|
|
|
|
|
|
Request-Line = Method SP Request-URI SP HTTP-Version CRLF
|
|
|
|
|
|
|
|
|
|
(19.3) Clients SHOULD be tolerant in parsing the Status-Line and servers
|
|
|
|
|
tolerant when parsing the Request-Line. In particular, they SHOULD accept any
|
|
|
|
|
amount of SP or HT characters between fields, even though only a single SP is
|
|
|
|
|
required.
|
|
|
|
|
|
|
|
|
|
4.5 General headers
|
|
|
|
|
Apply to MESSAGE.
|
|
|
|
|
|
|
|
|
|
general-header = Cache-Control
|
|
|
|
|
| Connection
|
|
|
|
|
| Date
|
|
|
|
|
| Pragma
|
|
|
|
|
| Trailer
|
|
|
|
|
| Transfer-Encoding
|
|
|
|
|
| Upgrade
|
|
|
|
|
| Via
|
|
|
|
|
| Warning
|
|
|
|
|
|
|
|
|
|
General-header field names can be extended reliably only in combination with a
|
|
|
|
|
change in the protocol version. However, new or experimental header fields may
|
|
|
|
|
be given the semantics of general header fields if all parties in the
|
|
|
|
|
communication recognize them to be general-header fields. Unrecognized header
|
|
|
|
|
fields are treated as entity-header fields.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5.3 Request Header Fields
|
|
|
|
|
|
|
|
|
|
The request-header fields allow the client to pass additional information about
|
|
|
|
|
the request, and about the client itself, to the server. These fields act as
|
|
|
|
|
request modifiers, with semantics equivalent to the parameters on a programming
|
|
|
|
|
language method invocation.
|
|
|
|
|
|
|
|
|
|
request-header = Accept
|
|
|
|
|
| Accept-Charset
|
|
|
|
|
| Accept-Encoding
|
|
|
|
|
| Accept-Language
|
|
|
|
|
| Authorization
|
|
|
|
|
| Expect
|
|
|
|
|
| From
|
|
|
|
|
| Host
|
|
|
|
|
| If-Match
|
|
|
|
|
| If-Modified-Since
|
|
|
|
|
| If-None-Match
|
|
|
|
|
| If-Range
|
|
|
|
|
| If-Unmodified-Since
|
|
|
|
|
| Max-Forwards
|
|
|
|
|
| Proxy-Authorization
|
|
|
|
|
| Range
|
|
|
|
|
| Referer
|
|
|
|
|
| TE
|
|
|
|
|
| User-Agent
|
|
|
|
|
|
|
|
|
|
Request-header field names can be extended reliably only in combination with a
|
|
|
|
|
change in the protocol version. However, new or experimental header fields MAY
|
|
|
|
|
be given the semantics of request-header fields if all parties in the
|
|
|
|
|
communication recognize them to be request-header fields. Unrecognized header
|
|
|
|
|
fields are treated as entity-header fields.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7.1 Entity header fields
|
|
|
|
|
|
|
|
|
|
Entity-header fields define metainformation about the entity-body or, if no
|
|
|
|
|
body is present, about the resource identified by the request. Some of this
|
|
|
|
|
metainformation is OPTIONAL; some might be REQUIRED by portions of this
|
|
|
|
|
specification.
|
|
|
|
|
|
|
|
|
|
entity-header = Allow
|
|
|
|
|
| Content-Encoding
|
|
|
|
|
| Content-Language
|
|
|
|
|
| Content-Length
|
|
|
|
|
| Content-Location
|
|
|
|
|
| Content-MD5
|
|
|
|
|
| Content-Range
|
|
|
|
|
| Content-Type
|
|
|
|
|
| Expires
|
|
|
|
|
| Last-Modified
|
|
|
|
|
| extension-header
|
|
|
|
|
extension-header = message-header
|
|
|
|
|
|
|
|
|
|
The extension-header mechanism allows additional entity-header fields to be
|
|
|
|
|
defined without changing the protocol, but these fields cannot be assumed to be
|
|
|
|
|
recognizable by the recipient. Unrecognized header fields SHOULD be ignored by
|
|
|
|
|
the recipient and MUST be forwarded by transparent proxies.
|
|
|
|
|
|
2012-01-07 22:58:54 +00:00
|
|
|
|
----------------------------------
|
|
|
|
|
|
|
|
|
|
The format of Request-URI is defined by RFC3986 :
|
|
|
|
|
|
|
|
|
|
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
|
|
|
|
|
|
|
|
|
|
hier-part = "//" authority path-abempty
|
|
|
|
|
/ path-absolute
|
|
|
|
|
/ path-rootless
|
|
|
|
|
/ path-empty
|
|
|
|
|
|
|
|
|
|
URI-reference = URI / relative-ref
|
|
|
|
|
|
|
|
|
|
absolute-URI = scheme ":" hier-part [ "?" query ]
|
|
|
|
|
|
|
|
|
|
relative-ref = relative-part [ "?" query ] [ "#" fragment ]
|
|
|
|
|
|
|
|
|
|
relative-part = "//" authority path-abempty
|
|
|
|
|
/ path-absolute
|
|
|
|
|
/ path-noscheme
|
|
|
|
|
/ path-empty
|
|
|
|
|
|
|
|
|
|
scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
|
|
|
|
|
|
|
|
|
|
authority = [ userinfo "@" ] host [ ":" port ]
|
|
|
|
|
userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
|
|
|
|
|
host = IP-literal / IPv4address / reg-name
|
|
|
|
|
port = *DIGIT
|
|
|
|
|
|
|
|
|
|
IP-literal = "[" ( IPv6address / IPvFuture ) "]"
|
|
|
|
|
|
|
|
|
|
IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
|
|
|
|
|
|
|
|
|
|
IPv6address = 6( h16 ":" ) ls32
|
|
|
|
|
/ "::" 5( h16 ":" ) ls32
|
|
|
|
|
/ [ h16 ] "::" 4( h16 ":" ) ls32
|
|
|
|
|
/ [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
|
|
|
|
|
/ [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
|
|
|
|
|
/ [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
|
|
|
|
|
/ [ *4( h16 ":" ) h16 ] "::" ls32
|
|
|
|
|
/ [ *5( h16 ":" ) h16 ] "::" h16
|
|
|
|
|
/ [ *6( h16 ":" ) h16 ] "::"
|
|
|
|
|
|
|
|
|
|
h16 = 1*4HEXDIG
|
|
|
|
|
ls32 = ( h16 ":" h16 ) / IPv4address
|
|
|
|
|
IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
|
|
|
|
|
dec-octet = DIGIT ; 0-9
|
|
|
|
|
/ %x31-39 DIGIT ; 10-99
|
|
|
|
|
/ "1" 2DIGIT ; 100-199
|
|
|
|
|
/ "2" %x30-34 DIGIT ; 200-249
|
|
|
|
|
/ "25" %x30-35 ; 250-255
|
|
|
|
|
|
|
|
|
|
reg-name = *( unreserved / pct-encoded / sub-delims )
|
|
|
|
|
|
|
|
|
|
path = path-abempty ; begins with "/" or is empty
|
|
|
|
|
/ path-absolute ; begins with "/" but not "//"
|
|
|
|
|
/ path-noscheme ; begins with a non-colon segment
|
|
|
|
|
/ path-rootless ; begins with a segment
|
|
|
|
|
/ path-empty ; zero characters
|
|
|
|
|
|
|
|
|
|
path-abempty = *( "/" segment )
|
|
|
|
|
path-absolute = "/" [ segment-nz *( "/" segment ) ]
|
|
|
|
|
path-noscheme = segment-nz-nc *( "/" segment )
|
|
|
|
|
path-rootless = segment-nz *( "/" segment )
|
|
|
|
|
path-empty = 0<pchar>
|
|
|
|
|
|
|
|
|
|
segment = *pchar
|
|
|
|
|
segment-nz = 1*pchar
|
|
|
|
|
segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
|
|
|
|
|
; non-zero-length segment without any colon ":"
|
|
|
|
|
|
|
|
|
|
pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
|
|
|
|
|
|
|
|
|
query = *( pchar / "/" / "?" )
|
|
|
|
|
|
|
|
|
|
fragment = *( pchar / "/" / "?" )
|
|
|
|
|
|
|
|
|
|
pct-encoded = "%" HEXDIG HEXDIG
|
|
|
|
|
|
|
|
|
|
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
|
|
|
|
reserved = gen-delims / sub-delims
|
|
|
|
|
gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
|
|
|
|
|
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
|
|
|
|
/ "*" / "+" / "," / ";" / "="
|
|
|
|
|
|
|
|
|
|
=> so the list of allowed characters in a URI is :
|
|
|
|
|
|
|
|
|
|
uri-char = unreserved / gen-delims / sub-delims / "%"
|
|
|
|
|
= ALPHA / DIGIT / "-" / "." / "_" / "~"
|
|
|
|
|
/ ":" / "/" / "?" / "#" / "[" / "]" / "@"
|
|
|
|
|
/ "!" / "$" / "&" / "'" / "(" / ")" /
|
|
|
|
|
/ "*" / "+" / "," / ";" / "=" / "%"
|
|
|
|
|
|
|
|
|
|
Note that non-ascii characters are forbidden ! Spaces and CTL are forbidden.
|
|
|
|
|
Unfortunately, some products such as Apache allow such characters :-/
|
|
|
|
|
|
2007-01-07 11:43:29 +00:00
|
|
|
|
---- The correct way to do it ----
|
|
|
|
|
|
|
|
|
|
- one http_session
|
|
|
|
|
It is basically any transport session on which we talk HTTP. It may be TCP,
|
|
|
|
|
SSL over TCP, etc... It knows a way to talk to the client, either the socket
|
|
|
|
|
file descriptor or a direct access to the client-side buffer. It should hold
|
|
|
|
|
information about the last accessed server so that we can guarantee that the
|
|
|
|
|
same server can be used during a whole session if needed. A first version
|
|
|
|
|
without optimal support for HTTP pipelining will have the client buffers tied
|
|
|
|
|
to the http_session. It may be possible that it is not sufficient for full
|
|
|
|
|
pipelining, but this will need further study. The link from the buffers to
|
2007-03-03 12:54:32 +00:00
|
|
|
|
the backend should be managed by the http transaction (http_txn), provided
|
|
|
|
|
that they are serialized. Each http_session, has 0 to N http_txn. Each
|
|
|
|
|
http_txn belongs to one and only one http_session.
|
2007-01-07 11:43:29 +00:00
|
|
|
|
|
2007-03-03 12:54:32 +00:00
|
|
|
|
- each http_txn has 1 request message (http_req), and 0 or 1 response message
|
|
|
|
|
(http_rtr). Each of them has 1 and only one http_txn. An http_txn holds
|
|
|
|
|
informations such as the HTTP method, the URI, the HTTP version, the
|
|
|
|
|
transfer-encoding, the HTTP status, the authorization, the req and rtr
|
|
|
|
|
content-length, the timers, logs, etc... The backend and server which process
|
|
|
|
|
the request are also known from the http_txn.
|
2007-01-07 11:43:29 +00:00
|
|
|
|
|
|
|
|
|
- both request and response messages hold header and parsing informations, such
|
2007-03-03 12:54:32 +00:00
|
|
|
|
as the parsing state, start of headers, start of message, captures, etc...
|
2007-01-07 11:43:29 +00:00
|
|
|
|
|