]>
Commit | Line | Data |
---|---|---|
e02d9044 AJ |
1 | #ifndef _SQUID_SRC_HTTP_HTTP1PARSER_H |
2 | #define _SQUID_SRC_HTTP_HTTP1PARSER_H | |
4c14658e | 3 | |
25f0d354 | 4 | #include "base/RefCount.h" |
274bd5ad | 5 | #include "http/forward.h" |
5aedd08d | 6 | #include "http/ProtocolVersion.h" |
9ff1b8ca | 7 | #include "http/RequestMethod.h" |
955394ce | 8 | #include "http/StatusCode.h" |
eb1bd364 | 9 | #include "SBuf.h" |
4c14658e | 10 | |
bb86dcd4 AJ |
11 | namespace Http { |
12 | ||
4c14658e AJ |
13 | // Parser states |
14 | #define HTTP_PARSE_NONE 0 // nothing. completely unset state. | |
15 | #define HTTP_PARSE_NEW 1 // initialized, but nothing usefully parsed yet. | |
b6a7fc85 | 16 | #define HTTP_PARSE_FIRST 2 // have parsed request first line |
f4880526 | 17 | #define HTTP_PARSE_MIME 3 // have located end of mime header block |
87abd755 | 18 | #define HTTP_PARSE_DONE 99 // have done with parsing so far |
4c14658e AJ |
19 | |
20 | /** HTTP protocol parser. | |
21 | * | |
22 | * Works on a raw character I/O buffer and tokenizes the content into | |
23 | * either an error state or, an HTTP procotol request major segments: | |
24 | * | |
25 | * \item Request Line (method, URL, protocol, version) | |
26 | * \item Mime header block | |
27 | */ | |
bb86dcd4 | 28 | class Http1Parser : public RefCountable |
4c14658e AJ |
29 | { |
30 | public: | |
bb86dcd4 | 31 | typedef RefCount<Http1Parser> Pointer; |
25f0d354 | 32 | |
bb86dcd4 | 33 | Http1Parser() { clear(); } |
4c14658e AJ |
34 | |
35 | /** Initialize a new parser. | |
36 | * Presenting it a buffer to work on and the current length of available | |
37 | * data. | |
38 | * NOTE: This is *not* the buffer size, just the parse-able data length. | |
39 | * The parse routines may be called again later with more data. | |
40 | */ | |
bb86dcd4 | 41 | Http1Parser(const char *aBuf, int len) { reset(aBuf,len); }; |
4c14658e AJ |
42 | |
43 | /// Set this parser back to a default state. | |
44 | /// Will DROP any reference to a buffer (does not free). | |
45 | void clear(); | |
46 | ||
47 | /// Reset the parser for use on a new buffer. | |
48 | void reset(const char *aBuf, int len); | |
49 | ||
87abd755 AJ |
50 | /** Whether the parser is already done processing the buffer. |
51 | * Use to determine between incomplete data and errors results | |
52 | * from the parse methods. | |
53 | */ | |
54 | bool isDone() const {return completedState_==HTTP_PARSE_DONE;} | |
b6a7fc85 | 55 | |
7e1d6c48 AJ |
56 | /// size in bytes of the first line (request-line) |
57 | /// including CRLF terminator | |
58 | int64_t firstLineSize() const {return req.end - req.start + 1;} | |
59 | ||
f4880526 | 60 | /// size in bytes of the message headers including CRLF terminator(s) |
7e1d6c48 | 61 | /// but excluding request-line bytes |
eb1bd364 | 62 | int64_t headerBlockSize() const {return mimeHeaderBlock_.length();} |
7e1d6c48 AJ |
63 | |
64 | /// size in bytes of HTTP message block, includes request-line and mime headers | |
65 | /// excludes any body/entity/payload bytes | |
f4880526 AJ |
66 | /// excludes any garbage prefix before the request-line |
67 | int64_t messageHeaderSize() const {return firstLineSize() + headerBlockSize();} | |
7e1d6c48 | 68 | |
eb1bd364 AJ |
69 | /// buffer containing HTTP mime headers, excluding request or status line. |
70 | const char *rawHeaderBuf() {return mimeHeaderBlock_.c_str();} | |
7e1d6c48 | 71 | |
87abd755 AJ |
72 | /** Attempt to parse a request. |
73 | * \return true if a valid request was parsed. | |
74 | * \note Use isDone() method to determine between incomplete parse and errors. | |
75 | */ | |
87abd755 | 76 | bool parseRequest(); |
afff15b2 | 77 | |
a4181565 AJ |
78 | /** |
79 | * \return A pointer to a field-value of the first matching field-name, or NULL. | |
80 | */ | |
81 | char *getHeaderField(const char *name); | |
82 | ||
4c14658e | 83 | public: |
4c14658e AJ |
84 | const char *buf; |
85 | int bufsiz; | |
74f478f8 | 86 | |
5aedd08d AJ |
87 | /// the protocol label for this message |
88 | const AnyP::ProtocolVersion & messageProtocol() const {return msgProtocol_;} | |
89 | ||
9ff1b8ca AJ |
90 | /// the HTTP method if this is a request message |
91 | const HttpRequestMethod & method() const {return method_;} | |
274bd5ad | 92 | |
9ff1b8ca AJ |
93 | /// the request-line URI if this is a request message, or an empty string. |
94 | const SBuf &requestUri() const {return uri_;} | |
5f3cc9a2 | 95 | |
74f478f8 | 96 | // TODO: Offsets for pieces of the (HTTP reply) Status-Line as per RFC 2616 |
4c14658e AJ |
97 | |
98 | /** HTTP status code to be used on the invalid-request error page | |
955394ce | 99 | * Http::scNone indicates incomplete parse, Http::scOkay indicates no error. |
4c14658e | 100 | */ |
955394ce | 101 | Http::StatusCode request_parse_status; |
b6a7fc85 AJ |
102 | |
103 | private: | |
c11191e0 AJ |
104 | bool skipGarbageLines(); |
105 | int parseRequestFirstLine(); | |
106 | ||
5ff9a17a AJ |
107 | /// Offsets for pieces of the (HTTP request) Request-Line as per RFC 2616 |
108 | struct request_offsets { | |
109 | int start, end; | |
110 | int m_start, m_end; // method | |
111 | int u_start, u_end; // url | |
112 | int v_start, v_end; // version (full text) | |
113 | } req; | |
114 | ||
b6a7fc85 AJ |
115 | /// byte offset for non-parsed region of the buffer |
116 | size_t parseOffset_; | |
117 | ||
118 | /// what stage the parser is currently up to | |
119 | uint8_t completedState_; | |
5aedd08d AJ |
120 | |
121 | /// what protocol label has been found in the first line | |
122 | AnyP::ProtocolVersion msgProtocol_; | |
274bd5ad AJ |
123 | |
124 | /// what request method has been found on the first line | |
9ff1b8ca | 125 | HttpRequestMethod method_; |
f4880526 | 126 | |
5f3cc9a2 AJ |
127 | /// raw copy of the origina client reqeust-line URI field |
128 | SBuf uri_; | |
129 | ||
eb1bd364 AJ |
130 | /// buffer holding the mime headers |
131 | SBuf mimeHeaderBlock_; | |
4c14658e AJ |
132 | }; |
133 | ||
bb86dcd4 AJ |
134 | } // namespace Http |
135 | ||
e02d9044 | 136 | #endif /* _SQUID_SRC_HTTP_HTTP1PARSER_H */ |