-
Notifications
You must be signed in to change notification settings - Fork 158
/
httpparser.hxx
119 lines (98 loc) · 3.56 KB
/
httpparser.hxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/** @file httpparser.hxx
*
* @copyright (C) 2016
* @date 2016.05.26
* @version 1.0.0
* @author amir zamani <[email protected]>
*
*/
#ifndef __QHTTP_HTTPPARSER_HXX__
#define __QHTTP_HTTPPARSER_HXX__
#include "qhttpbase.hpp"
///////////////////////////////////////////////////////////////////////////////
namespace qhttp {
namespace details {
///////////////////////////////////////////////////////////////////////////////
/// base HttpParser based on joyent http_parser
template<class TImpl>
class HttpParser
{
public:
explicit HttpParser(http_parser_type type) {
// create http_parser object
iparser.data = static_cast<TImpl*>(this);
http_parser_init(&iparser, type);
memset(&iparserSettings, 0, sizeof(http_parser_settings));
iparserSettings.on_message_begin = onMessageBegin;
iparserSettings.on_url = onUrl;
iparserSettings.on_status = onStatus;
iparserSettings.on_header_field = onHeaderField;
iparserSettings.on_header_value = onHeaderValue;
iparserSettings.on_headers_complete = onHeadersComplete;
iparserSettings.on_body = onBody;
iparserSettings.on_message_complete = onMessageComplete;
}
size_t parse(const char* data, size_t length) {
return http_parser_execute(&iparser,
&iparserSettings,
data,
length);
}
public: // callback functions for http_parser_settings
static int onMessageBegin(http_parser* p) {
return me(p)->messageBegin(p);
}
static int onUrl(http_parser* p, const char* at, size_t length) {
return me(p)->url(p, at, length);
}
static int onStatus(http_parser* p, const char* at, size_t length) {
return me(p)->status(p, at, length);
}
static int onHeaderField(http_parser* p, const char* at, size_t length) {
return me(p)->headerField(p, at, length);
}
static int onHeaderValue(http_parser* p, const char* at, size_t length) {
return me(p)->headerValue(p, at, length);
}
static int onHeadersComplete(http_parser* p) {
return me(p)->headersComplete(p);
}
static int onBody(http_parser* p, const char* at, size_t length) {
return me(p)->body(p, at, length);
}
static int onMessageComplete(http_parser* p) {
return me(p)->messageComplete(p);
}
protected:
// The ones we are reading in from the parser
QByteArray itempHeaderField;
QByteArray itempHeaderValue;
// if connection has a timeout, these fields will be used
quint32 itimeOut = 0;
QBasicTimer itimer;
// uniform socket object
QSocket isocket;
// if connection should persist
bool ikeepAlive = false;
// joyent http_parser
http_parser iparser;
http_parser_settings iparserSettings;
static auto me(http_parser* p) {
return static_cast<TImpl*>(p->data);
}
}; //
/// basic request parser (server)
template<class TImpl>
struct HttpRequestParser : public HttpParser<TImpl> {
HttpRequestParser() : HttpParser<TImpl>(HTTP_REQUEST) {}
};
/// basic response parser (clinet)
template<class TImpl>
struct HttpResponseParser : public HttpParser<TImpl> {
HttpResponseParser() : HttpParser<TImpl>(HTTP_RESPONSE) {}
};
///////////////////////////////////////////////////////////////////////////////
} // namespace details
} // namespace qhttp
///////////////////////////////////////////////////////////////////////////////
#endif // __QHTTP_HTTPPARSER_HXX__