正在显示
7 个修改的文件
包含
343 行增加
和
314 行删除
trunk/conf/console.conf
100755 → 100644
@@ -27,41 +27,263 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -27,41 +27,263 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
27 | 27 | ||
28 | #include <stdlib.h> | 28 | #include <stdlib.h> |
29 | 29 | ||
30 | +using namespace std; | ||
31 | + | ||
30 | #include <srs_kernel_error.hpp> | 32 | #include <srs_kernel_error.hpp> |
31 | #include <srs_kernel_log.hpp> | 33 | #include <srs_kernel_log.hpp> |
32 | #include <srs_app_socket.hpp> | 34 | #include <srs_app_socket.hpp> |
33 | 35 | ||
34 | #define SRS_DEFAULT_HTTP_PORT 80 | 36 | #define SRS_DEFAULT_HTTP_PORT 80 |
35 | 37 | ||
38 | +#define SRS_HTTP_HEADER_BUFFER 1024 | ||
39 | + | ||
36 | SrsHttpMessage::SrsHttpMessage() | 40 | SrsHttpMessage::SrsHttpMessage() |
37 | { | 41 | { |
38 | - body = new SrsBuffer(); | ||
39 | - state = SrsHttpParseStateInit; | 42 | + _body = new SrsBuffer(); |
43 | + _state = SrsHttpParseStateInit; | ||
40 | } | 44 | } |
41 | 45 | ||
42 | SrsHttpMessage::~SrsHttpMessage() | 46 | SrsHttpMessage::~SrsHttpMessage() |
43 | { | 47 | { |
44 | - srs_freep(body); | 48 | + srs_freep(_body); |
45 | } | 49 | } |
46 | 50 | ||
47 | void SrsHttpMessage::reset() | 51 | void SrsHttpMessage::reset() |
48 | { | 52 | { |
49 | - state = SrsHttpParseStateInit; | ||
50 | - body->clear(); | ||
51 | - url = ""; | 53 | + _state = SrsHttpParseStateInit; |
54 | + _body->clear(); | ||
55 | + _url = ""; | ||
52 | } | 56 | } |
53 | 57 | ||
54 | bool SrsHttpMessage::is_complete() | 58 | bool SrsHttpMessage::is_complete() |
55 | { | 59 | { |
56 | - return state == SrsHttpParseStateComplete; | 60 | + return _state == SrsHttpParseStateComplete; |
61 | +} | ||
62 | + | ||
63 | +u_int8_t SrsHttpMessage::method() | ||
64 | +{ | ||
65 | + return (u_int8_t)_header.method; | ||
66 | +} | ||
67 | + | ||
68 | +string SrsHttpMessage::url() | ||
69 | +{ | ||
70 | + return _url; | ||
71 | +} | ||
72 | + | ||
73 | +string SrsHttpMessage::body() | ||
74 | +{ | ||
75 | + std::string b; | ||
76 | + | ||
77 | + if (_body && !_body->empty()) { | ||
78 | + b.append(_body->bytes(), _body->size()); | ||
79 | + } | ||
80 | + | ||
81 | + return b; | ||
82 | +} | ||
83 | + | ||
84 | +int64_t SrsHttpMessage::body_size() | ||
85 | +{ | ||
86 | + return (int64_t)_body->size(); | ||
87 | +} | ||
88 | + | ||
89 | +int64_t SrsHttpMessage::content_length() | ||
90 | +{ | ||
91 | + return _header.content_length; | ||
92 | +} | ||
93 | + | ||
94 | +void SrsHttpMessage::set_url(std::string url) | ||
95 | +{ | ||
96 | + _url = url; | ||
97 | +} | ||
98 | + | ||
99 | +void SrsHttpMessage::set_state(SrsHttpParseState state) | ||
100 | +{ | ||
101 | + _state = state; | ||
102 | +} | ||
103 | + | ||
104 | +void SrsHttpMessage::set_header(http_parser* header) | ||
105 | +{ | ||
106 | + memcpy(&_header, header, sizeof(http_parser)); | ||
107 | +} | ||
108 | + | ||
109 | +void SrsHttpMessage::append_body(const char* body, int length) | ||
110 | +{ | ||
111 | + _body->append(body, length); | ||
57 | } | 112 | } |
58 | 113 | ||
59 | SrsHttpParser::SrsHttpParser() | 114 | SrsHttpParser::SrsHttpParser() |
60 | { | 115 | { |
116 | + msg = NULL; | ||
61 | } | 117 | } |
62 | 118 | ||
63 | SrsHttpParser::~SrsHttpParser() | 119 | SrsHttpParser::~SrsHttpParser() |
64 | { | 120 | { |
121 | + srs_freep(msg); | ||
122 | +} | ||
123 | + | ||
124 | +int SrsHttpParser::initialize(enum http_parser_type type) | ||
125 | +{ | ||
126 | + int ret = ERROR_SUCCESS; | ||
127 | + | ||
128 | + memset(&settings, 0, sizeof(settings)); | ||
129 | + settings.on_message_begin = on_message_begin; | ||
130 | + settings.on_url = on_url; | ||
131 | + settings.on_header_field = on_header_field; | ||
132 | + settings.on_header_value = on_header_value; | ||
133 | + settings.on_headers_complete = on_headers_complete; | ||
134 | + settings.on_body = on_body; | ||
135 | + settings.on_message_complete = on_message_complete; | ||
136 | + | ||
137 | + http_parser_init(&parser, type); | ||
138 | + // callback object ptr. | ||
139 | + parser.data = (void*)this; | ||
140 | + | ||
141 | + return ret; | ||
142 | +} | ||
143 | + | ||
144 | +int SrsHttpParser::parse_message(SrsSocket* skt, SrsHttpMessage** ppmsg) | ||
145 | +{ | ||
146 | + *ppmsg = NULL; | ||
147 | + | ||
148 | + int ret = ERROR_SUCCESS; | ||
149 | + | ||
150 | + // the msg must be always NULL | ||
151 | + srs_assert(msg == NULL); | ||
152 | + msg = new SrsHttpMessage(); | ||
153 | + | ||
154 | + // reset response header. | ||
155 | + msg->reset(); | ||
156 | + | ||
157 | + // do parse | ||
158 | + if ((ret = parse_message_imp(skt)) != ERROR_SUCCESS) { | ||
159 | + if (!srs_is_client_gracefully_close(ret)) { | ||
160 | + srs_error("parse http msg failed. ret=%d", ret); | ||
161 | + } | ||
162 | + srs_freep(msg); | ||
163 | + return ret; | ||
164 | + } | ||
165 | + | ||
166 | + // parse ok, return the msg. | ||
167 | + *ppmsg = msg; | ||
168 | + msg = NULL; | ||
169 | + | ||
170 | + return ret; | ||
171 | +} | ||
172 | + | ||
173 | +int SrsHttpParser::parse_message_imp(SrsSocket* skt) | ||
174 | +{ | ||
175 | + int ret = ERROR_SUCCESS; | ||
176 | + | ||
177 | + // the msg should never be NULL | ||
178 | + srs_assert(msg != NULL); | ||
179 | + | ||
180 | + // parser header. | ||
181 | + char buf[SRS_HTTP_HEADER_BUFFER]; | ||
182 | + for (;;) { | ||
183 | + ssize_t nread; | ||
184 | + if ((ret = skt->read(buf, (size_t)sizeof(buf), &nread)) != ERROR_SUCCESS) { | ||
185 | + if (!srs_is_client_gracefully_close(ret)) { | ||
186 | + srs_error("read body from server failed. ret=%d", ret); | ||
187 | + } | ||
188 | + return ret; | ||
189 | + } | ||
190 | + | ||
191 | + ssize_t nparsed = http_parser_execute(&parser, &settings, buf, nread); | ||
192 | + srs_info("read_size=%d, nparsed=%d", (int)nread, (int)nparsed); | ||
193 | + | ||
194 | + // check header size. | ||
195 | + if (msg->is_complete()) { | ||
196 | + srs_trace("http request parsed, method=%d, url=%s, content-length=%"PRId64"", | ||
197 | + msg->method(), msg->url().c_str(), msg->content_length()); | ||
198 | + | ||
199 | + return ret; | ||
200 | + } | ||
201 | + | ||
202 | + if (nparsed != nread) { | ||
203 | + ret = ERROR_HTTP_PARSE_HEADER; | ||
204 | + srs_error("parse response error, parsed(%d)!=read(%d), ret=%d", (int)nparsed, (int)nread, ret); | ||
205 | + return ret; | ||
206 | + } | ||
207 | + } | ||
208 | + | ||
209 | + return ret; | ||
210 | +} | ||
211 | + | ||
212 | +int SrsHttpParser::on_message_begin(http_parser* parser) | ||
213 | +{ | ||
214 | + SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
215 | + obj->msg->set_state(SrsHttpParseStateStart); | ||
216 | + | ||
217 | + srs_info("***MESSAGE BEGIN***"); | ||
218 | + | ||
219 | + return 0; | ||
220 | +} | ||
221 | + | ||
222 | +int SrsHttpParser::on_headers_complete(http_parser* parser) | ||
223 | +{ | ||
224 | + SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
225 | + obj->msg->set_header(parser); | ||
226 | + | ||
227 | + srs_info("***HEADERS COMPLETE***"); | ||
228 | + | ||
229 | + // see http_parser.c:1570, return 1 to skip body. | ||
230 | + return 0; | ||
231 | +} | ||
232 | + | ||
233 | +int SrsHttpParser::on_message_complete(http_parser* parser) | ||
234 | +{ | ||
235 | + SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
236 | + // save the parser when header parse completed. | ||
237 | + obj->msg->set_state(SrsHttpParseStateComplete); | ||
238 | + | ||
239 | + srs_info("***MESSAGE COMPLETE***\n"); | ||
240 | + | ||
241 | + return 0; | ||
242 | +} | ||
243 | + | ||
244 | +int SrsHttpParser::on_url(http_parser* parser, const char* at, size_t length) | ||
245 | +{ | ||
246 | + SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
247 | + | ||
248 | + if (length > 0) { | ||
249 | + std::string url; | ||
250 | + | ||
251 | + url.append(at, (int)length); | ||
252 | + | ||
253 | + obj->msg->set_url(url); | ||
254 | + } | ||
255 | + | ||
256 | + srs_info("Method: %d, Url: %.*s", parser->method, (int)length, at); | ||
257 | + | ||
258 | + return 0; | ||
259 | +} | ||
260 | + | ||
261 | +int SrsHttpParser::on_header_field(http_parser* /*parser*/, const char* at, size_t length) | ||
262 | +{ | ||
263 | + srs_info("Header field: %.*s", (int)length, at); | ||
264 | + return 0; | ||
265 | +} | ||
266 | + | ||
267 | +int SrsHttpParser::on_header_value(http_parser* /*parser*/, const char* at, size_t length) | ||
268 | +{ | ||
269 | + srs_info("Header value: %.*s", (int)length, at); | ||
270 | + return 0; | ||
271 | +} | ||
272 | + | ||
273 | +int SrsHttpParser::on_body(http_parser* parser, const char* at, size_t length) | ||
274 | +{ | ||
275 | + SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
276 | + | ||
277 | + if (length > 0) { | ||
278 | + srs_assert(obj); | ||
279 | + srs_assert(obj->msg); | ||
280 | + | ||
281 | + obj->msg->append_body(at, (int)length); | ||
282 | + } | ||
283 | + | ||
284 | + srs_info("Body: %.*s", (int)length, at); | ||
285 | + | ||
286 | + return 0; | ||
65 | } | 287 | } |
66 | 288 | ||
67 | SrsHttpUri::SrsHttpUri() | 289 | SrsHttpUri::SrsHttpUri() |
@@ -68,17 +68,43 @@ enum SrsHttpParseState { | @@ -68,17 +68,43 @@ enum SrsHttpParseState { | ||
68 | */ | 68 | */ |
69 | class SrsHttpMessage | 69 | class SrsHttpMessage |
70 | { | 70 | { |
71 | -public: | ||
72 | - std::string url; | ||
73 | - http_parser header; | ||
74 | - SrsBuffer* body; | ||
75 | - SrsHttpParseState state; | 71 | +private: |
72 | + /** | ||
73 | + * parsed url. | ||
74 | + */ | ||
75 | + std::string _url; | ||
76 | + /** | ||
77 | + * parsed http header. | ||
78 | + */ | ||
79 | + http_parser _header; | ||
80 | + /** | ||
81 | + * body object, in bytes. | ||
82 | + * @remark, user can get body in string by get_body(). | ||
83 | + */ | ||
84 | + SrsBuffer* _body; | ||
85 | + /** | ||
86 | + * parser state | ||
87 | + * @remark, user can use is_complete() to determine the state. | ||
88 | + */ | ||
89 | + SrsHttpParseState _state; | ||
76 | 90 | ||
91 | +public: | ||
77 | SrsHttpMessage(); | 92 | SrsHttpMessage(); |
78 | virtual ~SrsHttpMessage(); | 93 | virtual ~SrsHttpMessage(); |
79 | 94 | ||
95 | +public: | ||
80 | virtual void reset(); | 96 | virtual void reset(); |
97 | +public: | ||
81 | virtual bool is_complete(); | 98 | virtual bool is_complete(); |
99 | + virtual u_int8_t method(); | ||
100 | + virtual std::string url(); | ||
101 | + virtual std::string body(); | ||
102 | + virtual int64_t body_size(); | ||
103 | + virtual int64_t content_length(); | ||
104 | + virtual void set_url(std::string url); | ||
105 | + virtual void set_state(SrsHttpParseState state); | ||
106 | + virtual void set_header(http_parser* header); | ||
107 | + virtual void append_body(const char* body, int length); | ||
82 | }; | 108 | }; |
83 | 109 | ||
84 | /** | 110 | /** |
@@ -87,11 +113,39 @@ public: | @@ -87,11 +113,39 @@ public: | ||
87 | */ | 113 | */ |
88 | class SrsHttpParser | 114 | class SrsHttpParser |
89 | { | 115 | { |
116 | +private: | ||
117 | + http_parser_settings settings; | ||
118 | + http_parser parser; | ||
119 | + SrsHttpMessage* msg; | ||
90 | public: | 120 | public: |
91 | SrsHttpParser(); | 121 | SrsHttpParser(); |
92 | virtual ~SrsHttpParser(); | 122 | virtual ~SrsHttpParser(); |
93 | public: | 123 | public: |
94 | - //virtual int parse_requst(SrsHttpMessage** ppreq); | 124 | + /** |
125 | + * initialize the http parser with specified type, | ||
126 | + * one parser can only parse request or response messages. | ||
127 | + */ | ||
128 | + virtual int initialize(enum http_parser_type type); | ||
129 | + /** | ||
130 | + * always parse a http message, | ||
131 | + * that is, the *ppmsg always NOT-NULL when return success. | ||
132 | + * or error and *ppmsg must be NULL. | ||
133 | + * @remark, if success, *ppmsg always NOT-NULL, *ppmsg always is_complete(). | ||
134 | + */ | ||
135 | + virtual int parse_message(SrsSocket* skt, SrsHttpMessage** ppmsg); | ||
136 | +private: | ||
137 | + /** | ||
138 | + * parse the HTTP message to member field: msg. | ||
139 | + */ | ||
140 | + virtual int parse_message_imp(SrsSocket* skt); | ||
141 | +private: | ||
142 | + static int on_message_begin(http_parser* parser); | ||
143 | + static int on_headers_complete(http_parser* parser); | ||
144 | + static int on_message_complete(http_parser* parser); | ||
145 | + static int on_url(http_parser* parser, const char* at, size_t length); | ||
146 | + static int on_header_field(http_parser* parser, const char* at, size_t length); | ||
147 | + static int on_header_value(http_parser* parser, const char* at, size_t length); | ||
148 | + static int on_body(http_parser* parser, const char* at, size_t length); | ||
95 | }; | 149 | }; |
96 | 150 | ||
97 | /** | 151 | /** |
@@ -33,18 +33,19 @@ using namespace std; | @@ -33,18 +33,19 @@ using namespace std; | ||
33 | #include <srs_app_socket.hpp> | 33 | #include <srs_app_socket.hpp> |
34 | #include <srs_app_http.hpp> | 34 | #include <srs_app_http.hpp> |
35 | #include <srs_kernel_buffer.hpp> | 35 | #include <srs_kernel_buffer.hpp> |
36 | +#include <srs_core_autofree.hpp> | ||
36 | 37 | ||
37 | #define SRS_HTTP_HEADER_BUFFER 1024 | 38 | #define SRS_HTTP_HEADER_BUFFER 1024 |
38 | 39 | ||
39 | SrsHttpConn::SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd) | 40 | SrsHttpConn::SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd) |
40 | : SrsConnection(srs_server, client_stfd) | 41 | : SrsConnection(srs_server, client_stfd) |
41 | { | 42 | { |
42 | - req = new SrsHttpMessage(); | 43 | + parser = new SrsHttpParser(); |
43 | } | 44 | } |
44 | 45 | ||
45 | SrsHttpConn::~SrsHttpConn() | 46 | SrsHttpConn::~SrsHttpConn() |
46 | { | 47 | { |
47 | - srs_freep(req); | 48 | + srs_freep(parser); |
48 | } | 49 | } |
49 | 50 | ||
50 | int SrsHttpConn::do_cycle() | 51 | int SrsHttpConn::do_cycle() |
@@ -56,83 +57,46 @@ int SrsHttpConn::do_cycle() | @@ -56,83 +57,46 @@ int SrsHttpConn::do_cycle() | ||
56 | return ret; | 57 | return ret; |
57 | } | 58 | } |
58 | srs_trace("http get peer ip success. ip=%s", ip); | 59 | srs_trace("http get peer ip success. ip=%s", ip); |
59 | - | ||
60 | - // setup http parser | ||
61 | - http_parser_settings settings; | ||
62 | - | ||
63 | - memset(&settings, 0, sizeof(settings)); | ||
64 | - settings.on_message_begin = on_message_begin; | ||
65 | - settings.on_url = on_url; | ||
66 | - settings.on_header_field = on_header_field; | ||
67 | - settings.on_header_value = on_header_value; | ||
68 | - settings.on_headers_complete = on_headers_complete; | ||
69 | - settings.on_body = on_body; | ||
70 | - settings.on_message_complete = on_message_complete; | ||
71 | 60 | ||
72 | - http_parser parser; | ||
73 | - http_parser_init(&parser, HTTP_REQUEST); | ||
74 | - // callback object ptr. | ||
75 | - parser.data = (void*)this; | 61 | + // initialize parser |
62 | + if ((ret = parser->initialize(HTTP_REQUEST)) != ERROR_SUCCESS) { | ||
63 | + srs_error("initialize http parser failed. ret=%d", ret); | ||
64 | + return ret; | ||
65 | + } | ||
76 | 66 | ||
77 | // underlayer socket | 67 | // underlayer socket |
78 | SrsSocket skt(stfd); | 68 | SrsSocket skt(stfd); |
79 | 69 | ||
70 | + // process http messages. | ||
80 | for (;;) { | 71 | for (;;) { |
81 | - if ((ret = parse_request(&skt, &parser, &settings)) != ERROR_SUCCESS) { | ||
82 | - if (!srs_is_client_gracefully_close(ret)) { | ||
83 | - srs_error("http client cycle failed. ret=%d", ret); | ||
84 | - } | ||
85 | - return ret; | ||
86 | - } | ||
87 | - } | 72 | + SrsHttpMessage* req = NULL; |
88 | 73 | ||
89 | - return ret; | ||
90 | -} | ||
91 | - | ||
92 | -int SrsHttpConn::parse_request(SrsSocket* skt, http_parser* parser, http_parser_settings* settings) | ||
93 | -{ | ||
94 | - int ret = ERROR_SUCCESS; | ||
95 | - | ||
96 | - // reset response header. | ||
97 | - req->reset(); | ||
98 | - | ||
99 | - // parser header. | ||
100 | - char buf[SRS_HTTP_HEADER_BUFFER]; | ||
101 | - for (;;) { | ||
102 | - ssize_t nread; | ||
103 | - if ((ret = skt->read(buf, (size_t)sizeof(buf), &nread)) != ERROR_SUCCESS) { | ||
104 | - if (!srs_is_client_gracefully_close(ret)) { | ||
105 | - srs_error("read body from server failed. ret=%d", ret); | ||
106 | - } | 74 | + // get a http message |
75 | + if ((ret = parser->parse_message(&skt, &req)) != ERROR_SUCCESS) { | ||
107 | return ret; | 76 | return ret; |
108 | } | 77 | } |
109 | - | ||
110 | - ssize_t nparsed = http_parser_execute(parser, settings, buf, nread); | ||
111 | - srs_info("read_size=%d, nparsed=%d", (int)nread, (int)nparsed); | ||
112 | 78 | ||
113 | - // check header size. | ||
114 | - if (req->is_complete()) { | ||
115 | - srs_trace("http request parsed, method=%d, url=%s, content-length=%"PRId64"", | ||
116 | - req->header.method, req->url.c_str(), req->header.content_length); | ||
117 | - | ||
118 | - return process_request(skt); | ||
119 | - } | 79 | + // if SUCCESS, always NOT-NULL and completed message. |
80 | + srs_assert(req); | ||
81 | + srs_assert(req->is_complete()); | ||
82 | + | ||
83 | + // always free it in this scope. | ||
84 | + SrsAutoFree(SrsHttpMessage, req, false); | ||
120 | 85 | ||
121 | - if (nparsed != nread) { | ||
122 | - ret = ERROR_HTTP_PARSE_HEADER; | ||
123 | - srs_error("parse response error, parsed(%d)!=read(%d), ret=%d", (int)nparsed, (int)nread, ret); | 86 | + // ok, handle http request. |
87 | + if ((ret = process_request(&skt, req)) != ERROR_SUCCESS) { | ||
124 | return ret; | 88 | return ret; |
125 | } | 89 | } |
126 | } | 90 | } |
127 | - | 91 | + |
128 | return ret; | 92 | return ret; |
129 | } | 93 | } |
130 | 94 | ||
131 | -int SrsHttpConn::process_request(SrsSocket* skt) | 95 | +int SrsHttpConn::process_request(SrsSocket* skt, SrsHttpMessage* req) |
132 | { | 96 | { |
133 | int ret = ERROR_SUCCESS; | 97 | int ret = ERROR_SUCCESS; |
134 | 98 | ||
135 | - if (req->header.method == HTTP_OPTIONS) { | 99 | + if (req->method() == HTTP_OPTIONS) { |
136 | char data[] = "HTTP/1.1 200 OK" __CRLF | 100 | char data[] = "HTTP/1.1 200 OK" __CRLF |
137 | "Content-Length: 0"__CRLF | 101 | "Content-Length: 0"__CRLF |
138 | "Server: SRS/"RTMP_SIG_SRS_VERSION""__CRLF | 102 | "Server: SRS/"RTMP_SIG_SRS_VERSION""__CRLF |
@@ -149,14 +113,14 @@ int SrsHttpConn::process_request(SrsSocket* skt) | @@ -149,14 +113,14 @@ int SrsHttpConn::process_request(SrsSocket* skt) | ||
149 | 113 | ||
150 | std::stringstream ss; | 114 | std::stringstream ss; |
151 | ss << "HTTP/1.1 200 OK " << __CRLF | 115 | ss << "HTTP/1.1 200 OK " << __CRLF |
152 | - << "Content-Length: "<< tilte.length() + req->body->size() << __CRLF | 116 | + << "Content-Length: "<< tilte.length() + req->body_size() << __CRLF |
153 | << "Server: SRS/"RTMP_SIG_SRS_VERSION"" << __CRLF | 117 | << "Server: SRS/"RTMP_SIG_SRS_VERSION"" << __CRLF |
154 | << "Allow: DELETE, GET, HEAD, OPTIONS, POST, PUT" << __CRLF | 118 | << "Allow: DELETE, GET, HEAD, OPTIONS, POST, PUT" << __CRLF |
155 | << "Access-Control-Allow-Origin: *" << __CRLF | 119 | << "Access-Control-Allow-Origin: *" << __CRLF |
156 | << "Access-Control-Allow-Methods: GET, POST, HEAD, PUT, DELETE" << __CRLF | 120 | << "Access-Control-Allow-Methods: GET, POST, HEAD, PUT, DELETE" << __CRLF |
157 | << "Access-Control-Allow-Headers: Cache-Control,X-Proxy-Authorization,X-Requested-With,Content-Type" << __CRLF | 121 | << "Access-Control-Allow-Headers: Cache-Control,X-Proxy-Authorization,X-Requested-With,Content-Type" << __CRLF |
158 | << "Content-Type: text/html;charset=utf-8" << __CRLFCRLF | 122 | << "Content-Type: text/html;charset=utf-8" << __CRLFCRLF |
159 | - << tilte << (req->body->empty()? "":req->body->bytes()) | 123 | + << tilte << req->body().c_str() |
160 | << ""; | 124 | << ""; |
161 | return skt->write(ss.str().c_str(), ss.str().length(), NULL); | 125 | return skt->write(ss.str().c_str(), ss.str().length(), NULL); |
162 | } | 126 | } |
@@ -164,74 +128,4 @@ int SrsHttpConn::process_request(SrsSocket* skt) | @@ -164,74 +128,4 @@ int SrsHttpConn::process_request(SrsSocket* skt) | ||
164 | return ret; | 128 | return ret; |
165 | } | 129 | } |
166 | 130 | ||
167 | -int SrsHttpConn::on_message_begin(http_parser* parser) | ||
168 | -{ | ||
169 | - SrsHttpConn* obj = (SrsHttpConn*)parser->data; | ||
170 | - obj->req->state = SrsHttpParseStateStart; | ||
171 | - | ||
172 | - srs_info("***MESSAGE BEGIN***"); | ||
173 | - | ||
174 | - return 0; | ||
175 | -} | ||
176 | - | ||
177 | -int SrsHttpConn::on_headers_complete(http_parser* parser) | ||
178 | -{ | ||
179 | - SrsHttpConn* obj = (SrsHttpConn*)parser->data; | ||
180 | - memcpy(&obj->req->header, parser, sizeof(http_parser)); | ||
181 | - | ||
182 | - srs_info("***HEADERS COMPLETE***"); | ||
183 | - | ||
184 | - // see http_parser.c:1570, return 1 to skip body. | ||
185 | - return 0; | ||
186 | -} | ||
187 | - | ||
188 | -int SrsHttpConn::on_message_complete(http_parser* parser) | ||
189 | -{ | ||
190 | - SrsHttpConn* obj = (SrsHttpConn*)parser->data; | ||
191 | - // save the parser when header parse completed. | ||
192 | - obj->req->state = SrsHttpParseStateComplete; | ||
193 | - | ||
194 | - srs_info("***MESSAGE COMPLETE***\n"); | ||
195 | - | ||
196 | - return 0; | ||
197 | -} | ||
198 | - | ||
199 | -int SrsHttpConn::on_url(http_parser* parser, const char* at, size_t length) | ||
200 | -{ | ||
201 | - SrsHttpConn* obj = (SrsHttpConn*)parser->data; | ||
202 | - | ||
203 | - if (length > 0) { | ||
204 | - obj->req->url.append(at, (int)length); | ||
205 | - } | ||
206 | - | ||
207 | - srs_info("Method: %d, Url: %.*s", parser->method, (int)length, at); | ||
208 | - | ||
209 | - return 0; | ||
210 | -} | ||
211 | - | ||
212 | -int SrsHttpConn::on_header_field(http_parser* /*parser*/, const char* at, size_t length) | ||
213 | -{ | ||
214 | - srs_info("Header field: %.*s", (int)length, at); | ||
215 | - return 0; | ||
216 | -} | ||
217 | - | ||
218 | -int SrsHttpConn::on_header_value(http_parser* /*parser*/, const char* at, size_t length) | ||
219 | -{ | ||
220 | - srs_info("Header value: %.*s", (int)length, at); | ||
221 | - return 0; | ||
222 | -} | ||
223 | - | ||
224 | -int SrsHttpConn::on_body(http_parser* parser, const char* at, size_t length) | ||
225 | -{ | ||
226 | - SrsHttpConn* obj = (SrsHttpConn*)parser->data; | ||
227 | - | ||
228 | - if (length > 0) { | ||
229 | - obj->req->body->append(at, (int)length); | ||
230 | - } | ||
231 | - | ||
232 | - srs_info("Body: %.*s", (int)length, at); | ||
233 | - | ||
234 | - return 0; | ||
235 | -} | ||
236 | - | ||
237 | #endif | 131 | #endif |
@@ -38,28 +38,20 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -38,28 +38,20 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
38 | #include <http_parser.h> | 38 | #include <http_parser.h> |
39 | 39 | ||
40 | class SrsSocket; | 40 | class SrsSocket; |
41 | +class SrsHttpParser; | ||
41 | class SrsHttpMessage; | 42 | class SrsHttpMessage; |
42 | 43 | ||
43 | class SrsHttpConn : public SrsConnection | 44 | class SrsHttpConn : public SrsConnection |
44 | { | 45 | { |
45 | private: | 46 | private: |
46 | - SrsHttpMessage* req; | 47 | + SrsHttpParser* parser; |
47 | public: | 48 | public: |
48 | SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd); | 49 | SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd); |
49 | virtual ~SrsHttpConn(); | 50 | virtual ~SrsHttpConn(); |
50 | protected: | 51 | protected: |
51 | virtual int do_cycle(); | 52 | virtual int do_cycle(); |
52 | private: | 53 | private: |
53 | - virtual int parse_request(SrsSocket* skt, http_parser* parser, http_parser_settings* settings); | ||
54 | - virtual int process_request(SrsSocket* skt); | ||
55 | -private: | ||
56 | - static int on_message_begin(http_parser* parser); | ||
57 | - static int on_headers_complete(http_parser* parser); | ||
58 | - static int on_message_complete(http_parser* parser); | ||
59 | - static int on_url(http_parser* parser, const char* at, size_t length); | ||
60 | - static int on_header_field(http_parser* parser, const char* at, size_t length); | ||
61 | - static int on_header_value(http_parser* parser, const char* at, size_t length); | ||
62 | - static int on_body(http_parser* parser, const char* at, size_t length); | 54 | + virtual int process_request(SrsSocket* skt, SrsHttpMessage* req); |
63 | }; | 55 | }; |
64 | 56 | ||
65 | #endif | 57 | #endif |
@@ -45,17 +45,30 @@ SrsHttpClient::SrsHttpClient() | @@ -45,17 +45,30 @@ SrsHttpClient::SrsHttpClient() | ||
45 | { | 45 | { |
46 | connected = false; | 46 | connected = false; |
47 | stfd = NULL; | 47 | stfd = NULL; |
48 | + parser = NULL; | ||
48 | } | 49 | } |
49 | 50 | ||
50 | SrsHttpClient::~SrsHttpClient() | 51 | SrsHttpClient::~SrsHttpClient() |
51 | { | 52 | { |
52 | disconnect(); | 53 | disconnect(); |
54 | + srs_freep(parser); | ||
53 | } | 55 | } |
54 | 56 | ||
55 | int SrsHttpClient::post(SrsHttpUri* uri, std::string req, std::string& res) | 57 | int SrsHttpClient::post(SrsHttpUri* uri, std::string req, std::string& res) |
56 | { | 58 | { |
59 | + res = ""; | ||
60 | + | ||
57 | int ret = ERROR_SUCCESS; | 61 | int ret = ERROR_SUCCESS; |
58 | 62 | ||
63 | + if (!parser) { | ||
64 | + parser = new SrsHttpParser(); | ||
65 | + | ||
66 | + if ((ret = parser->initialize(HTTP_RESPONSE)) != ERROR_SUCCESS) { | ||
67 | + srs_error("initialize parser failed. ret=%d", ret); | ||
68 | + return ret; | ||
69 | + } | ||
70 | + } | ||
71 | + | ||
59 | if ((ret = connect(uri)) != ERROR_SUCCESS) { | 72 | if ((ret = connect(uri)) != ERROR_SUCCESS) { |
60 | srs_error("http connect server failed. ret=%d", ret); | 73 | srs_error("http connect server failed. ret=%d", ret); |
61 | return ret; | 74 | return ret; |
@@ -77,8 +90,7 @@ int SrsHttpClient::post(SrsHttpUri* uri, std::string req, std::string& res) | @@ -77,8 +90,7 @@ int SrsHttpClient::post(SrsHttpUri* uri, std::string req, std::string& res) | ||
77 | SrsSocket skt(stfd); | 90 | SrsSocket skt(stfd); |
78 | 91 | ||
79 | std::string data = ss.str(); | 92 | std::string data = ss.str(); |
80 | - ssize_t nwrite; | ||
81 | - if ((ret = skt.write(data.c_str(), data.length(), &nwrite)) != ERROR_SUCCESS) { | 93 | + if ((ret = skt.write(data.c_str(), data.length(), NULL)) != ERROR_SUCCESS) { |
82 | // disconnect when error. | 94 | // disconnect when error. |
83 | disconnect(); | 95 | disconnect(); |
84 | 96 | ||
@@ -86,10 +98,19 @@ int SrsHttpClient::post(SrsHttpUri* uri, std::string req, std::string& res) | @@ -86,10 +98,19 @@ int SrsHttpClient::post(SrsHttpUri* uri, std::string req, std::string& res) | ||
86 | return ret; | 98 | return ret; |
87 | } | 99 | } |
88 | 100 | ||
89 | - if ((ret = parse_response(uri, &skt, &res)) != ERROR_SUCCESS) { | 101 | + SrsHttpMessage* msg = NULL; |
102 | + if ((ret = parser->parse_message(&skt, &msg)) != ERROR_SUCCESS) { | ||
90 | srs_error("parse http post response failed. ret=%d", ret); | 103 | srs_error("parse http post response failed. ret=%d", ret); |
91 | return ret; | 104 | return ret; |
92 | } | 105 | } |
106 | + | ||
107 | + srs_assert(msg); | ||
108 | + srs_assert(msg->is_complete()); | ||
109 | + | ||
110 | + // get response body. | ||
111 | + if (msg->body_size() > 0) { | ||
112 | + res = msg->body(); | ||
113 | + } | ||
93 | srs_info("parse http post response success."); | 114 | srs_info("parse http post response success."); |
94 | 115 | ||
95 | return ret; | 116 | return ret; |
@@ -153,152 +174,6 @@ int SrsHttpClient::connect(SrsHttpUri* uri) | @@ -153,152 +174,6 @@ int SrsHttpClient::connect(SrsHttpUri* uri) | ||
153 | return ret; | 174 | return ret; |
154 | } | 175 | } |
155 | 176 | ||
156 | -int SrsHttpClient::parse_response(SrsHttpUri* uri, SrsSocket* skt, std::string* response) | ||
157 | -{ | ||
158 | - int ret = ERROR_SUCCESS; | ||
159 | - | ||
160 | - int body_received = 0; | ||
161 | - if ((ret = parse_response_header(skt, response, body_received)) != ERROR_SUCCESS) { | ||
162 | - srs_error("parse response header failed. ret=%d", ret); | ||
163 | - return ret; | ||
164 | - } | ||
165 | - | ||
166 | - if ((ret = parse_response_body(uri, skt, response, body_received)) != ERROR_SUCCESS) { | ||
167 | - srs_error("parse response body failed. ret=%d", ret); | ||
168 | - return ret; | ||
169 | - } | ||
170 | - | ||
171 | - srs_info("url %s download, body size=%"PRId64, uri->get_url(), http_header.content_length); | ||
172 | - | ||
173 | - return ret; | ||
174 | -} | ||
175 | - | ||
176 | -int SrsHttpClient::parse_response_header(SrsSocket* skt, std::string* response, int& body_received) | ||
177 | -{ | ||
178 | - int ret = ERROR_SUCCESS; | ||
179 | - | ||
180 | - http_parser_settings settings; | ||
181 | - | ||
182 | - memset(&settings, 0, sizeof(settings)); | ||
183 | - settings.on_headers_complete = on_headers_complete; | ||
184 | - | ||
185 | - http_parser parser; | ||
186 | - http_parser_init(&parser, HTTP_RESPONSE); | ||
187 | - // callback object ptr. | ||
188 | - parser.data = (void*)this; | ||
189 | - | ||
190 | - // reset response header. | ||
191 | - memset(&http_header, 0, sizeof(http_header)); | ||
192 | - | ||
193 | - // parser header. | ||
194 | - char buf[SRS_HTTP_HEADER_BUFFER]; | ||
195 | - for (;;) { | ||
196 | - ssize_t nread; | ||
197 | - if ((ret = skt->read(buf, (size_t)sizeof(buf), &nread)) != ERROR_SUCCESS) { | ||
198 | - srs_error("read body from server failed. ret=%d", ret); | ||
199 | - return ret; | ||
200 | - } | ||
201 | - | ||
202 | - ssize_t nparsed = http_parser_execute(&parser, &settings, buf, nread); | ||
203 | - srs_info("read_size=%d, nparsed=%d", (int)nread, (int)nparsed); | ||
204 | - | ||
205 | - // check header size. | ||
206 | - if (http_header.nread != 0) { | ||
207 | - body_received = nread - nparsed; | ||
208 | - | ||
209 | - srs_info("http header parsed, size=%d, content-length=%"PRId64", body-received=%d", | ||
210 | - http_header.nread, http_header.content_length, body_received); | ||
211 | - | ||
212 | - if(response != NULL && body_received > 0){ | ||
213 | - response->append(buf + nparsed, body_received); | ||
214 | - } | ||
215 | - | ||
216 | - return ret; | ||
217 | - } | ||
218 | - | ||
219 | - if (nparsed != nread) { | ||
220 | - ret = ERROR_HTTP_PARSE_HEADER; | ||
221 | - srs_error("parse response error, parsed(%d)!=read(%d), ret=%d", (int)nparsed, (int)nread, ret); | ||
222 | - return ret; | ||
223 | - } | ||
224 | - } | ||
225 | - | ||
226 | - return ret; | ||
227 | -} | ||
228 | - | ||
229 | -int SrsHttpClient::parse_response_body(SrsHttpUri* uri, SrsSocket* skt, std::string* response, int body_received) | ||
230 | -{ | ||
231 | - int ret = ERROR_SUCCESS; | ||
232 | - | ||
233 | - srs_assert(uri != NULL); | ||
234 | - | ||
235 | - uint64_t body_left = http_header.content_length - body_received; | ||
236 | - | ||
237 | - if (body_left <= 0) { | ||
238 | - return ret; | ||
239 | - } | ||
240 | - | ||
241 | - if (response != NULL) { | ||
242 | - char buf[SRS_HTTP_BODY_BUFFER]; | ||
243 | - | ||
244 | - return parse_response_body_data( | ||
245 | - uri, skt, response, (size_t)body_left, | ||
246 | - (const void*)buf, (size_t)SRS_HTTP_BODY_BUFFER | ||
247 | - ); | ||
248 | - } else { | ||
249 | - // if ignore response, use shared fast memory. | ||
250 | - static char buf[SRS_HTTP_BODY_BUFFER]; | ||
251 | - | ||
252 | - return parse_response_body_data( | ||
253 | - uri, skt, response, (size_t)body_left, | ||
254 | - (const void*)buf, (size_t)SRS_HTTP_BODY_BUFFER | ||
255 | - ); | ||
256 | - } | ||
257 | - | ||
258 | - return ret; | ||
259 | -} | ||
260 | - | ||
261 | -int SrsHttpClient::parse_response_body_data(SrsHttpUri* uri, SrsSocket* skt, std::string* response, size_t body_left, const void* buf, size_t size) | ||
262 | -{ | ||
263 | - int ret = ERROR_SUCCESS; | ||
264 | - | ||
265 | - srs_assert(uri != NULL); | ||
266 | - | ||
267 | - while (body_left > 0) { | ||
268 | - ssize_t nread; | ||
269 | - int size_to_read = srs_min(size, body_left); | ||
270 | - if ((ret = skt->read(buf, size_to_read, &nread)) != ERROR_SUCCESS) { | ||
271 | - srs_error("read header from server failed. ret=%d", ret); | ||
272 | - return ret; | ||
273 | - } | ||
274 | - | ||
275 | - if (response != NULL && nread > 0) { | ||
276 | - response->append((char*)buf, nread); | ||
277 | - } | ||
278 | - | ||
279 | - body_left -= nread; | ||
280 | - srs_info("read url(%s) content partial %"PRId64"/%"PRId64"", | ||
281 | - uri->get_url(), http_header.content_length - body_left, http_header.content_length); | ||
282 | - } | ||
283 | - | ||
284 | - return ret; | ||
285 | -} | ||
286 | - | ||
287 | -int SrsHttpClient::on_headers_complete(http_parser* parser) | ||
288 | -{ | ||
289 | - SrsHttpClient* obj = (SrsHttpClient*)parser->data; | ||
290 | - obj->complete_header(parser); | ||
291 | - | ||
292 | - // see http_parser.c:1570, return 1 to skip body. | ||
293 | - return 1; | ||
294 | -} | ||
295 | - | ||
296 | -void SrsHttpClient::complete_header(http_parser* parser) | ||
297 | -{ | ||
298 | - // save the parser status when header parse completed. | ||
299 | - memcpy(&http_header, parser, sizeof(http_header)); | ||
300 | -} | ||
301 | - | ||
302 | SrsHttpHooks::SrsHttpHooks() | 177 | SrsHttpHooks::SrsHttpHooks() |
303 | { | 178 | { |
304 | } | 179 | } |
@@ -36,6 +36,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -36,6 +36,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
36 | class SrsHttpUri; | 36 | class SrsHttpUri; |
37 | class SrsSocket; | 37 | class SrsSocket; |
38 | class SrsRequest; | 38 | class SrsRequest; |
39 | +class SrsHttpParser; | ||
39 | 40 | ||
40 | #include <srs_app_st.hpp> | 41 | #include <srs_app_st.hpp> |
41 | 42 | ||
@@ -47,8 +48,7 @@ class SrsHttpClient | @@ -47,8 +48,7 @@ class SrsHttpClient | ||
47 | private: | 48 | private: |
48 | bool connected; | 49 | bool connected; |
49 | st_netfd_t stfd; | 50 | st_netfd_t stfd; |
50 | -private: | ||
51 | - http_parser http_header; | 51 | + SrsHttpParser* parser; |
52 | public: | 52 | public: |
53 | SrsHttpClient(); | 53 | SrsHttpClient(); |
54 | virtual ~SrsHttpClient(); | 54 | virtual ~SrsHttpClient(); |
@@ -62,14 +62,6 @@ public: | @@ -62,14 +62,6 @@ public: | ||
62 | private: | 62 | private: |
63 | virtual void disconnect(); | 63 | virtual void disconnect(); |
64 | virtual int connect(SrsHttpUri* uri); | 64 | virtual int connect(SrsHttpUri* uri); |
65 | -private: | ||
66 | - virtual int parse_response(SrsHttpUri* uri, SrsSocket* skt, std::string* response); | ||
67 | - virtual int parse_response_header(SrsSocket* skt, std::string* response, int& body_received); | ||
68 | - virtual int parse_response_body(SrsHttpUri* uri, SrsSocket* skt, std::string* response, int body_received); | ||
69 | - virtual int parse_response_body_data(SrsHttpUri* uri, SrsSocket* skt, std::string* response, size_t body_left, const void* buf, size_t size); | ||
70 | -private: | ||
71 | - static int on_headers_complete(http_parser* parser); | ||
72 | - virtual void complete_header(http_parser* parser); | ||
73 | }; | 65 | }; |
74 | 66 | ||
75 | /** | 67 | /** |
-
请 注册 或 登录 后发表评论