]> git.ipfire.org Git - thirdparty/squid.git/blame - src/http/Http1Parser.h
Merge fron trunk rev.13398
[thirdparty/squid.git] / src / http / Http1Parser.h
CommitLineData
1b51ee7b
AJ
1#ifndef _SQUID_SRC_HTTP_ONEREQUESTPARSER_H
2#define _SQUID_SRC_HTTP_ONEREQUESTPARSER_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 11namespace Http {
1b51ee7b 12namespace One {
bb86dcd4 13
4c14658e 14// Parser states
678451c0
AJ
15enum ParseState {
16 HTTP_PARSE_NONE =0, ///< nothing. completely unset state.
17 HTTP_PARSE_NEW =1, ///< initialized, but nothing usefully parsed yet
18 HTTP_PARSE_FIRST, ///< HTTP/1 message first line
19 HTTP_PARSE_MIME, ///< mime header block
20 HTTP_PARSE_DONE ///< completed with parsing a full request header
21};
4c14658e
AJ
22
23/** HTTP protocol parser.
24 *
00589b8e 25 * Works on a raw character I/O buffer and tokenizes the content into
7322c9dd 26 * either an error state or HTTP procotol major sections:
4c14658e 27 *
7322c9dd
AJ
28 * \item first-line (request-line / simple-request / status-line)
29 * \item mime-header block
4c14658e 30 */
7322c9dd 31class Parser : public RefCountable
4c14658e
AJ
32{
33public:
7322c9dd 34 Parser() { clear(); }
4c14658e
AJ
35
36 /** Initialize a new parser.
7322c9dd 37 * Presenting it a buffer to work on and the current length of available data.
4c14658e
AJ
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 */
bfe8bc51 41 Parser(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).
7322c9dd 45 virtual void clear();
4c14658e
AJ
46
47 /// Reset the parser for use on a new buffer.
48 void reset(const char *aBuf, int len);
49
f9daf571
AJ
50 /** Adjust parser state to account for a buffer shift of n bytes.
51 *
52 * The leftmost n bytes bytes have been dropped and all other
53 * bytes shifted left n positions.
54 */
678451c0 55 virtual void noteBufferShift(const int64_t n) = 0;
f9daf571 56
87abd755
AJ
57 /** Whether the parser is already done processing the buffer.
58 * Use to determine between incomplete data and errors results
f9daf571 59 * from the parse.
87abd755 60 */
cbcd99df 61 bool isDone() const {return parsingStage_==HTTP_PARSE_DONE;}
b6a7fc85 62
cbcd99df
AJ
63 /// number of bytes at the start of the buffer which are no longer needed
64 int64_t doneBytes() const {return (int64_t)parseOffset_;}
f9daf571
AJ
65
66 /// size in bytes of the first line including CRLF terminator
7322c9dd 67 virtual int64_t firstLineSize() const = 0;
7e1d6c48 68
f4880526 69 /// size in bytes of the message headers including CRLF terminator(s)
7322c9dd 70 /// but excluding first-line bytes
eb1bd364 71 int64_t headerBlockSize() const {return mimeHeaderBlock_.length();}
7e1d6c48 72
7322c9dd 73 /// size in bytes of HTTP message block, includes first-line and mime headers
7e1d6c48 74 /// excludes any body/entity/payload bytes
7322c9dd 75 /// excludes any garbage prefix before the first-line
f4880526 76 int64_t messageHeaderSize() const {return firstLineSize() + headerBlockSize();}
7e1d6c48 77
7322c9dd 78 /// buffer containing HTTP mime headers, excluding message first-line.
eb1bd364 79 const char *rawHeaderBuf() {return mimeHeaderBlock_.c_str();}
7e1d6c48 80
7322c9dd 81 /// attempt to parse a message from the buffer
678451c0
AJ
82 /// \retval true if a full message was found and parsed
83 /// \retval false if incomplete, invalid or no message was found
7322c9dd
AJ
84 virtual bool parse() = 0;
85
86 /// the protocol label for this message
87 const AnyP::ProtocolVersion & messageProtocol() const {return msgProtocol_;}
afff15b2 88
a4181565
AJ
89 /**
90 * \return A pointer to a field-value of the first matching field-name, or NULL.
91 */
92 char *getHeaderField(const char *name);
93
4c14658e 94public:
4c14658e
AJ
95 const char *buf;
96 int bufsiz;
74f478f8 97
7322c9dd
AJ
98protected:
99 /// what stage the parser is currently up to
cbcd99df 100 ParseState parsingStage_;
7322c9dd
AJ
101
102 /// what protocol label has been found in the first line
103 AnyP::ProtocolVersion msgProtocol_;
104
105 /// byte offset for non-parsed region of the buffer
106 size_t parseOffset_;
107
108 /// buffer holding the mime headers
109 SBuf mimeHeaderBlock_;
110};
111
112/** HTTP protocol request parser.
113 *
114 * Works on a raw character I/O buffer and tokenizes the content into
115 * either an error state or, an HTTP procotol request major segments:
116 *
117 * \item Request Line (method, URL, protocol, version)
118 * \item Mime header block
119 */
120class RequestParser : public Http1::Parser
121{
122public:
123 /* Http::One::Parser API */
124 RequestParser() : Parser() {}
125 RequestParser(const char *aBuf, int len) : Parser(aBuf, len) {}
126 virtual void clear();
678451c0 127 virtual void noteBufferShift(const int64_t n);
7322c9dd
AJ
128 virtual int64_t firstLineSize() const {return req.end - req.start + 1;}
129 virtual bool parse();
5aedd08d 130
9ff1b8ca
AJ
131 /// the HTTP method if this is a request message
132 const HttpRequestMethod & method() const {return method_;}
274bd5ad 133
9ff1b8ca
AJ
134 /// the request-line URI if this is a request message, or an empty string.
135 const SBuf &requestUri() const {return uri_;}
5f3cc9a2 136
4c14658e 137 /** HTTP status code to be used on the invalid-request error page
955394ce 138 * Http::scNone indicates incomplete parse, Http::scOkay indicates no error.
4c14658e 139 */
955394ce 140 Http::StatusCode request_parse_status;
b6a7fc85
AJ
141
142private:
cbcd99df 143 void skipGarbageLines();
c11191e0
AJ
144 int parseRequestFirstLine();
145
5ff9a17a 146 /// Offsets for pieces of the (HTTP request) Request-Line as per RFC 2616
cbcd99df 147 /// only valid before and during parse stage HTTP_PARSE_FIRST
5ff9a17a
AJ
148 struct request_offsets {
149 int start, end;
150 int m_start, m_end; // method
151 int u_start, u_end; // url
152 int v_start, v_end; // version (full text)
153 } req;
154
274bd5ad 155 /// what request method has been found on the first line
9ff1b8ca 156 HttpRequestMethod method_;
f4880526 157
5f3cc9a2
AJ
158 /// raw copy of the origina client reqeust-line URI field
159 SBuf uri_;
4c14658e
AJ
160};
161
1b51ee7b 162} // namespace One
bb86dcd4
AJ
163} // namespace Http
164
e02d9044 165#endif /* _SQUID_SRC_HTTP_HTTP1PARSER_H */