OSDN Git Service

Initial commit
[wordring-tm/wordring-tm.git] / http / httprequest.h
1 #ifndef HTTPREQUEST_H
2 #define HTTPREQUEST_H
3
4 #include <QByteArray>
5 #include <QList>
6 #include <QPair>
7 #include <QUrl>
8
9 #include <functional>
10
11 class HttpRequestParser;
12
13 class HttpRequest
14 {
15         friend class HttpRequestParser;
16
17 public:
18         enum : int
19         {
20                 ParseError = -500,
21                 BadRequestError = -400,
22
23                 Error = -1,
24
25                 Initial = 0, // 初期状態
26                 Partial,
27                 Ready, /*!< 解析完了 */
28         };
29
30 public:
31         typedef QPair<QByteArray, QByteArray> pair_type;
32         typedef QList<pair_type> list_type;
33         typedef list_type::const_iterator const_iterator;
34
35 public:
36         HttpRequest();
37
38         void clear();
39
40         QByteArray method() const;
41         QByteArray url() const;
42         QByteArray version() const;
43
44         bool has_attribute(QByteArray const& name) const;
45         QByteArray attribute(QByteArray const& name) const;
46
47         const_iterator begin();
48         const_iterator end();
49
50         QByteArray const& content() const;
51
52         void state(int state);
53         int state() const;
54
55         int content_length() const;
56         QByteArray transfer_encoding() const;
57
58         QByteArray dump() const;
59
60 private:
61         int m_state;
62
63         QByteArray m_method;
64         QByteArray m_url;
65         QByteArray m_version;
66         list_type m_attributes;
67
68         QByteArray m_content;
69 };
70
71 class HttpRequestParser
72 {
73         enum : int
74         {
75                 Error = -1,
76                 Initial = 0, // 初期状態
77                 HeaderPartial,
78                 HeaderReady, // ヘッダの解析が完了した状態
79                 ContentPartial,
80                 ContentReady,
81         };
82
83 public:
84         HttpRequestParser();
85
86         void attach(HttpRequest *request);
87         void detach(HttpRequest *request);
88
89         int push(int offset, QByteArray const &bytes);
90
91 private:
92         int parse(int offset, QByteArray const &bytes);
93         int parse(char ch);
94
95         int content(int offset, QByteArray const &bytes);
96
97         bool isOneOf(char ch, char const *string)
98         {
99                 for(int i = 0; char c = string[i]; i++) if(c == ch) return true;
100                 return false;
101         }
102         bool isToken(char ch)      { return !isCTL(ch) && !isSeparators(ch); }
103         bool isSeparators(char ch) { return isOneOf(ch, "()<>@,;:\\\"/[]?={} \t"); }
104         bool isURI(char ch)
105         {
106                 // Yahooが使うので、「^」追加
107                 return ('0' <= ch && ch <= '9') || ('A' <= ch && ch <= 'Z')
108                                 || ('a' <= ch && ch <= 'z') || isOneOf(ch, "^!#$&'()*+,/:;=?@[]-._~%");
109         }
110         bool isCHAR(char ch)       { return 0 <= ch && ch <= 127; }
111         bool isCTL(char ch)        { return (0 <= ch && ch <= 31) || ch == 127; }
112         bool isUPALPHA(char ch)    { return 'A' <= ch && ch <= 'Z'; }
113         bool isLOALPHA(char ch)    { return 'A' <= ch && ch <= 'Z'; }
114         bool isALPHA(char ch)      { return isUPALPHA(ch) || isLOALPHA(ch); }
115         bool isDIGIT(char ch)      { return '0' <= ch && ch <= '9'; }
116
117 private:
118         HttpRequest *m_request; /*!< 出力先 */
119
120         int m_count; /*!< 読み込んだバイト数 */
121         int m_state; /*!< パーサの進行状態 */
122
123         int m_state0; /*!< 状態変数 0 */
124         std::function<int(int, QByteArray const&)> m_cparser; /*!< コンテンツ用パーサ */
125
126         class ContentReader
127         {
128         public:
129                 ContentReader(int length, HttpRequestParser *parser);
130                 int operator()(int offset, QByteArray const &bytes);
131         private:
132                 int m_length;
133                 HttpRequestParser *m_parser;
134         };
135
136         class ChunkReader
137         {
138         public:
139                 ChunkReader(HttpRequestParser *parser);
140                 int operator()(int offset, QByteArray const &bytes);
141
142         };
143 };
144
145
146
147 #endif // HTTPREQUEST_H