winlin

merge the app http to conn.

@@ -36,6 +36,7 @@ using namespace std; @@ -36,6 +36,7 @@ using namespace std;
36 #include <srs_app_http.hpp> 36 #include <srs_app_http.hpp>
37 #include <srs_app_utility.hpp> 37 #include <srs_app_utility.hpp>
38 #include <srs_core_autofree.hpp> 38 #include <srs_core_autofree.hpp>
  39 +#include <srs_app_http_conn.hpp>
39 40
40 SrsHttpHeartbeat::SrsHttpHeartbeat() 41 SrsHttpHeartbeat::SrsHttpHeartbeat()
41 { 42 {
@@ -23,964 +23,3 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -23,964 +23,3 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 23
24 #include <srs_app_http.hpp> 24 #include <srs_app_http.hpp>
25 25
26 -#ifdef SRS_AUTO_HTTP_PARSER  
27 -  
28 -#include <sstream>  
29 -using namespace std;  
30 -  
31 -#include <srs_kernel_error.hpp>  
32 -#include <srs_kernel_log.hpp>  
33 -#include <srs_app_st_socket.hpp>  
34 -#include <srs_rtmp_sdk.hpp>  
35 -#include <srs_rtmp_buffer.hpp>  
36 -#include <srs_kernel_utility.hpp>  
37 -#include <srs_rtmp_utility.hpp>  
38 -#include <srs_core_autofree.hpp>  
39 -  
40 -SrsHttpResponseWriter::SrsHttpResponseWriter(SrsStSocket* io)  
41 -{  
42 - skt = io;  
43 - hdr = new SrsHttpHeader();  
44 - header_wrote = false;  
45 - status = SRS_CONSTS_HTTP_OK;  
46 - content_length = -1;  
47 - written = 0;  
48 - header_sent = false;  
49 -}  
50 -  
51 -SrsHttpResponseWriter::~SrsHttpResponseWriter()  
52 -{  
53 - srs_freep(hdr);  
54 -}  
55 -  
56 -int SrsHttpResponseWriter::final_request()  
57 -{  
58 - // complete the chunked encoding.  
59 - if (content_length == -1) {  
60 - std::stringstream ss;  
61 - ss << 0 << SRS_HTTP_CRLF << SRS_HTTP_CRLF;  
62 - std::string ch = ss.str();  
63 - return skt->write((void*)ch.data(), (int)ch.length(), NULL);  
64 - }  
65 -  
66 - // flush when send with content length  
67 - return write(NULL, 0);  
68 -}  
69 -  
70 -SrsHttpHeader* SrsHttpResponseWriter::header()  
71 -{  
72 - return hdr;  
73 -}  
74 -  
75 -int SrsHttpResponseWriter::write(char* data, int size)  
76 -{  
77 - int ret = ERROR_SUCCESS;  
78 -  
79 - if (!header_wrote) {  
80 - write_header(SRS_CONSTS_HTTP_OK);  
81 - }  
82 -  
83 - written += size;  
84 - if (content_length != -1 && written > content_length) {  
85 - ret = ERROR_HTTP_CONTENT_LENGTH;  
86 - srs_error("http: exceed content length. ret=%d", ret);  
87 - return ret;  
88 - }  
89 -  
90 - if ((ret = send_header(data, size)) != ERROR_SUCCESS) {  
91 - srs_error("http: send header failed. ret=%d", ret);  
92 - return ret;  
93 - }  
94 -  
95 - // ignore NULL content.  
96 - if (!data) {  
97 - return ret;  
98 - }  
99 -  
100 - // directly send with content length  
101 - if (content_length != -1) {  
102 - return skt->write((void*)data, size, NULL);  
103 - }  
104 -  
105 - // send in chunked encoding.  
106 - std::stringstream ss;  
107 - ss << hex << size << SRS_HTTP_CRLF;  
108 - std::string ch = ss.str();  
109 - if ((ret = skt->write((void*)ch.data(), (int)ch.length(), NULL)) != ERROR_SUCCESS) {  
110 - return ret;  
111 - }  
112 - if ((ret = skt->write((void*)data, size, NULL)) != ERROR_SUCCESS) {  
113 - return ret;  
114 - }  
115 - if ((ret = skt->write((void*)SRS_HTTP_CRLF, 2, NULL)) != ERROR_SUCCESS) {  
116 - return ret;  
117 - }  
118 -  
119 - return ret;  
120 -}  
121 -  
122 -void SrsHttpResponseWriter::write_header(int code)  
123 -{  
124 - if (header_wrote) {  
125 - srs_warn("http: multiple write_header calls, code=%d", code);  
126 - return;  
127 - }  
128 -  
129 - header_wrote = true;  
130 - status = code;  
131 -  
132 - // parse the content length from header.  
133 - content_length = hdr->content_length();  
134 -}  
135 -  
136 -int SrsHttpResponseWriter::send_header(char* data, int size)  
137 -{  
138 - int ret = ERROR_SUCCESS;  
139 -  
140 - if (header_sent) {  
141 - return ret;  
142 - }  
143 - header_sent = true;  
144 -  
145 - std::stringstream ss;  
146 -  
147 - // status_line  
148 - ss << "HTTP/1.1 " << status << " "  
149 - << srs_generate_http_status_text(status) << SRS_HTTP_CRLF;  
150 -  
151 - // detect content type  
152 - if (srs_go_http_body_allowd(status)) {  
153 - if (hdr->content_type().empty()) {  
154 - hdr->set_content_type(srs_go_http_detect(data, size));  
155 - }  
156 - }  
157 -  
158 - // set server if not set.  
159 - if (hdr->get("Server").empty()) {  
160 - hdr->set("Server", RTMP_SIG_SRS_KEY"/"RTMP_SIG_SRS_VERSION);  
161 - }  
162 -  
163 - // chunked encoding  
164 - if (content_length == -1) {  
165 - hdr->set("Transfer-Encoding", "chunked");  
166 - }  
167 -  
168 - // keep alive to make vlc happy.  
169 - hdr->set("Connection", "Keep-Alive");  
170 -  
171 - // write headers  
172 - hdr->write(ss);  
173 -  
174 - // header_eof  
175 - ss << SRS_HTTP_CRLF;  
176 -  
177 - std::string buf = ss.str();  
178 - return skt->write((void*)buf.c_str(), buf.length(), NULL);  
179 -}  
180 -  
181 -SrsHttpResponseReader::SrsHttpResponseReader(SrsHttpMessage* msg, SrsStSocket* io)  
182 -{  
183 - skt = io;  
184 - owner = msg;  
185 - is_eof = false;  
186 - nb_total_read = 0;  
187 - nb_left_chunk = 0;  
188 - buffer = NULL;  
189 -}  
190 -  
191 -SrsHttpResponseReader::~SrsHttpResponseReader()  
192 -{  
193 -}  
194 -  
195 -int SrsHttpResponseReader::initialize(SrsFastBuffer* body)  
196 -{  
197 - int ret = ERROR_SUCCESS;  
198 -  
199 - nb_chunk = 0;  
200 - nb_left_chunk = 0;  
201 - nb_total_read = 0;  
202 - buffer = body;  
203 -  
204 - return ret;  
205 -}  
206 -  
207 -bool SrsHttpResponseReader::eof()  
208 -{  
209 - return is_eof;  
210 -}  
211 -  
212 -int SrsHttpResponseReader::read(char* data, int nb_data, int* nb_read)  
213 -{  
214 - int ret = ERROR_SUCCESS;  
215 -  
216 - if (is_eof) {  
217 - ret = ERROR_HTTP_RESPONSE_EOF;  
218 - srs_error("http: response EOF. ret=%d", ret);  
219 - return ret;  
220 - }  
221 -  
222 - // chunked encoding.  
223 - if (owner->is_chunked()) {  
224 - return read_chunked(data, nb_data, nb_read);  
225 - }  
226 -  
227 - // read by specified content-length  
228 - int max = (int)owner->content_length() - (int)nb_total_read;  
229 - if (max <= 0) {  
230 - is_eof = true;  
231 - return ret;  
232 - }  
233 -  
234 - // change the max to read.  
235 - nb_data = srs_min(nb_data, max);  
236 - return read_specified(data, nb_data, nb_read);  
237 -}  
238 -  
239 -int SrsHttpResponseReader::read_chunked(char* data, int nb_data, int* nb_read)  
240 -{  
241 - int ret = ERROR_SUCCESS;  
242 -  
243 - // when no bytes left in chunk,  
244 - // parse the chunk length first.  
245 - if (nb_left_chunk <= 0) {  
246 - char* at = NULL;  
247 - int length = 0;  
248 - while (!at) {  
249 - // find the CRLF of chunk header end.  
250 - char* start = buffer->bytes();  
251 - char* end = start + buffer->size();  
252 - for (char* p = start; p < end - 1; p++) {  
253 - if (p[0] == SRS_HTTP_CR && p[1] == SRS_HTTP_LF) {  
254 - // invalid chunk, ignore.  
255 - if (p == start) {  
256 - ret = ERROR_HTTP_INVALID_CHUNK_HEADER;  
257 - srs_error("chunk header start with CRLF. ret=%d", ret);  
258 - return ret;  
259 - }  
260 - length = (int)(p - start + 2);  
261 - at = buffer->read_slice(length);  
262 - break;  
263 - }  
264 - }  
265 -  
266 - // got at, ok.  
267 - if (at) {  
268 - break;  
269 - }  
270 -  
271 - // when empty, only grow 1bytes, but the buffer will cache more.  
272 - if ((ret = buffer->grow(skt, buffer->size() + 1)) != ERROR_SUCCESS) {  
273 - if (!srs_is_client_gracefully_close(ret)) {  
274 - srs_error("read body from server failed. ret=%d", ret);  
275 - }  
276 - return ret;  
277 - }  
278 - }  
279 - srs_assert(length >= 3);  
280 -  
281 - // it's ok to set the pos and pos+1 to NULL.  
282 - at[length - 1] = 0;  
283 - at[length - 2] = 0;  
284 -  
285 - // size is the bytes size, excludes the chunk header and end CRLF.  
286 - int ilength = (int)::strtol(at, NULL, 16);  
287 - if (ilength < 0) {  
288 - ret = ERROR_HTTP_INVALID_CHUNK_HEADER;  
289 - srs_error("chunk header negative, length=%d. ret=%d", ilength, ret);  
290 - return ret;  
291 - }  
292 -  
293 - // all bytes in chunk is left now.  
294 - nb_chunk = nb_left_chunk = ilength;  
295 - }  
296 -  
297 - if (nb_chunk <= 0) {  
298 - // for the last chunk, eof.  
299 - is_eof = true;  
300 - } else {  
301 - // for not the last chunk, there must always exists bytes.  
302 - // left bytes in chunk, read some.  
303 - srs_assert(nb_left_chunk);  
304 -  
305 - int nb_bytes = srs_min(nb_left_chunk, nb_data);  
306 - ret = read_specified(data, nb_bytes, &nb_bytes);  
307 -  
308 - // the nb_bytes used for output already read size of bytes.  
309 - if (nb_read) {  
310 - *nb_read = nb_bytes;  
311 - }  
312 - nb_left_chunk -= nb_bytes;  
313 - srs_info("http: read %d bytes of chunk", nb_bytes);  
314 -  
315 - // error or still left bytes in chunk, ignore and read in future.  
316 - if (nb_left_chunk > 0 || (ret != ERROR_SUCCESS)) {  
317 - return ret;  
318 - }  
319 - srs_info("http: read total chunk %dB", nb_chunk);  
320 - }  
321 -  
322 - // for both the last or not, the CRLF of chunk payload end.  
323 - if ((ret = buffer->grow(skt, 2)) != ERROR_SUCCESS) {  
324 - if (!srs_is_client_gracefully_close(ret)) {  
325 - srs_error("read EOF of chunk from server failed. ret=%d", ret);  
326 - }  
327 - return ret;  
328 - }  
329 - buffer->read_slice(2);  
330 -  
331 - return ret;  
332 -}  
333 -  
334 -int SrsHttpResponseReader::read_specified(char* data, int nb_data, int* nb_read)  
335 -{  
336 - int ret = ERROR_SUCCESS;  
337 -  
338 - if (buffer->size() <= 0) {  
339 - // when empty, only grow 1bytes, but the buffer will cache more.  
340 - if ((ret = buffer->grow(skt, 1)) != ERROR_SUCCESS) {  
341 - if (!srs_is_client_gracefully_close(ret)) {  
342 - srs_error("read body from server failed. ret=%d", ret);  
343 - }  
344 - return ret;  
345 - }  
346 - }  
347 -  
348 - int nb_bytes = srs_min(nb_data, buffer->size());  
349 -  
350 - // read data to buffer.  
351 - srs_assert(nb_bytes);  
352 - char* p = buffer->read_slice(nb_bytes);  
353 - memcpy(data, p, nb_bytes);  
354 - if (nb_read) {  
355 - *nb_read = nb_bytes;  
356 - }  
357 -  
358 - // increase the total read to determine whether EOF.  
359 - nb_total_read += nb_bytes;  
360 -  
361 - // for not chunked  
362 - if (!owner->is_chunked()) {  
363 - // when read completed, eof.  
364 - if (nb_total_read >= (int)owner->content_length()) {  
365 - is_eof = true;  
366 - }  
367 - }  
368 -  
369 - return ret;  
370 -}  
371 -  
372 -SrsHttpMessage::SrsHttpMessage(SrsStSocket* io, SrsConnection* c) : ISrsHttpMessage()  
373 -{  
374 - conn = c;  
375 - chunked = false;  
376 - keep_alive = true;  
377 - _uri = new SrsHttpUri();  
378 - _body = new SrsHttpResponseReader(this, io);  
379 - _http_ts_send_buffer = new char[SRS_HTTP_TS_SEND_BUFFER_SIZE];  
380 -}  
381 -  
382 -SrsHttpMessage::~SrsHttpMessage()  
383 -{  
384 - srs_freep(_body);  
385 - srs_freep(_uri);  
386 - srs_freep(_http_ts_send_buffer);  
387 -}  
388 -  
389 -int SrsHttpMessage::update(string url, http_parser* header, SrsFastBuffer* body, vector<SrsHttpHeaderField>& headers)  
390 -{  
391 - int ret = ERROR_SUCCESS;  
392 -  
393 - _url = url;  
394 - _header = *header;  
395 - _headers = headers;  
396 -  
397 - // whether chunked.  
398 - std::string transfer_encoding = get_request_header("Transfer-Encoding");  
399 - chunked = (transfer_encoding == "chunked");  
400 -  
401 - // whether keep alive.  
402 - keep_alive = http_should_keep_alive(header);  
403 -  
404 - // set the buffer.  
405 - if ((ret = _body->initialize(body)) != ERROR_SUCCESS) {  
406 - return ret;  
407 - }  
408 -  
409 - // parse uri from url.  
410 - std::string host = get_request_header("Host");  
411 -  
412 - // donot parse the empty host for uri,  
413 - // for example, the response contains no host,  
414 - // ignore it is ok.  
415 - if (host.empty()) {  
416 - return ret;  
417 - }  
418 -  
419 - // parse uri to schema/server:port/path?query  
420 - std::string uri = "http://" + host + _url;  
421 - if ((ret = _uri->initialize(uri)) != ERROR_SUCCESS) {  
422 - return ret;  
423 - }  
424 -  
425 - // must format as key=value&...&keyN=valueN  
426 - std::string q = _uri->get_query();  
427 - size_t pos = string::npos;  
428 - while (!q.empty()) {  
429 - std::string k = q;  
430 - if ((pos = q.find("=")) != string::npos) {  
431 - k = q.substr(0, pos);  
432 - q = q.substr(pos + 1);  
433 - } else {  
434 - q = "";  
435 - }  
436 -  
437 - std::string v = q;  
438 - if ((pos = q.find("&")) != string::npos) {  
439 - v = q.substr(0, pos);  
440 - q = q.substr(pos + 1);  
441 - } else {  
442 - q = "";  
443 - }  
444 -  
445 - _query[k] = v;  
446 - }  
447 -  
448 - // parse ext.  
449 - _ext = _uri->get_path();  
450 - if ((pos = _ext.rfind(".")) != string::npos) {  
451 - _ext = _ext.substr(pos);  
452 - } else {  
453 - _ext = "";  
454 - }  
455 -  
456 - return ret;  
457 -}  
458 -  
459 -SrsConnection* SrsHttpMessage::connection()  
460 -{  
461 - return conn;  
462 -}  
463 -  
464 -u_int8_t SrsHttpMessage::method()  
465 -{  
466 - return (u_int8_t)_header.method;  
467 -}  
468 -  
469 -u_int16_t SrsHttpMessage::status_code()  
470 -{  
471 - return (u_int16_t)_header.status_code;  
472 -}  
473 -  
474 -string SrsHttpMessage::method_str()  
475 -{  
476 - if (is_http_get()) {  
477 - return "GET";  
478 - }  
479 - if (is_http_put()) {  
480 - return "PUT";  
481 - }  
482 - if (is_http_post()) {  
483 - return "POST";  
484 - }  
485 - if (is_http_delete()) {  
486 - return "DELETE";  
487 - }  
488 - if (is_http_options()) {  
489 - return "OPTIONS";  
490 - }  
491 -  
492 - return "OTHER";  
493 -}  
494 -  
495 -bool SrsHttpMessage::is_http_get()  
496 -{  
497 - return _header.method == SRS_CONSTS_HTTP_GET;  
498 -}  
499 -  
500 -bool SrsHttpMessage::is_http_put()  
501 -{  
502 - return _header.method == SRS_CONSTS_HTTP_PUT;  
503 -}  
504 -  
505 -bool SrsHttpMessage::is_http_post()  
506 -{  
507 - return _header.method == SRS_CONSTS_HTTP_POST;  
508 -}  
509 -  
510 -bool SrsHttpMessage::is_http_delete()  
511 -{  
512 - return _header.method == SRS_CONSTS_HTTP_DELETE;  
513 -}  
514 -  
515 -bool SrsHttpMessage::is_http_options()  
516 -{  
517 - return _header.method == SRS_CONSTS_HTTP_OPTIONS;  
518 -}  
519 -  
520 -bool SrsHttpMessage::is_chunked()  
521 -{  
522 - return chunked;  
523 -}  
524 -  
525 -bool SrsHttpMessage::is_keep_alive()  
526 -{  
527 - return keep_alive;  
528 -}  
529 -  
530 -string SrsHttpMessage::uri()  
531 -{  
532 - std::string uri = _uri->get_schema();  
533 - if (uri.empty()) {  
534 - uri += "http";  
535 - }  
536 - uri += "://";  
537 -  
538 - uri += host();  
539 - uri += path();  
540 - return uri;  
541 -}  
542 -  
543 -string SrsHttpMessage::url()  
544 -{  
545 - return _uri->get_url();  
546 -}  
547 -  
548 -string SrsHttpMessage::host()  
549 -{  
550 - return _uri->get_host();  
551 -}  
552 -  
553 -string SrsHttpMessage::path()  
554 -{  
555 - return _uri->get_path();  
556 -}  
557 -  
558 -string SrsHttpMessage::ext()  
559 -{  
560 - return _ext;  
561 -}  
562 -  
563 -int SrsHttpMessage::body_read_all(string& body)  
564 -{  
565 - int ret = ERROR_SUCCESS;  
566 -  
567 - // cache to read.  
568 - char* buf = new char[SRS_HTTP_READ_CACHE_BYTES];  
569 - SrsAutoFree(char, buf);  
570 -  
571 - // whatever, read util EOF.  
572 - while (!_body->eof()) {  
573 - int nb_read = 0;  
574 - if ((ret = _body->read(buf, SRS_HTTP_READ_CACHE_BYTES, &nb_read)) != ERROR_SUCCESS) {  
575 - return ret;  
576 - }  
577 -  
578 - if (nb_read > 0) {  
579 - body.append(buf, nb_read);  
580 - }  
581 - }  
582 -  
583 - return ret;  
584 -}  
585 -  
586 -ISrsHttpResponseReader* SrsHttpMessage::body_reader()  
587 -{  
588 - return _body;  
589 -}  
590 -  
591 -int64_t SrsHttpMessage::content_length()  
592 -{  
593 - return _header.content_length;  
594 -}  
595 -  
596 -string SrsHttpMessage::query_get(string key)  
597 -{  
598 - std::string v;  
599 -  
600 - if (_query.find(key) != _query.end()) {  
601 - v = _query[key];  
602 - }  
603 -  
604 - return v;  
605 -}  
606 -  
607 -int SrsHttpMessage::request_header_count()  
608 -{  
609 - return (int)_headers.size();  
610 -}  
611 -  
612 -string SrsHttpMessage::request_header_key_at(int index)  
613 -{  
614 - srs_assert(index < request_header_count());  
615 - SrsHttpHeaderField item = _headers[index];  
616 - return item.first;  
617 -}  
618 -  
619 -string SrsHttpMessage::request_header_value_at(int index)  
620 -{  
621 - srs_assert(index < request_header_count());  
622 - SrsHttpHeaderField item = _headers[index];  
623 - return item.second;  
624 -}  
625 -  
626 -string SrsHttpMessage::get_request_header(string name)  
627 -{  
628 - std::vector<SrsHttpHeaderField>::iterator it;  
629 -  
630 - for (it = _headers.begin(); it != _headers.end(); ++it) {  
631 - SrsHttpHeaderField& elem = *it;  
632 - std::string key = elem.first;  
633 - std::string value = elem.second;  
634 - if (key == name) {  
635 - return value;  
636 - }  
637 - }  
638 -  
639 - return "";  
640 -}  
641 -  
642 -SrsRequest* SrsHttpMessage::to_request(string vhost)  
643 -{  
644 - SrsRequest* req = new SrsRequest();  
645 -  
646 - req->app = _uri->get_path();  
647 - size_t pos = string::npos;  
648 - if ((pos = req->app.rfind("/")) != string::npos) {  
649 - req->stream = req->app.substr(pos + 1);  
650 - req->app = req->app.substr(0, pos);  
651 - }  
652 - if ((pos = req->stream.rfind(".")) != string::npos) {  
653 - req->stream = req->stream.substr(0, pos);  
654 - }  
655 -  
656 - req->tcUrl = "rtmp://" + vhost + req->app;  
657 - req->pageUrl = get_request_header("Referer");  
658 - req->objectEncoding = 0;  
659 -  
660 - srs_discovery_tc_url(req->tcUrl,  
661 - req->schema, req->host, req->vhost, req->app, req->port,  
662 - req->param);  
663 - req->strip();  
664 -  
665 - return req;  
666 -}  
667 -  
668 -SrsHttpParser::SrsHttpParser()  
669 -{  
670 - buffer = new SrsFastBuffer();  
671 -}  
672 -  
673 -SrsHttpParser::~SrsHttpParser()  
674 -{  
675 - srs_freep(buffer);  
676 -}  
677 -  
678 -int SrsHttpParser::initialize(enum http_parser_type type)  
679 -{  
680 - int ret = ERROR_SUCCESS;  
681 -  
682 - memset(&settings, 0, sizeof(settings));  
683 - settings.on_message_begin = on_message_begin;  
684 - settings.on_url = on_url;  
685 - settings.on_header_field = on_header_field;  
686 - settings.on_header_value = on_header_value;  
687 - settings.on_headers_complete = on_headers_complete;  
688 - settings.on_body = on_body;  
689 - settings.on_message_complete = on_message_complete;  
690 -  
691 - http_parser_init(&parser, type);  
692 - // callback object ptr.  
693 - parser.data = (void*)this;  
694 -  
695 - return ret;  
696 -}  
697 -  
698 -int SrsHttpParser::parse_message(SrsStSocket* skt, SrsConnection* conn, ISrsHttpMessage** ppmsg)  
699 -{  
700 - *ppmsg = NULL;  
701 -  
702 - int ret = ERROR_SUCCESS;  
703 -  
704 - // reset request data.  
705 - field_name = "";  
706 - field_value = "";  
707 - expect_field_name = true;  
708 - state = SrsHttpParseStateInit;  
709 - header = http_parser();  
710 - url = "";  
711 - headers.clear();  
712 - header_parsed = 0;  
713 -  
714 - // do parse  
715 - if ((ret = parse_message_imp(skt)) != ERROR_SUCCESS) {  
716 - if (!srs_is_client_gracefully_close(ret)) {  
717 - srs_error("parse http msg failed. ret=%d", ret);  
718 - }  
719 - return ret;  
720 - }  
721 -  
722 - // create msg  
723 - SrsHttpMessage* msg = new SrsHttpMessage(skt, conn);  
724 -  
725 - // initalize http msg, parse url.  
726 - if ((ret = msg->update(url, &header, buffer, headers)) != ERROR_SUCCESS) {  
727 - srs_error("initialize http msg failed. ret=%d", ret);  
728 - srs_freep(msg);  
729 - return ret;  
730 - }  
731 -  
732 - // parse ok, return the msg.  
733 - *ppmsg = msg;  
734 -  
735 - return ret;  
736 -}  
737 -  
738 -int SrsHttpParser::parse_message_imp(SrsStSocket* skt)  
739 -{  
740 - int ret = ERROR_SUCCESS;  
741 -  
742 - while (true) {  
743 - ssize_t nparsed = 0;  
744 -  
745 - // when got entire http header, parse it.  
746 - // @see https://github.com/simple-rtmp-server/srs/issues/400  
747 - char* start = buffer->bytes();  
748 - char* end = start + buffer->size();  
749 - for (char* p = start; p <= end - 4; p++) {  
750 - // SRS_HTTP_CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A  
751 - if (p[0] == SRS_CONSTS_CR && p[1] == SRS_CONSTS_LF && p[2] == SRS_CONSTS_CR && p[3] == SRS_CONSTS_LF) {  
752 - nparsed = http_parser_execute(&parser, &settings, buffer->bytes(), buffer->size());  
753 - srs_info("buffer=%d, nparsed=%d, header=%d", buffer->size(), (int)nparsed, header_parsed);  
754 - break;  
755 - }  
756 - }  
757 -  
758 - // consume the parsed bytes.  
759 - if (nparsed && header_parsed) {  
760 - buffer->read_slice(header_parsed);  
761 - }  
762 -  
763 - // ok atleast header completed,  
764 - // never wait for body completed, for maybe chunked.  
765 - if (state == SrsHttpParseStateHeaderComplete || state == SrsHttpParseStateMessageComplete) {  
766 - break;  
767 - }  
768 -  
769 - // when nothing parsed, read more to parse.  
770 - if (nparsed == 0) {  
771 - // when requires more, only grow 1bytes, but the buffer will cache more.  
772 - if ((ret = buffer->grow(skt, buffer->size() + 1)) != ERROR_SUCCESS) {  
773 - if (!srs_is_client_gracefully_close(ret)) {  
774 - srs_error("read body from server failed. ret=%d", ret);  
775 - }  
776 - return ret;  
777 - }  
778 - }  
779 - }  
780 -  
781 - // parse last header.  
782 - if (!field_name.empty() && !field_value.empty()) {  
783 - headers.push_back(std::make_pair(field_name, field_value));  
784 - }  
785 -  
786 - return ret;  
787 -}  
788 -  
789 -int SrsHttpParser::on_message_begin(http_parser* parser)  
790 -{  
791 - SrsHttpParser* obj = (SrsHttpParser*)parser->data;  
792 - srs_assert(obj);  
793 -  
794 - obj->state = SrsHttpParseStateStart;  
795 -  
796 - srs_info("***MESSAGE BEGIN***");  
797 -  
798 - return 0;  
799 -}  
800 -  
801 -int SrsHttpParser::on_headers_complete(http_parser* parser)  
802 -{  
803 - SrsHttpParser* obj = (SrsHttpParser*)parser->data;  
804 - srs_assert(obj);  
805 -  
806 - obj->header = *parser;  
807 - // save the parser when header parse completed.  
808 - obj->state = SrsHttpParseStateHeaderComplete;  
809 - obj->header_parsed = (int)parser->nread;  
810 -  
811 - srs_info("***HEADERS COMPLETE***");  
812 -  
813 - // see http_parser.c:1570, return 1 to skip body.  
814 - return 0;  
815 -}  
816 -  
817 -int SrsHttpParser::on_message_complete(http_parser* parser)  
818 -{  
819 - SrsHttpParser* obj = (SrsHttpParser*)parser->data;  
820 - srs_assert(obj);  
821 -  
822 - // save the parser when body parse completed.  
823 - obj->state = SrsHttpParseStateMessageComplete;  
824 -  
825 - srs_info("***MESSAGE COMPLETE***\n");  
826 -  
827 - return 0;  
828 -}  
829 -  
830 -int SrsHttpParser::on_url(http_parser* parser, const char* at, size_t length)  
831 -{  
832 - SrsHttpParser* obj = (SrsHttpParser*)parser->data;  
833 - srs_assert(obj);  
834 -  
835 - if (length > 0) {  
836 - obj->url.append(at, (int)length);  
837 - }  
838 -  
839 - srs_info("Method: %d, Url: %.*s", parser->method, (int)length, at);  
840 -  
841 - return 0;  
842 -}  
843 -  
844 -int SrsHttpParser::on_header_field(http_parser* parser, const char* at, size_t length)  
845 -{  
846 - SrsHttpParser* obj = (SrsHttpParser*)parser->data;  
847 - srs_assert(obj);  
848 -  
849 - // field value=>name, reap the field.  
850 - if (!obj->expect_field_name) {  
851 - obj->headers.push_back(std::make_pair(obj->field_name, obj->field_value));  
852 -  
853 - // reset the field name when parsed.  
854 - obj->field_name = "";  
855 - obj->field_value = "";  
856 - }  
857 - obj->expect_field_name = true;  
858 -  
859 - if (length > 0) {  
860 - obj->field_name.append(at, (int)length);  
861 - }  
862 -  
863 - srs_info("Header field(%d bytes): %.*s", (int)length, (int)length, at);  
864 - return 0;  
865 -}  
866 -  
867 -int SrsHttpParser::on_header_value(http_parser* parser, const char* at, size_t length)  
868 -{  
869 - SrsHttpParser* obj = (SrsHttpParser*)parser->data;  
870 - srs_assert(obj);  
871 -  
872 - if (length > 0) {  
873 - obj->field_value.append(at, (int)length);  
874 - }  
875 - obj->expect_field_name = false;  
876 -  
877 - srs_info("Header value(%d bytes): %.*s", (int)length, (int)length, at);  
878 - return 0;  
879 -}  
880 -  
881 -int SrsHttpParser::on_body(http_parser* parser, const char* at, size_t length)  
882 -{  
883 - SrsHttpParser* obj = (SrsHttpParser*)parser->data;  
884 - srs_assert(obj);  
885 -  
886 - srs_info("Body: %.*s", (int)length, at);  
887 -  
888 - return 0;  
889 -}  
890 -  
891 -SrsHttpUri::SrsHttpUri()  
892 -{  
893 - port = SRS_DEFAULT_HTTP_PORT;  
894 -}  
895 -  
896 -SrsHttpUri::~SrsHttpUri()  
897 -{  
898 -}  
899 -  
900 -int SrsHttpUri::initialize(string _url)  
901 -{  
902 - int ret = ERROR_SUCCESS;  
903 -  
904 - url = _url;  
905 - const char* purl = url.c_str();  
906 -  
907 - http_parser_url hp_u;  
908 - if((ret = http_parser_parse_url(purl, url.length(), 0, &hp_u)) != 0){  
909 - int code = ret;  
910 - ret = ERROR_HTTP_PARSE_URI;  
911 -  
912 - srs_error("parse url %s failed, code=%d, ret=%d", purl, code, ret);  
913 - return ret;  
914 - }  
915 -  
916 - std::string field = get_uri_field(url, &hp_u, UF_SCHEMA);  
917 - if(!field.empty()){  
918 - schema = field;  
919 - }  
920 -  
921 - host = get_uri_field(url, &hp_u, UF_HOST);  
922 -  
923 - field = get_uri_field(url, &hp_u, UF_PORT);  
924 - if(!field.empty()){  
925 - port = atoi(field.c_str());  
926 - }  
927 -  
928 - path = get_uri_field(url, &hp_u, UF_PATH);  
929 - srs_info("parse url %s success", purl);  
930 -  
931 - query = get_uri_field(url, &hp_u, UF_QUERY);  
932 - srs_info("parse query %s success", query.c_str());  
933 -  
934 - return ret;  
935 -}  
936 -  
937 -const char* SrsHttpUri::get_url()  
938 -{  
939 - return url.data();  
940 -}  
941 -  
942 -const char* SrsHttpUri::get_schema()  
943 -{  
944 - return schema.data();  
945 -}  
946 -  
947 -const char* SrsHttpUri::get_host()  
948 -{  
949 - return host.data();  
950 -}  
951 -  
952 -int SrsHttpUri::get_port()  
953 -{  
954 - return port;  
955 -}  
956 -  
957 -const char* SrsHttpUri::get_path()  
958 -{  
959 - return path.data();  
960 -}  
961 -  
962 -const char* SrsHttpUri::get_query()  
963 -{  
964 - return query.data();  
965 -}  
966 -  
967 -string SrsHttpUri::get_uri_field(string uri, http_parser_url* hp_u, http_parser_url_fields field)  
968 -{  
969 - if((hp_u->field_set & (1 << field)) == 0){  
970 - return "";  
971 - }  
972 -  
973 - srs_verbose("uri field matched, off=%d, len=%d, value=%.*s",  
974 - hp_u->field_data[field].off,  
975 - hp_u->field_data[field].len,  
976 - hp_u->field_data[field].len,  
977 - uri.c_str() + hp_u->field_data[field].off);  
978 -  
979 - int offset = hp_u->field_data[field].off;  
980 - int len = hp_u->field_data[field].len;  
981 -  
982 - return uri.substr(offset, len);  
983 -}  
984 -  
985 -#endif  
986 -  
@@ -29,314 +29,4 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -29,314 +29,4 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 */ 29 */
30 #include <srs_core.hpp> 30 #include <srs_core.hpp>
31 31
32 -#ifdef SRS_AUTO_HTTP_PARSER  
33 -  
34 -#include <map>  
35 -#include <string>  
36 -#include <vector>  
37 -  
38 -#include <http_parser.h>  
39 -  
40 -#include <srs_app_st.hpp>  
41 -#include <srs_http_stack.hpp>  
42 -  
43 -class SrsRequest;  
44 -class SrsStSocket;  
45 -class SrsHttpMessage;  
46 -class SrsFastBuffer;  
47 -class SrsHttpUri;  
48 -class SrsConnection;  
49 -  
50 -/**  
51 - * response writer use st socket  
52 - */  
53 -class SrsHttpResponseWriter : public ISrsHttpResponseWriter  
54 -{  
55 -private:  
56 - SrsStSocket* skt;  
57 - SrsHttpHeader* hdr;  
58 -private:  
59 - // reply header has been (logically) written  
60 - bool header_wrote;  
61 - // status code passed to WriteHeader  
62 - int status;  
63 -private:  
64 - // explicitly-declared Content-Length; or -1  
65 - int64_t content_length;  
66 - // number of bytes written in body  
67 - int64_t written;  
68 -private:  
69 - // wroteHeader tells whether the header's been written to "the  
70 - // wire" (or rather: w.conn.buf). this is unlike  
71 - // (*response).wroteHeader, which tells only whether it was  
72 - // logically written.  
73 - bool header_sent;  
74 -public:  
75 - SrsHttpResponseWriter(SrsStSocket* io);  
76 - virtual ~SrsHttpResponseWriter();  
77 -public:  
78 - virtual int final_request();  
79 - virtual SrsHttpHeader* header();  
80 - virtual int write(char* data, int size);  
81 - virtual void write_header(int code);  
82 - virtual int send_header(char* data, int size);  
83 -};  
84 -  
85 -/**  
86 - * response reader use st socket.  
87 - */  
88 -class SrsHttpResponseReader : virtual public ISrsHttpResponseReader  
89 -{  
90 -private:  
91 - SrsStSocket* skt;  
92 - SrsHttpMessage* owner;  
93 - SrsFastBuffer* buffer;  
94 - bool is_eof;  
95 - // the left bytes in chunk.  
96 - int nb_left_chunk;  
97 - // the number of bytes of current chunk.  
98 - int nb_chunk;  
99 - // already read total bytes.  
100 - int64_t nb_total_read;  
101 -public:  
102 - SrsHttpResponseReader(SrsHttpMessage* msg, SrsStSocket* io);  
103 - virtual ~SrsHttpResponseReader();  
104 -public:  
105 - /**  
106 - * initialize the response reader with buffer.  
107 - */  
108 - virtual int initialize(SrsFastBuffer* buffer);  
109 - // interface ISrsHttpResponseReader  
110 -public:  
111 - virtual bool eof();  
112 - virtual int read(char* data, int nb_data, int* nb_read);  
113 -private:  
114 - virtual int read_chunked(char* data, int nb_data, int* nb_read);  
115 - virtual int read_specified(char* data, int nb_data, int* nb_read);  
116 -};  
117 -  
118 -// for http header.  
119 -typedef std::pair<std::string, std::string> SrsHttpHeaderField;  
120 -  
121 -// A Request represents an HTTP request received by a server  
122 -// or to be sent by a client.  
123 -//  
124 -// The field semantics differ slightly between client and server  
125 -// usage. In addition to the notes on the fields below, see the  
126 -// documentation for Request.Write and RoundTripper.  
127 -/**  
128 - * the http message, request or response.  
129 - */  
130 -class SrsHttpMessage : public ISrsHttpMessage  
131 -{  
132 -private:  
133 - /**  
134 - * parsed url.  
135 - */  
136 - std::string _url;  
137 - /**  
138 - * the extension of file, for example, .flv  
139 - */  
140 - std::string _ext;  
141 - /**  
142 - * parsed http header.  
143 - */  
144 - http_parser _header;  
145 - /**  
146 - * body object, reader object.  
147 - * @remark, user can get body in string by get_body().  
148 - */  
149 - SrsHttpResponseReader* _body;  
150 - /**  
151 - * whether the body is chunked.  
152 - */  
153 - bool chunked;  
154 - /**  
155 - * whether the request indicates should keep alive  
156 - * for the http connection.  
157 - */  
158 - bool keep_alive;  
159 - /**  
160 - * uri parser  
161 - */  
162 - SrsHttpUri* _uri;  
163 - /**  
164 - * use a buffer to read and send ts file.  
165 - */  
166 - // TODO: FIXME: remove it.  
167 - char* _http_ts_send_buffer;  
168 - // http headers  
169 - std::vector<SrsHttpHeaderField> _headers;  
170 - // the query map  
171 - std::map<std::string, std::string> _query;  
172 - // the transport connection, can be NULL.  
173 - SrsConnection* conn;  
174 -public:  
175 - SrsHttpMessage(SrsStSocket* io, SrsConnection* c);  
176 - virtual ~SrsHttpMessage();  
177 -public:  
178 - /**  
179 - * set the original messages, then update the message.  
180 - */  
181 - virtual int update(std::string url, http_parser* header,  
182 - SrsFastBuffer* body, std::vector<SrsHttpHeaderField>& headers  
183 - );  
184 -private:  
185 - virtual SrsConnection* connection();  
186 -public:  
187 - virtual u_int8_t method();  
188 - virtual u_int16_t status_code();  
189 - /**  
190 - * method helpers.  
191 - */  
192 - virtual std::string method_str();  
193 - virtual bool is_http_get();  
194 - virtual bool is_http_put();  
195 - virtual bool is_http_post();  
196 - virtual bool is_http_delete();  
197 - virtual bool is_http_options();  
198 - /**  
199 - * whether body is chunked encoding, for reader only.  
200 - */  
201 - virtual bool is_chunked();  
202 - /**  
203 - * whether should keep the connection alive.  
204 - */  
205 - virtual bool is_keep_alive();  
206 - /**  
207 - * the uri contains the host and path.  
208 - */  
209 - virtual std::string uri();  
210 - /**  
211 - * the url maybe the path.  
212 - */  
213 - virtual std::string url();  
214 - virtual std::string host();  
215 - virtual std::string path();  
216 - virtual std::string ext();  
217 -public:  
218 - /**  
219 - * read body to string.  
220 - * @remark for small http body.  
221 - */  
222 - virtual int body_read_all(std::string& body);  
223 - /**  
224 - * get the body reader, to read one by one.  
225 - * @remark when body is very large, or chunked, use this.  
226 - */  
227 - virtual ISrsHttpResponseReader* body_reader();  
228 - /**  
229 - * the content length, -1 for chunked or not set.  
230 - */  
231 - virtual int64_t content_length();  
232 - /**  
233 - * get the param in query string,  
234 - * for instance, query is "start=100&end=200",  
235 - * then query_get("start") is "100", and query_get("end") is "200"  
236 - */  
237 - virtual std::string query_get(std::string key);  
238 - /**  
239 - * get the headers.  
240 - */  
241 - virtual int request_header_count();  
242 - virtual std::string request_header_key_at(int index);  
243 - virtual std::string request_header_value_at(int index);  
244 - virtual std::string get_request_header(std::string name);  
245 -public:  
246 - /**  
247 - * convert the http message to a request.  
248 - * @remark user must free the return request.  
249 - */  
250 - virtual SrsRequest* to_request(std::string vhost);  
251 -};  
252 -  
253 -/**  
254 -* wrapper for http-parser,  
255 -* provides HTTP message originted service.  
256 -*/  
257 -class SrsHttpParser  
258 -{  
259 -private:  
260 - http_parser_settings settings;  
261 - http_parser parser;  
262 - // the global parse buffer.  
263 - SrsFastBuffer* buffer;  
264 -private:  
265 - // http parse data, reset before parse message.  
266 - bool expect_field_name;  
267 - std::string field_name;  
268 - std::string field_value;  
269 - SrsHttpParseState state;  
270 - http_parser header;  
271 - std::string url;  
272 - std::vector<SrsHttpHeaderField> headers;  
273 - int header_parsed;  
274 -public:  
275 - SrsHttpParser();  
276 - virtual ~SrsHttpParser();  
277 -public:  
278 - /**  
279 - * initialize the http parser with specified type,  
280 - * one parser can only parse request or response messages.  
281 - */  
282 - virtual int initialize(enum http_parser_type type);  
283 - /**  
284 - * always parse a http message,  
285 - * that is, the *ppmsg always NOT-NULL when return success.  
286 - * or error and *ppmsg must be NULL.  
287 - * @remark, if success, *ppmsg always NOT-NULL, *ppmsg always is_complete().  
288 - */  
289 - virtual int parse_message(SrsStSocket* skt, SrsConnection* conn, ISrsHttpMessage** ppmsg);  
290 -private:  
291 - /**  
292 - * parse the HTTP message to member field: msg.  
293 - */  
294 - virtual int parse_message_imp(SrsStSocket* skt);  
295 -private:  
296 - static int on_message_begin(http_parser* parser);  
297 - static int on_headers_complete(http_parser* parser);  
298 - static int on_message_complete(http_parser* parser);  
299 - static int on_url(http_parser* parser, const char* at, size_t length);  
300 - static int on_header_field(http_parser* parser, const char* at, size_t length);  
301 - static int on_header_value(http_parser* parser, const char* at, size_t length);  
302 - static int on_body(http_parser* parser, const char* at, size_t length);  
303 -};  
304 -  
305 -/**  
306 -* used to resolve the http uri.  
307 -*/  
308 -class SrsHttpUri  
309 -{  
310 -private:  
311 - std::string url;  
312 - std::string schema;  
313 - std::string host;  
314 - int port;  
315 - std::string path;  
316 - std::string query;  
317 -public:  
318 - SrsHttpUri();  
319 - virtual ~SrsHttpUri();  
320 -public:  
321 - /**  
322 - * initialize the http uri.  
323 - */  
324 - virtual int initialize(std::string _url);  
325 -public:  
326 - virtual const char* get_url();  
327 - virtual const char* get_schema();  
328 - virtual const char* get_host();  
329 - virtual int get_port();  
330 - virtual const char* get_path();  
331 - virtual const char* get_query();  
332 -private:  
333 - /**  
334 - * get the parsed url field.  
335 - * @return return empty string if not set.  
336 - */  
337 - virtual std::string get_uri_field(std::string uri, http_parser_url* hp_u, http_parser_url_fields field);  
338 -};  
339 -  
340 -#endif  
341 -  
342 #endif 32 #endif
@@ -39,6 +39,7 @@ using namespace std; @@ -39,6 +39,7 @@ using namespace std;
39 #include <srs_rtmp_sdk.hpp> 39 #include <srs_rtmp_sdk.hpp>
40 #include <srs_app_dvr.hpp> 40 #include <srs_app_dvr.hpp>
41 #include <srs_app_config.hpp> 41 #include <srs_app_config.hpp>
  42 +#include <srs_app_http_conn.hpp>
42 43
43 SrsGoApiRoot::SrsGoApiRoot() 44 SrsGoApiRoot::SrsGoApiRoot()
44 { 45 {
@@ -39,7 +39,7 @@ class SrsHttpHandler; @@ -39,7 +39,7 @@ class SrsHttpHandler;
39 39
40 #include <srs_app_st.hpp> 40 #include <srs_app_st.hpp>
41 #include <srs_app_conn.hpp> 41 #include <srs_app_conn.hpp>
42 -#include <srs_app_http.hpp> 42 +#include <srs_http_stack.hpp>
43 43
44 // for http root. 44 // for http root.
45 class SrsGoApiRoot : public ISrsHttpHandler 45 class SrsGoApiRoot : public ISrsHttpHandler
@@ -36,6 +36,7 @@ using namespace std; @@ -36,6 +36,7 @@ using namespace std;
36 #include <srs_kernel_utility.hpp> 36 #include <srs_kernel_utility.hpp>
37 #include <srs_app_utility.hpp> 37 #include <srs_app_utility.hpp>
38 #include <srs_core_autofree.hpp> 38 #include <srs_core_autofree.hpp>
  39 +#include <srs_app_http_conn.hpp>
39 40
40 SrsHttpClient::SrsHttpClient() 41 SrsHttpClient::SrsHttpClient()
41 { 42 {
@@ -23,7 +23,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -23,7 +23,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 23
24 #include <srs_app_http_conn.hpp> 24 #include <srs_app_http_conn.hpp>
25 25
26 -#ifdef SRS_AUTO_HTTP_SERVER 26 +#if defined(SRS_AUTO_HTTP_PARSER) || defined(SRS_AUTO_HTTP_SERVER)
27 27
28 #include <sys/types.h> 28 #include <sys/types.h>
29 #include <sys/stat.h> 29 #include <sys/stat.h>
@@ -33,6 +33,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -33,6 +33,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 #include <sstream> 33 #include <sstream>
34 using namespace std; 34 using namespace std;
35 35
  36 +#include <srs_rtmp_buffer.hpp>
  37 +#include <srs_rtmp_utility.hpp>
36 #include <srs_kernel_log.hpp> 38 #include <srs_kernel_log.hpp>
37 #include <srs_kernel_error.hpp> 39 #include <srs_kernel_error.hpp>
38 #include <srs_app_st_socket.hpp> 40 #include <srs_app_st_socket.hpp>
@@ -51,6 +53,959 @@ using namespace std; @@ -51,6 +53,959 @@ using namespace std;
51 #include <srs_app_source.hpp> 53 #include <srs_app_source.hpp>
52 #include <srs_app_server.hpp> 54 #include <srs_app_server.hpp>
53 55
  56 +#endif
  57 +
  58 +#ifdef SRS_AUTO_HTTP_PARSER
  59 +
  60 +SrsHttpResponseWriter::SrsHttpResponseWriter(SrsStSocket* io)
  61 +{
  62 + skt = io;
  63 + hdr = new SrsHttpHeader();
  64 + header_wrote = false;
  65 + status = SRS_CONSTS_HTTP_OK;
  66 + content_length = -1;
  67 + written = 0;
  68 + header_sent = false;
  69 +}
  70 +
  71 +SrsHttpResponseWriter::~SrsHttpResponseWriter()
  72 +{
  73 + srs_freep(hdr);
  74 +}
  75 +
  76 +int SrsHttpResponseWriter::final_request()
  77 +{
  78 + // complete the chunked encoding.
  79 + if (content_length == -1) {
  80 + std::stringstream ss;
  81 + ss << 0 << SRS_HTTP_CRLF << SRS_HTTP_CRLF;
  82 + std::string ch = ss.str();
  83 + return skt->write((void*)ch.data(), (int)ch.length(), NULL);
  84 + }
  85 +
  86 + // flush when send with content length
  87 + return write(NULL, 0);
  88 +}
  89 +
  90 +SrsHttpHeader* SrsHttpResponseWriter::header()
  91 +{
  92 + return hdr;
  93 +}
  94 +
  95 +int SrsHttpResponseWriter::write(char* data, int size)
  96 +{
  97 + int ret = ERROR_SUCCESS;
  98 +
  99 + if (!header_wrote) {
  100 + write_header(SRS_CONSTS_HTTP_OK);
  101 + }
  102 +
  103 + written += size;
  104 + if (content_length != -1 && written > content_length) {
  105 + ret = ERROR_HTTP_CONTENT_LENGTH;
  106 + srs_error("http: exceed content length. ret=%d", ret);
  107 + return ret;
  108 + }
  109 +
  110 + if ((ret = send_header(data, size)) != ERROR_SUCCESS) {
  111 + srs_error("http: send header failed. ret=%d", ret);
  112 + return ret;
  113 + }
  114 +
  115 + // ignore NULL content.
  116 + if (!data) {
  117 + return ret;
  118 + }
  119 +
  120 + // directly send with content length
  121 + if (content_length != -1) {
  122 + return skt->write((void*)data, size, NULL);
  123 + }
  124 +
  125 + // send in chunked encoding.
  126 + std::stringstream ss;
  127 + ss << hex << size << SRS_HTTP_CRLF;
  128 + std::string ch = ss.str();
  129 + if ((ret = skt->write((void*)ch.data(), (int)ch.length(), NULL)) != ERROR_SUCCESS) {
  130 + return ret;
  131 + }
  132 + if ((ret = skt->write((void*)data, size, NULL)) != ERROR_SUCCESS) {
  133 + return ret;
  134 + }
  135 + if ((ret = skt->write((void*)SRS_HTTP_CRLF, 2, NULL)) != ERROR_SUCCESS) {
  136 + return ret;
  137 + }
  138 +
  139 + return ret;
  140 +}
  141 +
  142 +void SrsHttpResponseWriter::write_header(int code)
  143 +{
  144 + if (header_wrote) {
  145 + srs_warn("http: multiple write_header calls, code=%d", code);
  146 + return;
  147 + }
  148 +
  149 + header_wrote = true;
  150 + status = code;
  151 +
  152 + // parse the content length from header.
  153 + content_length = hdr->content_length();
  154 +}
  155 +
  156 +int SrsHttpResponseWriter::send_header(char* data, int size)
  157 +{
  158 + int ret = ERROR_SUCCESS;
  159 +
  160 + if (header_sent) {
  161 + return ret;
  162 + }
  163 + header_sent = true;
  164 +
  165 + std::stringstream ss;
  166 +
  167 + // status_line
  168 + ss << "HTTP/1.1 " << status << " "
  169 + << srs_generate_http_status_text(status) << SRS_HTTP_CRLF;
  170 +
  171 + // detect content type
  172 + if (srs_go_http_body_allowd(status)) {
  173 + if (hdr->content_type().empty()) {
  174 + hdr->set_content_type(srs_go_http_detect(data, size));
  175 + }
  176 + }
  177 +
  178 + // set server if not set.
  179 + if (hdr->get("Server").empty()) {
  180 + hdr->set("Server", RTMP_SIG_SRS_KEY"/"RTMP_SIG_SRS_VERSION);
  181 + }
  182 +
  183 + // chunked encoding
  184 + if (content_length == -1) {
  185 + hdr->set("Transfer-Encoding", "chunked");
  186 + }
  187 +
  188 + // keep alive to make vlc happy.
  189 + hdr->set("Connection", "Keep-Alive");
  190 +
  191 + // write headers
  192 + hdr->write(ss);
  193 +
  194 + // header_eof
  195 + ss << SRS_HTTP_CRLF;
  196 +
  197 + std::string buf = ss.str();
  198 + return skt->write((void*)buf.c_str(), buf.length(), NULL);
  199 +}
  200 +
  201 +SrsHttpResponseReader::SrsHttpResponseReader(SrsHttpMessage* msg, SrsStSocket* io)
  202 +{
  203 + skt = io;
  204 + owner = msg;
  205 + is_eof = false;
  206 + nb_total_read = 0;
  207 + nb_left_chunk = 0;
  208 + buffer = NULL;
  209 +}
  210 +
  211 +SrsHttpResponseReader::~SrsHttpResponseReader()
  212 +{
  213 +}
  214 +
  215 +int SrsHttpResponseReader::initialize(SrsFastBuffer* body)
  216 +{
  217 + int ret = ERROR_SUCCESS;
  218 +
  219 + nb_chunk = 0;
  220 + nb_left_chunk = 0;
  221 + nb_total_read = 0;
  222 + buffer = body;
  223 +
  224 + return ret;
  225 +}
  226 +
  227 +bool SrsHttpResponseReader::eof()
  228 +{
  229 + return is_eof;
  230 +}
  231 +
  232 +int SrsHttpResponseReader::read(char* data, int nb_data, int* nb_read)
  233 +{
  234 + int ret = ERROR_SUCCESS;
  235 +
  236 + if (is_eof) {
  237 + ret = ERROR_HTTP_RESPONSE_EOF;
  238 + srs_error("http: response EOF. ret=%d", ret);
  239 + return ret;
  240 + }
  241 +
  242 + // chunked encoding.
  243 + if (owner->is_chunked()) {
  244 + return read_chunked(data, nb_data, nb_read);
  245 + }
  246 +
  247 + // read by specified content-length
  248 + int max = (int)owner->content_length() - (int)nb_total_read;
  249 + if (max <= 0) {
  250 + is_eof = true;
  251 + return ret;
  252 + }
  253 +
  254 + // change the max to read.
  255 + nb_data = srs_min(nb_data, max);
  256 + return read_specified(data, nb_data, nb_read);
  257 +}
  258 +
  259 +int SrsHttpResponseReader::read_chunked(char* data, int nb_data, int* nb_read)
  260 +{
  261 + int ret = ERROR_SUCCESS;
  262 +
  263 + // when no bytes left in chunk,
  264 + // parse the chunk length first.
  265 + if (nb_left_chunk <= 0) {
  266 + char* at = NULL;
  267 + int length = 0;
  268 + while (!at) {
  269 + // find the CRLF of chunk header end.
  270 + char* start = buffer->bytes();
  271 + char* end = start + buffer->size();
  272 + for (char* p = start; p < end - 1; p++) {
  273 + if (p[0] == SRS_HTTP_CR && p[1] == SRS_HTTP_LF) {
  274 + // invalid chunk, ignore.
  275 + if (p == start) {
  276 + ret = ERROR_HTTP_INVALID_CHUNK_HEADER;
  277 + srs_error("chunk header start with CRLF. ret=%d", ret);
  278 + return ret;
  279 + }
  280 + length = (int)(p - start + 2);
  281 + at = buffer->read_slice(length);
  282 + break;
  283 + }
  284 + }
  285 +
  286 + // got at, ok.
  287 + if (at) {
  288 + break;
  289 + }
  290 +
  291 + // when empty, only grow 1bytes, but the buffer will cache more.
  292 + if ((ret = buffer->grow(skt, buffer->size() + 1)) != ERROR_SUCCESS) {
  293 + if (!srs_is_client_gracefully_close(ret)) {
  294 + srs_error("read body from server failed. ret=%d", ret);
  295 + }
  296 + return ret;
  297 + }
  298 + }
  299 + srs_assert(length >= 3);
  300 +
  301 + // it's ok to set the pos and pos+1 to NULL.
  302 + at[length - 1] = 0;
  303 + at[length - 2] = 0;
  304 +
  305 + // size is the bytes size, excludes the chunk header and end CRLF.
  306 + int ilength = (int)::strtol(at, NULL, 16);
  307 + if (ilength < 0) {
  308 + ret = ERROR_HTTP_INVALID_CHUNK_HEADER;
  309 + srs_error("chunk header negative, length=%d. ret=%d", ilength, ret);
  310 + return ret;
  311 + }
  312 +
  313 + // all bytes in chunk is left now.
  314 + nb_chunk = nb_left_chunk = ilength;
  315 + }
  316 +
  317 + if (nb_chunk <= 0) {
  318 + // for the last chunk, eof.
  319 + is_eof = true;
  320 + } else {
  321 + // for not the last chunk, there must always exists bytes.
  322 + // left bytes in chunk, read some.
  323 + srs_assert(nb_left_chunk);
  324 +
  325 + int nb_bytes = srs_min(nb_left_chunk, nb_data);
  326 + ret = read_specified(data, nb_bytes, &nb_bytes);
  327 +
  328 + // the nb_bytes used for output already read size of bytes.
  329 + if (nb_read) {
  330 + *nb_read = nb_bytes;
  331 + }
  332 + nb_left_chunk -= nb_bytes;
  333 + srs_info("http: read %d bytes of chunk", nb_bytes);
  334 +
  335 + // error or still left bytes in chunk, ignore and read in future.
  336 + if (nb_left_chunk > 0 || (ret != ERROR_SUCCESS)) {
  337 + return ret;
  338 + }
  339 + srs_info("http: read total chunk %dB", nb_chunk);
  340 + }
  341 +
  342 + // for both the last or not, the CRLF of chunk payload end.
  343 + if ((ret = buffer->grow(skt, 2)) != ERROR_SUCCESS) {
  344 + if (!srs_is_client_gracefully_close(ret)) {
  345 + srs_error("read EOF of chunk from server failed. ret=%d", ret);
  346 + }
  347 + return ret;
  348 + }
  349 + buffer->read_slice(2);
  350 +
  351 + return ret;
  352 +}
  353 +
  354 +int SrsHttpResponseReader::read_specified(char* data, int nb_data, int* nb_read)
  355 +{
  356 + int ret = ERROR_SUCCESS;
  357 +
  358 + if (buffer->size() <= 0) {
  359 + // when empty, only grow 1bytes, but the buffer will cache more.
  360 + if ((ret = buffer->grow(skt, 1)) != ERROR_SUCCESS) {
  361 + if (!srs_is_client_gracefully_close(ret)) {
  362 + srs_error("read body from server failed. ret=%d", ret);
  363 + }
  364 + return ret;
  365 + }
  366 + }
  367 +
  368 + int nb_bytes = srs_min(nb_data, buffer->size());
  369 +
  370 + // read data to buffer.
  371 + srs_assert(nb_bytes);
  372 + char* p = buffer->read_slice(nb_bytes);
  373 + memcpy(data, p, nb_bytes);
  374 + if (nb_read) {
  375 + *nb_read = nb_bytes;
  376 + }
  377 +
  378 + // increase the total read to determine whether EOF.
  379 + nb_total_read += nb_bytes;
  380 +
  381 + // for not chunked
  382 + if (!owner->is_chunked()) {
  383 + // when read completed, eof.
  384 + if (nb_total_read >= (int)owner->content_length()) {
  385 + is_eof = true;
  386 + }
  387 + }
  388 +
  389 + return ret;
  390 +}
  391 +
  392 +SrsHttpMessage::SrsHttpMessage(SrsStSocket* io, SrsConnection* c) : ISrsHttpMessage()
  393 +{
  394 + conn = c;
  395 + chunked = false;
  396 + keep_alive = true;
  397 + _uri = new SrsHttpUri();
  398 + _body = new SrsHttpResponseReader(this, io);
  399 + _http_ts_send_buffer = new char[SRS_HTTP_TS_SEND_BUFFER_SIZE];
  400 +}
  401 +
  402 +SrsHttpMessage::~SrsHttpMessage()
  403 +{
  404 + srs_freep(_body);
  405 + srs_freep(_uri);
  406 + srs_freep(_http_ts_send_buffer);
  407 +}
  408 +
  409 +int SrsHttpMessage::update(string url, http_parser* header, SrsFastBuffer* body, vector<SrsHttpHeaderField>& headers)
  410 +{
  411 + int ret = ERROR_SUCCESS;
  412 +
  413 + _url = url;
  414 + _header = *header;
  415 + _headers = headers;
  416 +
  417 + // whether chunked.
  418 + std::string transfer_encoding = get_request_header("Transfer-Encoding");
  419 + chunked = (transfer_encoding == "chunked");
  420 +
  421 + // whether keep alive.
  422 + keep_alive = http_should_keep_alive(header);
  423 +
  424 + // set the buffer.
  425 + if ((ret = _body->initialize(body)) != ERROR_SUCCESS) {
  426 + return ret;
  427 + }
  428 +
  429 + // parse uri from url.
  430 + std::string host = get_request_header("Host");
  431 +
  432 + // donot parse the empty host for uri,
  433 + // for example, the response contains no host,
  434 + // ignore it is ok.
  435 + if (host.empty()) {
  436 + return ret;
  437 + }
  438 +
  439 + // parse uri to schema/server:port/path?query
  440 + std::string uri = "http://" + host + _url;
  441 + if ((ret = _uri->initialize(uri)) != ERROR_SUCCESS) {
  442 + return ret;
  443 + }
  444 +
  445 + // must format as key=value&...&keyN=valueN
  446 + std::string q = _uri->get_query();
  447 + size_t pos = string::npos;
  448 + while (!q.empty()) {
  449 + std::string k = q;
  450 + if ((pos = q.find("=")) != string::npos) {
  451 + k = q.substr(0, pos);
  452 + q = q.substr(pos + 1);
  453 + } else {
  454 + q = "";
  455 + }
  456 +
  457 + std::string v = q;
  458 + if ((pos = q.find("&")) != string::npos) {
  459 + v = q.substr(0, pos);
  460 + q = q.substr(pos + 1);
  461 + } else {
  462 + q = "";
  463 + }
  464 +
  465 + _query[k] = v;
  466 + }
  467 +
  468 + // parse ext.
  469 + _ext = _uri->get_path();
  470 + if ((pos = _ext.rfind(".")) != string::npos) {
  471 + _ext = _ext.substr(pos);
  472 + } else {
  473 + _ext = "";
  474 + }
  475 +
  476 + return ret;
  477 +}
  478 +
  479 +SrsConnection* SrsHttpMessage::connection()
  480 +{
  481 + return conn;
  482 +}
  483 +
  484 +u_int8_t SrsHttpMessage::method()
  485 +{
  486 + return (u_int8_t)_header.method;
  487 +}
  488 +
  489 +u_int16_t SrsHttpMessage::status_code()
  490 +{
  491 + return (u_int16_t)_header.status_code;
  492 +}
  493 +
  494 +string SrsHttpMessage::method_str()
  495 +{
  496 + if (is_http_get()) {
  497 + return "GET";
  498 + }
  499 + if (is_http_put()) {
  500 + return "PUT";
  501 + }
  502 + if (is_http_post()) {
  503 + return "POST";
  504 + }
  505 + if (is_http_delete()) {
  506 + return "DELETE";
  507 + }
  508 + if (is_http_options()) {
  509 + return "OPTIONS";
  510 + }
  511 +
  512 + return "OTHER";
  513 +}
  514 +
  515 +bool SrsHttpMessage::is_http_get()
  516 +{
  517 + return _header.method == SRS_CONSTS_HTTP_GET;
  518 +}
  519 +
  520 +bool SrsHttpMessage::is_http_put()
  521 +{
  522 + return _header.method == SRS_CONSTS_HTTP_PUT;
  523 +}
  524 +
  525 +bool SrsHttpMessage::is_http_post()
  526 +{
  527 + return _header.method == SRS_CONSTS_HTTP_POST;
  528 +}
  529 +
  530 +bool SrsHttpMessage::is_http_delete()
  531 +{
  532 + return _header.method == SRS_CONSTS_HTTP_DELETE;
  533 +}
  534 +
  535 +bool SrsHttpMessage::is_http_options()
  536 +{
  537 + return _header.method == SRS_CONSTS_HTTP_OPTIONS;
  538 +}
  539 +
  540 +bool SrsHttpMessage::is_chunked()
  541 +{
  542 + return chunked;
  543 +}
  544 +
  545 +bool SrsHttpMessage::is_keep_alive()
  546 +{
  547 + return keep_alive;
  548 +}
  549 +
  550 +string SrsHttpMessage::uri()
  551 +{
  552 + std::string uri = _uri->get_schema();
  553 + if (uri.empty()) {
  554 + uri += "http";
  555 + }
  556 + uri += "://";
  557 +
  558 + uri += host();
  559 + uri += path();
  560 + return uri;
  561 +}
  562 +
  563 +string SrsHttpMessage::url()
  564 +{
  565 + return _uri->get_url();
  566 +}
  567 +
  568 +string SrsHttpMessage::host()
  569 +{
  570 + return _uri->get_host();
  571 +}
  572 +
  573 +string SrsHttpMessage::path()
  574 +{
  575 + return _uri->get_path();
  576 +}
  577 +
  578 +string SrsHttpMessage::ext()
  579 +{
  580 + return _ext;
  581 +}
  582 +
  583 +int SrsHttpMessage::body_read_all(string& body)
  584 +{
  585 + int ret = ERROR_SUCCESS;
  586 +
  587 + // cache to read.
  588 + char* buf = new char[SRS_HTTP_READ_CACHE_BYTES];
  589 + SrsAutoFree(char, buf);
  590 +
  591 + // whatever, read util EOF.
  592 + while (!_body->eof()) {
  593 + int nb_read = 0;
  594 + if ((ret = _body->read(buf, SRS_HTTP_READ_CACHE_BYTES, &nb_read)) != ERROR_SUCCESS) {
  595 + return ret;
  596 + }
  597 +
  598 + if (nb_read > 0) {
  599 + body.append(buf, nb_read);
  600 + }
  601 + }
  602 +
  603 + return ret;
  604 +}
  605 +
  606 +ISrsHttpResponseReader* SrsHttpMessage::body_reader()
  607 +{
  608 + return _body;
  609 +}
  610 +
  611 +int64_t SrsHttpMessage::content_length()
  612 +{
  613 + return _header.content_length;
  614 +}
  615 +
  616 +string SrsHttpMessage::query_get(string key)
  617 +{
  618 + std::string v;
  619 +
  620 + if (_query.find(key) != _query.end()) {
  621 + v = _query[key];
  622 + }
  623 +
  624 + return v;
  625 +}
  626 +
  627 +int SrsHttpMessage::request_header_count()
  628 +{
  629 + return (int)_headers.size();
  630 +}
  631 +
  632 +string SrsHttpMessage::request_header_key_at(int index)
  633 +{
  634 + srs_assert(index < request_header_count());
  635 + SrsHttpHeaderField item = _headers[index];
  636 + return item.first;
  637 +}
  638 +
  639 +string SrsHttpMessage::request_header_value_at(int index)
  640 +{
  641 + srs_assert(index < request_header_count());
  642 + SrsHttpHeaderField item = _headers[index];
  643 + return item.second;
  644 +}
  645 +
  646 +string SrsHttpMessage::get_request_header(string name)
  647 +{
  648 + std::vector<SrsHttpHeaderField>::iterator it;
  649 +
  650 + for (it = _headers.begin(); it != _headers.end(); ++it) {
  651 + SrsHttpHeaderField& elem = *it;
  652 + std::string key = elem.first;
  653 + std::string value = elem.second;
  654 + if (key == name) {
  655 + return value;
  656 + }
  657 + }
  658 +
  659 + return "";
  660 +}
  661 +
  662 +SrsRequest* SrsHttpMessage::to_request(string vhost)
  663 +{
  664 + SrsRequest* req = new SrsRequest();
  665 +
  666 + req->app = _uri->get_path();
  667 + size_t pos = string::npos;
  668 + if ((pos = req->app.rfind("/")) != string::npos) {
  669 + req->stream = req->app.substr(pos + 1);
  670 + req->app = req->app.substr(0, pos);
  671 + }
  672 + if ((pos = req->stream.rfind(".")) != string::npos) {
  673 + req->stream = req->stream.substr(0, pos);
  674 + }
  675 +
  676 + req->tcUrl = "rtmp://" + vhost + req->app;
  677 + req->pageUrl = get_request_header("Referer");
  678 + req->objectEncoding = 0;
  679 +
  680 + srs_discovery_tc_url(req->tcUrl,
  681 + req->schema, req->host, req->vhost, req->app, req->port,
  682 + req->param);
  683 + req->strip();
  684 +
  685 + return req;
  686 +}
  687 +
  688 +SrsHttpParser::SrsHttpParser()
  689 +{
  690 + buffer = new SrsFastBuffer();
  691 +}
  692 +
  693 +SrsHttpParser::~SrsHttpParser()
  694 +{
  695 + srs_freep(buffer);
  696 +}
  697 +
  698 +int SrsHttpParser::initialize(enum http_parser_type type)
  699 +{
  700 + int ret = ERROR_SUCCESS;
  701 +
  702 + memset(&settings, 0, sizeof(settings));
  703 + settings.on_message_begin = on_message_begin;
  704 + settings.on_url = on_url;
  705 + settings.on_header_field = on_header_field;
  706 + settings.on_header_value = on_header_value;
  707 + settings.on_headers_complete = on_headers_complete;
  708 + settings.on_body = on_body;
  709 + settings.on_message_complete = on_message_complete;
  710 +
  711 + http_parser_init(&parser, type);
  712 + // callback object ptr.
  713 + parser.data = (void*)this;
  714 +
  715 + return ret;
  716 +}
  717 +
  718 +int SrsHttpParser::parse_message(SrsStSocket* skt, SrsConnection* conn, ISrsHttpMessage** ppmsg)
  719 +{
  720 + *ppmsg = NULL;
  721 +
  722 + int ret = ERROR_SUCCESS;
  723 +
  724 + // reset request data.
  725 + field_name = "";
  726 + field_value = "";
  727 + expect_field_name = true;
  728 + state = SrsHttpParseStateInit;
  729 + header = http_parser();
  730 + url = "";
  731 + headers.clear();
  732 + header_parsed = 0;
  733 +
  734 + // do parse
  735 + if ((ret = parse_message_imp(skt)) != ERROR_SUCCESS) {
  736 + if (!srs_is_client_gracefully_close(ret)) {
  737 + srs_error("parse http msg failed. ret=%d", ret);
  738 + }
  739 + return ret;
  740 + }
  741 +
  742 + // create msg
  743 + SrsHttpMessage* msg = new SrsHttpMessage(skt, conn);
  744 +
  745 + // initalize http msg, parse url.
  746 + if ((ret = msg->update(url, &header, buffer, headers)) != ERROR_SUCCESS) {
  747 + srs_error("initialize http msg failed. ret=%d", ret);
  748 + srs_freep(msg);
  749 + return ret;
  750 + }
  751 +
  752 + // parse ok, return the msg.
  753 + *ppmsg = msg;
  754 +
  755 + return ret;
  756 +}
  757 +
  758 +int SrsHttpParser::parse_message_imp(SrsStSocket* skt)
  759 +{
  760 + int ret = ERROR_SUCCESS;
  761 +
  762 + while (true) {
  763 + ssize_t nparsed = 0;
  764 +
  765 + // when got entire http header, parse it.
  766 + // @see https://github.com/simple-rtmp-server/srs/issues/400
  767 + char* start = buffer->bytes();
  768 + char* end = start + buffer->size();
  769 + for (char* p = start; p <= end - 4; p++) {
  770 + // SRS_HTTP_CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A
  771 + if (p[0] == SRS_CONSTS_CR && p[1] == SRS_CONSTS_LF && p[2] == SRS_CONSTS_CR && p[3] == SRS_CONSTS_LF) {
  772 + nparsed = http_parser_execute(&parser, &settings, buffer->bytes(), buffer->size());
  773 + srs_info("buffer=%d, nparsed=%d, header=%d", buffer->size(), (int)nparsed, header_parsed);
  774 + break;
  775 + }
  776 + }
  777 +
  778 + // consume the parsed bytes.
  779 + if (nparsed && header_parsed) {
  780 + buffer->read_slice(header_parsed);
  781 + }
  782 +
  783 + // ok atleast header completed,
  784 + // never wait for body completed, for maybe chunked.
  785 + if (state == SrsHttpParseStateHeaderComplete || state == SrsHttpParseStateMessageComplete) {
  786 + break;
  787 + }
  788 +
  789 + // when nothing parsed, read more to parse.
  790 + if (nparsed == 0) {
  791 + // when requires more, only grow 1bytes, but the buffer will cache more.
  792 + if ((ret = buffer->grow(skt, buffer->size() + 1)) != ERROR_SUCCESS) {
  793 + if (!srs_is_client_gracefully_close(ret)) {
  794 + srs_error("read body from server failed. ret=%d", ret);
  795 + }
  796 + return ret;
  797 + }
  798 + }
  799 + }
  800 +
  801 + // parse last header.
  802 + if (!field_name.empty() && !field_value.empty()) {
  803 + headers.push_back(std::make_pair(field_name, field_value));
  804 + }
  805 +
  806 + return ret;
  807 +}
  808 +
  809 +int SrsHttpParser::on_message_begin(http_parser* parser)
  810 +{
  811 + SrsHttpParser* obj = (SrsHttpParser*)parser->data;
  812 + srs_assert(obj);
  813 +
  814 + obj->state = SrsHttpParseStateStart;
  815 +
  816 + srs_info("***MESSAGE BEGIN***");
  817 +
  818 + return 0;
  819 +}
  820 +
  821 +int SrsHttpParser::on_headers_complete(http_parser* parser)
  822 +{
  823 + SrsHttpParser* obj = (SrsHttpParser*)parser->data;
  824 + srs_assert(obj);
  825 +
  826 + obj->header = *parser;
  827 + // save the parser when header parse completed.
  828 + obj->state = SrsHttpParseStateHeaderComplete;
  829 + obj->header_parsed = (int)parser->nread;
  830 +
  831 + srs_info("***HEADERS COMPLETE***");
  832 +
  833 + // see http_parser.c:1570, return 1 to skip body.
  834 + return 0;
  835 +}
  836 +
  837 +int SrsHttpParser::on_message_complete(http_parser* parser)
  838 +{
  839 + SrsHttpParser* obj = (SrsHttpParser*)parser->data;
  840 + srs_assert(obj);
  841 +
  842 + // save the parser when body parse completed.
  843 + obj->state = SrsHttpParseStateMessageComplete;
  844 +
  845 + srs_info("***MESSAGE COMPLETE***\n");
  846 +
  847 + return 0;
  848 +}
  849 +
  850 +int SrsHttpParser::on_url(http_parser* parser, const char* at, size_t length)
  851 +{
  852 + SrsHttpParser* obj = (SrsHttpParser*)parser->data;
  853 + srs_assert(obj);
  854 +
  855 + if (length > 0) {
  856 + obj->url.append(at, (int)length);
  857 + }
  858 +
  859 + srs_info("Method: %d, Url: %.*s", parser->method, (int)length, at);
  860 +
  861 + return 0;
  862 +}
  863 +
  864 +int SrsHttpParser::on_header_field(http_parser* parser, const char* at, size_t length)
  865 +{
  866 + SrsHttpParser* obj = (SrsHttpParser*)parser->data;
  867 + srs_assert(obj);
  868 +
  869 + // field value=>name, reap the field.
  870 + if (!obj->expect_field_name) {
  871 + obj->headers.push_back(std::make_pair(obj->field_name, obj->field_value));
  872 +
  873 + // reset the field name when parsed.
  874 + obj->field_name = "";
  875 + obj->field_value = "";
  876 + }
  877 + obj->expect_field_name = true;
  878 +
  879 + if (length > 0) {
  880 + obj->field_name.append(at, (int)length);
  881 + }
  882 +
  883 + srs_info("Header field(%d bytes): %.*s", (int)length, (int)length, at);
  884 + return 0;
  885 +}
  886 +
  887 +int SrsHttpParser::on_header_value(http_parser* parser, const char* at, size_t length)
  888 +{
  889 + SrsHttpParser* obj = (SrsHttpParser*)parser->data;
  890 + srs_assert(obj);
  891 +
  892 + if (length > 0) {
  893 + obj->field_value.append(at, (int)length);
  894 + }
  895 + obj->expect_field_name = false;
  896 +
  897 + srs_info("Header value(%d bytes): %.*s", (int)length, (int)length, at);
  898 + return 0;
  899 +}
  900 +
  901 +int SrsHttpParser::on_body(http_parser* parser, const char* at, size_t length)
  902 +{
  903 + SrsHttpParser* obj = (SrsHttpParser*)parser->data;
  904 + srs_assert(obj);
  905 +
  906 + srs_info("Body: %.*s", (int)length, at);
  907 +
  908 + return 0;
  909 +}
  910 +
  911 +SrsHttpUri::SrsHttpUri()
  912 +{
  913 + port = SRS_DEFAULT_HTTP_PORT;
  914 +}
  915 +
  916 +SrsHttpUri::~SrsHttpUri()
  917 +{
  918 +}
  919 +
  920 +int SrsHttpUri::initialize(string _url)
  921 +{
  922 + int ret = ERROR_SUCCESS;
  923 +
  924 + url = _url;
  925 + const char* purl = url.c_str();
  926 +
  927 + http_parser_url hp_u;
  928 + if((ret = http_parser_parse_url(purl, url.length(), 0, &hp_u)) != 0){
  929 + int code = ret;
  930 + ret = ERROR_HTTP_PARSE_URI;
  931 +
  932 + srs_error("parse url %s failed, code=%d, ret=%d", purl, code, ret);
  933 + return ret;
  934 + }
  935 +
  936 + std::string field = get_uri_field(url, &hp_u, UF_SCHEMA);
  937 + if(!field.empty()){
  938 + schema = field;
  939 + }
  940 +
  941 + host = get_uri_field(url, &hp_u, UF_HOST);
  942 +
  943 + field = get_uri_field(url, &hp_u, UF_PORT);
  944 + if(!field.empty()){
  945 + port = atoi(field.c_str());
  946 + }
  947 +
  948 + path = get_uri_field(url, &hp_u, UF_PATH);
  949 + srs_info("parse url %s success", purl);
  950 +
  951 + query = get_uri_field(url, &hp_u, UF_QUERY);
  952 + srs_info("parse query %s success", query.c_str());
  953 +
  954 + return ret;
  955 +}
  956 +
  957 +const char* SrsHttpUri::get_url()
  958 +{
  959 + return url.data();
  960 +}
  961 +
  962 +const char* SrsHttpUri::get_schema()
  963 +{
  964 + return schema.data();
  965 +}
  966 +
  967 +const char* SrsHttpUri::get_host()
  968 +{
  969 + return host.data();
  970 +}
  971 +
  972 +int SrsHttpUri::get_port()
  973 +{
  974 + return port;
  975 +}
  976 +
  977 +const char* SrsHttpUri::get_path()
  978 +{
  979 + return path.data();
  980 +}
  981 +
  982 +const char* SrsHttpUri::get_query()
  983 +{
  984 + return query.data();
  985 +}
  986 +
  987 +string SrsHttpUri::get_uri_field(string uri, http_parser_url* hp_u, http_parser_url_fields field)
  988 +{
  989 + if((hp_u->field_set & (1 << field)) == 0){
  990 + return "";
  991 + }
  992 +
  993 + srs_verbose("uri field matched, off=%d, len=%d, value=%.*s",
  994 + hp_u->field_data[field].off,
  995 + hp_u->field_data[field].len,
  996 + hp_u->field_data[field].len,
  997 + uri.c_str() + hp_u->field_data[field].off);
  998 +
  999 + int offset = hp_u->field_data[field].off;
  1000 + int len = hp_u->field_data[field].len;
  1001 +
  1002 + return uri.substr(offset, len);
  1003 +}
  1004 +
  1005 +#endif
  1006 +
  1007 +#ifdef SRS_AUTO_HTTP_SERVER
  1008 +
54 SrsVodStream::SrsVodStream(string root_dir) 1009 SrsVodStream::SrsVodStream(string root_dir)
55 : SrsHttpFileServer(root_dir) 1010 : SrsHttpFileServer(root_dir)
56 { 1011 {
@@ -30,14 +30,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -30,14 +30,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 30
31 #include <srs_core.hpp> 31 #include <srs_core.hpp>
32 32
33 -#ifdef SRS_AUTO_HTTP_SERVER 33 +#ifdef SRS_AUTO_HTTP_PARSER
  34 +#include <http_parser.h>
  35 +#endif
  36 +
  37 +#if defined(SRS_AUTO_HTTP_PARSER) || defined(SRS_AUTO_HTTP_SERVER)
  38 +
  39 +#include <map>
  40 +#include <string>
  41 +#include <vector>
34 42
35 #include <srs_app_st.hpp> 43 #include <srs_app_st.hpp>
36 -#include <srs_app_conn.hpp> 44 +#include <srs_http_stack.hpp>
37 #include <srs_app_http.hpp> 45 #include <srs_app_http.hpp>
38 #include <srs_app_reload.hpp> 46 #include <srs_app_reload.hpp>
39 #include <srs_kernel_file.hpp> 47 #include <srs_kernel_file.hpp>
40 #include <srs_app_thread.hpp> 48 #include <srs_app_thread.hpp>
  49 +#include <srs_app_conn.hpp>
41 50
42 class SrsServer; 51 class SrsServer;
43 class SrsSource; 52 class SrsSource;
@@ -53,6 +62,309 @@ class ISrsHttpMessage; @@ -53,6 +62,309 @@ class ISrsHttpMessage;
53 class SrsHttpHandler; 62 class SrsHttpHandler;
54 class SrsMessageQueue; 63 class SrsMessageQueue;
55 class SrsSharedPtrMessage; 64 class SrsSharedPtrMessage;
  65 +class SrsRequest;
  66 +class SrsFastBuffer;
  67 +class SrsHttpUri;
  68 +class SrsConnection;
  69 +class SrsHttpMessage;
  70 +
  71 +#endif
  72 +
  73 +#ifdef SRS_AUTO_HTTP_PARSER
  74 +
  75 +/**
  76 + * response writer use st socket
  77 + */
  78 +class SrsHttpResponseWriter : public ISrsHttpResponseWriter
  79 +{
  80 +private:
  81 + SrsStSocket* skt;
  82 + SrsHttpHeader* hdr;
  83 +private:
  84 + // reply header has been (logically) written
  85 + bool header_wrote;
  86 + // status code passed to WriteHeader
  87 + int status;
  88 +private:
  89 + // explicitly-declared Content-Length; or -1
  90 + int64_t content_length;
  91 + // number of bytes written in body
  92 + int64_t written;
  93 +private:
  94 + // wroteHeader tells whether the header's been written to "the
  95 + // wire" (or rather: w.conn.buf). this is unlike
  96 + // (*response).wroteHeader, which tells only whether it was
  97 + // logically written.
  98 + bool header_sent;
  99 +public:
  100 + SrsHttpResponseWriter(SrsStSocket* io);
  101 + virtual ~SrsHttpResponseWriter();
  102 +public:
  103 + virtual int final_request();
  104 + virtual SrsHttpHeader* header();
  105 + virtual int write(char* data, int size);
  106 + virtual void write_header(int code);
  107 + virtual int send_header(char* data, int size);
  108 +};
  109 +
  110 +/**
  111 + * response reader use st socket.
  112 + */
  113 +class SrsHttpResponseReader : virtual public ISrsHttpResponseReader
  114 +{
  115 +private:
  116 + SrsStSocket* skt;
  117 + SrsHttpMessage* owner;
  118 + SrsFastBuffer* buffer;
  119 + bool is_eof;
  120 + // the left bytes in chunk.
  121 + int nb_left_chunk;
  122 + // the number of bytes of current chunk.
  123 + int nb_chunk;
  124 + // already read total bytes.
  125 + int64_t nb_total_read;
  126 +public:
  127 + SrsHttpResponseReader(SrsHttpMessage* msg, SrsStSocket* io);
  128 + virtual ~SrsHttpResponseReader();
  129 +public:
  130 + /**
  131 + * initialize the response reader with buffer.
  132 + */
  133 + virtual int initialize(SrsFastBuffer* buffer);
  134 + // interface ISrsHttpResponseReader
  135 +public:
  136 + virtual bool eof();
  137 + virtual int read(char* data, int nb_data, int* nb_read);
  138 +private:
  139 + virtual int read_chunked(char* data, int nb_data, int* nb_read);
  140 + virtual int read_specified(char* data, int nb_data, int* nb_read);
  141 +};
  142 +
  143 +// for http header.
  144 +typedef std::pair<std::string, std::string> SrsHttpHeaderField;
  145 +
  146 +// A Request represents an HTTP request received by a server
  147 +// or to be sent by a client.
  148 +//
  149 +// The field semantics differ slightly between client and server
  150 +// usage. In addition to the notes on the fields below, see the
  151 +// documentation for Request.Write and RoundTripper.
  152 +/**
  153 + * the http message, request or response.
  154 + */
  155 +class SrsHttpMessage : public ISrsHttpMessage
  156 +{
  157 +private:
  158 + /**
  159 + * parsed url.
  160 + */
  161 + std::string _url;
  162 + /**
  163 + * the extension of file, for example, .flv
  164 + */
  165 + std::string _ext;
  166 + /**
  167 + * parsed http header.
  168 + */
  169 + http_parser _header;
  170 + /**
  171 + * body object, reader object.
  172 + * @remark, user can get body in string by get_body().
  173 + */
  174 + SrsHttpResponseReader* _body;
  175 + /**
  176 + * whether the body is chunked.
  177 + */
  178 + bool chunked;
  179 + /**
  180 + * whether the request indicates should keep alive
  181 + * for the http connection.
  182 + */
  183 + bool keep_alive;
  184 + /**
  185 + * uri parser
  186 + */
  187 + SrsHttpUri* _uri;
  188 + /**
  189 + * use a buffer to read and send ts file.
  190 + */
  191 + // TODO: FIXME: remove it.
  192 + char* _http_ts_send_buffer;
  193 + // http headers
  194 + std::vector<SrsHttpHeaderField> _headers;
  195 + // the query map
  196 + std::map<std::string, std::string> _query;
  197 + // the transport connection, can be NULL.
  198 + SrsConnection* conn;
  199 +public:
  200 + SrsHttpMessage(SrsStSocket* io, SrsConnection* c);
  201 + virtual ~SrsHttpMessage();
  202 +public:
  203 + /**
  204 + * set the original messages, then update the message.
  205 + */
  206 + virtual int update(std::string url, http_parser* header,
  207 + SrsFastBuffer* body, std::vector<SrsHttpHeaderField>& headers
  208 + );
  209 +private:
  210 + virtual SrsConnection* connection();
  211 +public:
  212 + virtual u_int8_t method();
  213 + virtual u_int16_t status_code();
  214 + /**
  215 + * method helpers.
  216 + */
  217 + virtual std::string method_str();
  218 + virtual bool is_http_get();
  219 + virtual bool is_http_put();
  220 + virtual bool is_http_post();
  221 + virtual bool is_http_delete();
  222 + virtual bool is_http_options();
  223 + /**
  224 + * whether body is chunked encoding, for reader only.
  225 + */
  226 + virtual bool is_chunked();
  227 + /**
  228 + * whether should keep the connection alive.
  229 + */
  230 + virtual bool is_keep_alive();
  231 + /**
  232 + * the uri contains the host and path.
  233 + */
  234 + virtual std::string uri();
  235 + /**
  236 + * the url maybe the path.
  237 + */
  238 + virtual std::string url();
  239 + virtual std::string host();
  240 + virtual std::string path();
  241 + virtual std::string ext();
  242 +public:
  243 + /**
  244 + * read body to string.
  245 + * @remark for small http body.
  246 + */
  247 + virtual int body_read_all(std::string& body);
  248 + /**
  249 + * get the body reader, to read one by one.
  250 + * @remark when body is very large, or chunked, use this.
  251 + */
  252 + virtual ISrsHttpResponseReader* body_reader();
  253 + /**
  254 + * the content length, -1 for chunked or not set.
  255 + */
  256 + virtual int64_t content_length();
  257 + /**
  258 + * get the param in query string,
  259 + * for instance, query is "start=100&end=200",
  260 + * then query_get("start") is "100", and query_get("end") is "200"
  261 + */
  262 + virtual std::string query_get(std::string key);
  263 + /**
  264 + * get the headers.
  265 + */
  266 + virtual int request_header_count();
  267 + virtual std::string request_header_key_at(int index);
  268 + virtual std::string request_header_value_at(int index);
  269 + virtual std::string get_request_header(std::string name);
  270 +public:
  271 + /**
  272 + * convert the http message to a request.
  273 + * @remark user must free the return request.
  274 + */
  275 + virtual SrsRequest* to_request(std::string vhost);
  276 +};
  277 +
  278 +/**
  279 + * wrapper for http-parser,
  280 + * provides HTTP message originted service.
  281 + */
  282 +class SrsHttpParser
  283 +{
  284 +private:
  285 + http_parser_settings settings;
  286 + http_parser parser;
  287 + // the global parse buffer.
  288 + SrsFastBuffer* buffer;
  289 +private:
  290 + // http parse data, reset before parse message.
  291 + bool expect_field_name;
  292 + std::string field_name;
  293 + std::string field_value;
  294 + SrsHttpParseState state;
  295 + http_parser header;
  296 + std::string url;
  297 + std::vector<SrsHttpHeaderField> headers;
  298 + int header_parsed;
  299 +public:
  300 + SrsHttpParser();
  301 + virtual ~SrsHttpParser();
  302 +public:
  303 + /**
  304 + * initialize the http parser with specified type,
  305 + * one parser can only parse request or response messages.
  306 + */
  307 + virtual int initialize(enum http_parser_type type);
  308 + /**
  309 + * always parse a http message,
  310 + * that is, the *ppmsg always NOT-NULL when return success.
  311 + * or error and *ppmsg must be NULL.
  312 + * @remark, if success, *ppmsg always NOT-NULL, *ppmsg always is_complete().
  313 + */
  314 + virtual int parse_message(SrsStSocket* skt, SrsConnection* conn, ISrsHttpMessage** ppmsg);
  315 +private:
  316 + /**
  317 + * parse the HTTP message to member field: msg.
  318 + */
  319 + virtual int parse_message_imp(SrsStSocket* skt);
  320 +private:
  321 + static int on_message_begin(http_parser* parser);
  322 + static int on_headers_complete(http_parser* parser);
  323 + static int on_message_complete(http_parser* parser);
  324 + static int on_url(http_parser* parser, const char* at, size_t length);
  325 + static int on_header_field(http_parser* parser, const char* at, size_t length);
  326 + static int on_header_value(http_parser* parser, const char* at, size_t length);
  327 + static int on_body(http_parser* parser, const char* at, size_t length);
  328 +};
  329 +
  330 +/**
  331 + * used to resolve the http uri.
  332 + */
  333 +class SrsHttpUri
  334 +{
  335 +private:
  336 + std::string url;
  337 + std::string schema;
  338 + std::string host;
  339 + int port;
  340 + std::string path;
  341 + std::string query;
  342 +public:
  343 + SrsHttpUri();
  344 + virtual ~SrsHttpUri();
  345 +public:
  346 + /**
  347 + * initialize the http uri.
  348 + */
  349 + virtual int initialize(std::string _url);
  350 +public:
  351 + virtual const char* get_url();
  352 + virtual const char* get_schema();
  353 + virtual const char* get_host();
  354 + virtual int get_port();
  355 + virtual const char* get_path();
  356 + virtual const char* get_query();
  357 +private:
  358 + /**
  359 + * get the parsed url field.
  360 + * @return return empty string if not set.
  361 + */
  362 + virtual std::string get_uri_field(std::string uri, http_parser_url* hp_u, http_parser_url_fields field);
  363 +};
  364 +
  365 +#endif
  366 +
  367 +#ifdef SRS_AUTO_HTTP_SERVER
56 368
57 /** 369 /**
58 * the flv vod stream supports flv?start=offset-bytes. 370 * the flv vod stream supports flv?start=offset-bytes.
@@ -38,6 +38,7 @@ using namespace std; @@ -38,6 +38,7 @@ using namespace std;
38 #include <srs_core_autofree.hpp> 38 #include <srs_core_autofree.hpp>
39 #include <srs_app_config.hpp> 39 #include <srs_app_config.hpp>
40 #include <srs_kernel_utility.hpp> 40 #include <srs_kernel_utility.hpp>
  41 +#include <srs_app_http_conn.hpp>
41 42
42 #define SRS_HTTP_RESPONSE_OK SRS_XSTR(ERROR_SUCCESS) 43 #define SRS_HTTP_RESPONSE_OK SRS_XSTR(ERROR_SUCCESS)
43 44
@@ -47,6 +47,7 @@ using namespace std; @@ -47,6 +47,7 @@ using namespace std;
47 #include <srs_app_utility.hpp> 47 #include <srs_app_utility.hpp>
48 #include <srs_rtmp_amf0.hpp> 48 #include <srs_rtmp_amf0.hpp>
49 #include <srs_raw_avc.hpp> 49 #include <srs_raw_avc.hpp>
  50 +#include <srs_app_http_conn.hpp>
50 51
51 // pre-declare 52 // pre-declare
52 int proxy_hls2rtmp(std::string hls, std::string rtmp); 53 int proxy_hls2rtmp(std::string hls, std::string rtmp);