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