winlin

refine http framework, use http message

@@ -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()
@@ -57,70 +58,33 @@ int SrsHttpConn::do_cycle() @@ -57,70 +58,33 @@ int SrsHttpConn::do_cycle()
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
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 -  
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 78
110 - ssize_t nparsed = http_parser_execute(parser, settings, buf, nread);  
111 - srs_info("read_size=%d, nparsed=%d", (int)nread, (int)nparsed); 79 + // if SUCCESS, always NOT-NULL and completed message.
  80 + srs_assert(req);
  81 + srs_assert(req->is_complete());
112 82
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); 83 + // always free it in this scope.
  84 + SrsAutoFree(SrsHttpMessage, req, false);
117 85
118 - return process_request(skt);  
119 - }  
120 -  
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 }
@@ -128,11 +92,11 @@ int SrsHttpConn::parse_request(SrsSocket* skt, http_parser* parser, http_parser_ @@ -128,11 +92,11 @@ int SrsHttpConn::parse_request(SrsSocket* skt, http_parser* parser, http_parser_
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 /**