]> git.ipfire.org Git - thirdparty/squid.git/blame - src/http/one/Parser.h
SourceFormat Enforcement
[thirdparty/squid.git] / src / http / one / Parser.h
CommitLineData
48a37aee 1/*
4ac4a490 2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
48a37aee
AJ
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
83aacd9a
AJ
9#ifndef _SQUID_SRC_HTTP_ONE_PARSER_H
10#define _SQUID_SRC_HTTP_ONE_PARSER_H
4c14658e 11
c99510dd
AJ
12#include "anyp/ProtocolVersion.h"
13#include "http/one/forward.h"
f1d5359e 14#include "http/StatusCode.h"
65e41a45 15#include "sbuf/SBuf.h"
4c14658e 16
bb86dcd4 17namespace Http {
1b51ee7b 18namespace One {
bb86dcd4 19
4c14658e 20// Parser states
678451c0 21enum ParseState {
350ec67a
AJ
22 HTTP_PARSE_NONE, ///< initialized, but nothing usefully parsed yet
23 HTTP_PARSE_FIRST, ///< HTTP/1 message first-line
24 HTTP_PARSE_CHUNK_SZ, ///< HTTP/1.1 chunked encoding chunk-size
25 HTTP_PARSE_CHUNK_EXT, ///< HTTP/1.1 chunked encoding chunk-ext
26 HTTP_PARSE_CHUNK, ///< HTTP/1.1 chunked encoding chunk-data
27 HTTP_PARSE_MIME, ///< HTTP/1 mime-header block
28 HTTP_PARSE_DONE ///< parsed a message header, or reached a terminal syntax error
678451c0 29};
4c14658e 30
36a9c964 31/** HTTP/1.x protocol parser
4c14658e 32 *
00589b8e 33 * Works on a raw character I/O buffer and tokenizes the content into
36a9c964 34 * the major CRLF delimited segments of an HTTP/1 procotol message:
4c14658e 35 *
7322c9dd 36 * \item first-line (request-line / simple-request / status-line)
36a9c964 37 * \item mime-header 0*( header-name ':' SP field-value CRLF)
4c14658e 38 */
7322c9dd 39class Parser : public RefCountable
4c14658e
AJ
40{
41public:
8e677087
AJ
42 typedef SBuf::size_type size_type;
43
e47e0802 44 Parser() : parseStatusCode(Http::scNone), parsingStage_(HTTP_PARSE_NONE), hackExpectsMime_(false) {}
f9688132 45 virtual ~Parser() {}
4c14658e
AJ
46
47 /// Set this parser back to a default state.
48 /// Will DROP any reference to a buffer (does not free).
f9688132 49 virtual void clear() = 0;
4c14658e 50
36a9c964
AJ
51 /// attempt to parse a message from the buffer
52 /// \retval true if a full message was found and parsed
53 /// \retval false if incomplete, invalid or no message was found
54 virtual bool parse(const SBuf &aBuf) = 0;
f9daf571 55
36a9c964
AJ
56 /** Whether the parser is waiting on more data to complete parsing a message.
57 * Use to distinguish between incomplete data and error results
58 * when parse() returns false.
87abd755 59 */
36a9c964 60 bool needsMoreData() const {return parsingStage_!=HTTP_PARSE_DONE;}
f9daf571
AJ
61
62 /// size in bytes of the first line including CRLF terminator
8e677087 63 virtual size_type firstLineSize() const = 0;
7e1d6c48 64
f4880526 65 /// size in bytes of the message headers including CRLF terminator(s)
7322c9dd 66 /// but excluding first-line bytes
8e677087 67 size_type headerBlockSize() const {return mimeHeaderBlock_.length();}
7e1d6c48 68
7322c9dd 69 /// size in bytes of HTTP message block, includes first-line and mime headers
7e1d6c48 70 /// excludes any body/entity/payload bytes
7322c9dd 71 /// excludes any garbage prefix before the first-line
8e677087 72 size_type messageHeaderSize() const {return firstLineSize() + headerBlockSize();}
7e1d6c48 73
7322c9dd 74 /// buffer containing HTTP mime headers, excluding message first-line.
36a9c964 75 SBuf mimeHeader() const {return mimeHeaderBlock_;}
7322c9dd
AJ
76
77 /// the protocol label for this message
78 const AnyP::ProtocolVersion & messageProtocol() const {return msgProtocol_;}
afff15b2 79
a4181565 80 /**
f1d5359e 81 * Scan the mime header block (badly) for a header with the given name.
687696c1
AJ
82 *
83 * BUG: omits lines when searching for headers with obs-fold or multiple entries.
84 *
85 * BUG: limits output to just 1KB when Squid accepts up to 64KB line length.
86 *
a4181565
AJ
87 * \return A pointer to a field-value of the first matching field-name, or NULL.
88 */
89 char *getHeaderField(const char *name);
90
b749de75
AJ
91 /// the remaining unprocessed section of buffer
92 const SBuf &remaining() const {return buf_;}
93
9a4b5048
AJ
94#if USE_HTTP_VIOLATIONS
95 /// the right debugs() level for parsing HTTP violation messages
96 int violationLevel() const;
97#endif
98
f1d5359e
AJ
99 /**
100 * HTTP status code resulting from the parse process.
101 * to be used on the invalid message handling.
102 *
103 * Http::scNone indicates incomplete parse,
104 * Http::scOkay indicates no error,
105 * other codes represent a parse error.
106 */
107 Http::StatusCode parseStatusCode;
108
a1b9ec20
AR
109 /// the characters which are to be considered valid whitespace
110 /// (WSP / BSP / OWS)
111 static const CharacterSet &DelimiterCharacters();
112
b749de75 113protected:
188ad27f
AJ
114 /**
115 * detect and skip the CRLF or (if tolerant) LF line terminator
116 * consume from the tokenizer.
117 *
118 * throws if non-terminator is detected.
119 * \retval true only if line terminator found.
120 * \retval false incomplete or missing line terminator, need more data.
121 */
f29718b0 122 bool skipLineTerminator(Http1::Tokenizer &tok) const;
b8f86fd2
AJ
123
124 /**
f8cab755 125 * Scan to find the mime headers block for current message.
b8f86fd2 126 *
f8cab755
AJ
127 * \retval true If mime block (or a blocks non-existence) has been
128 * identified accurately within limit characters.
129 * mimeHeaderBlock_ has been updated and buf_ consumed.
130 *
131 * \retval false An error occured, or no mime terminator found within limit.
b8f86fd2 132 */
f8cab755 133 bool grabMimeBlock(const char *which, const size_t limit);
f1d5359e 134
9651320a
AJ
135 /// RFC 7230 section 2.6 - 7 magic octets
136 static const SBuf Http1magic;
137
b749de75
AJ
138 /// bytes remaining to be parsed
139 SBuf buf_;
74f478f8 140
7322c9dd 141 /// what stage the parser is currently up to
cbcd99df 142 ParseState parsingStage_;
7322c9dd 143
7a4fa6a0
AJ
144 /// what protocol label has been found in the first line (if any)
145 AnyP::ProtocolVersion msgProtocol_;
7322c9dd 146
7a4fa6a0 147 /// buffer holding the mime headers (if any)
7322c9dd 148 SBuf mimeHeaderBlock_;
e47e0802
AJ
149
150 /// Whether the invalid HTTP as HTTP/0.9 hack expects a mime header block
151 bool hackExpectsMime_;
00237269
AJ
152
153private:
154 void cleanMimePrefix();
155 void unfoldMime();
7322c9dd
AJ
156};
157
1b51ee7b 158} // namespace One
bb86dcd4
AJ
159} // namespace Http
160
83aacd9a 161#endif /* _SQUID_SRC_HTTP_ONE_PARSER_H */
f53969cc 162