正在显示
9 个修改的文件
包含
948 行增加
和
847 行删除
| @@ -427,7 +427,7 @@ MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_socke | @@ -427,7 +427,7 @@ MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_socke | ||
| 427 | "srs_app_codec" "srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder" | 427 | "srs_app_codec" "srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder" |
| 428 | "srs_app_http" "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" | 428 | "srs_app_http" "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" |
| 429 | "srs_app_config" "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" | 429 | "srs_app_config" "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" |
| 430 | - "srs_app_http_conn") | 430 | + "srs_app_http_conn" "srs_app_http_hooks") |
| 431 | APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh | 431 | APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh |
| 432 | APP_OBJS="${MODULE_OBJS[@]}" | 432 | APP_OBJS="${MODULE_OBJS[@]}" |
| 433 | # | 433 | # |
| @@ -23,26 +23,46 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -23,26 +23,46 @@ 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_HTTP_CALLBACK | ||
| 27 | - | ||
| 28 | -#include <sstream> | ||
| 29 | -using namespace std; | 26 | +#ifdef SRS_HTTP_PARSER |
| 30 | 27 | ||
| 31 | #include <stdlib.h> | 28 | #include <stdlib.h> |
| 32 | -#include <sys/socket.h> | ||
| 33 | -#include <netinet/in.h> | ||
| 34 | -#include <arpa/inet.h> | ||
| 35 | 29 | ||
| 36 | #include <srs_kernel_error.hpp> | 30 | #include <srs_kernel_error.hpp> |
| 37 | -#include <srs_protocol_rtmp.hpp> | ||
| 38 | #include <srs_kernel_log.hpp> | 31 | #include <srs_kernel_log.hpp> |
| 39 | #include <srs_app_socket.hpp> | 32 | #include <srs_app_socket.hpp> |
| 40 | 33 | ||
| 41 | #define SRS_DEFAULT_HTTP_PORT 80 | 34 | #define SRS_DEFAULT_HTTP_PORT 80 |
| 42 | -#define SRS_HTTP_RESPONSE_OK "0" | ||
| 43 | 35 | ||
| 44 | -#define SRS_HTTP_HEADER_BUFFER 1024 | ||
| 45 | -#define SRS_HTTP_BODY_BUFFER 32 * 1024 | 36 | +SrsHttpMessage::SrsHttpMessage() |
| 37 | +{ | ||
| 38 | + body = new SrsBuffer(); | ||
| 39 | + state = SrsHttpParseStateInit; | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +SrsHttpMessage::~SrsHttpMessage() | ||
| 43 | +{ | ||
| 44 | + srs_freep(body); | ||
| 45 | +} | ||
| 46 | + | ||
| 47 | +void SrsHttpMessage::reset() | ||
| 48 | +{ | ||
| 49 | + state = SrsHttpParseStateInit; | ||
| 50 | + body->clear(); | ||
| 51 | + url = ""; | ||
| 52 | +} | ||
| 53 | + | ||
| 54 | +bool SrsHttpMessage::is_complete() | ||
| 55 | +{ | ||
| 56 | + return state == SrsHttpParseStateComplete; | ||
| 57 | +} | ||
| 58 | + | ||
| 59 | +SrsHttpParser::SrsHttpParser() | ||
| 60 | +{ | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | +SrsHttpParser::~SrsHttpParser() | ||
| 64 | +{ | ||
| 65 | +} | ||
| 46 | 66 | ||
| 47 | SrsHttpUri::SrsHttpUri() | 67 | SrsHttpUri::SrsHttpUri() |
| 48 | { | 68 | { |
| @@ -130,692 +150,4 @@ std::string SrsHttpUri::get_uri_field(std::string uri, http_parser_url* hp_u, ht | @@ -130,692 +150,4 @@ std::string SrsHttpUri::get_uri_field(std::string uri, http_parser_url* hp_u, ht | ||
| 130 | return uri.substr(offset, len); | 150 | return uri.substr(offset, len); |
| 131 | } | 151 | } |
| 132 | 152 | ||
| 133 | -SrsHttpClient::SrsHttpClient() | ||
| 134 | -{ | ||
| 135 | - connected = false; | ||
| 136 | - stfd = NULL; | ||
| 137 | -} | ||
| 138 | - | ||
| 139 | -SrsHttpClient::~SrsHttpClient() | ||
| 140 | -{ | ||
| 141 | - disconnect(); | ||
| 142 | -} | ||
| 143 | - | ||
| 144 | -int SrsHttpClient::post(SrsHttpUri* uri, std::string req, std::string& res) | ||
| 145 | -{ | ||
| 146 | - int ret = ERROR_SUCCESS; | ||
| 147 | - | ||
| 148 | - if ((ret = connect(uri)) != ERROR_SUCCESS) { | ||
| 149 | - srs_error("http connect server failed. ret=%d", ret); | ||
| 150 | - return ret; | ||
| 151 | - } | ||
| 152 | - | ||
| 153 | - // send POST request to uri | ||
| 154 | - // POST %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d\r\n\r\n%s | ||
| 155 | - std::stringstream ss; | ||
| 156 | - ss << "POST " << uri->get_path() << " " | ||
| 157 | - << "HTTP/1.1" << __CRLF | ||
| 158 | - << "Host: " << uri->get_host() << __CRLF | ||
| 159 | - << "Connection: Keep-Alive" << __CRLF | ||
| 160 | - << "Content-Length: " << std::dec << req.length() << __CRLF | ||
| 161 | - << "User-Agent: " << RTMP_SIG_SRS_NAME << RTMP_SIG_SRS_VERSION << __CRLF | ||
| 162 | - << "Content-Type: text/html" << __CRLF | ||
| 163 | - << __CRLF | ||
| 164 | - << req; | ||
| 165 | - | ||
| 166 | - SrsSocket skt(stfd); | ||
| 167 | - | ||
| 168 | - std::string data = ss.str(); | ||
| 169 | - ssize_t nwrite; | ||
| 170 | - if ((ret = skt.write(data.c_str(), data.length(), &nwrite)) != ERROR_SUCCESS) { | ||
| 171 | - // disconnect when error. | ||
| 172 | - disconnect(); | ||
| 173 | - | ||
| 174 | - srs_error("write http post failed. ret=%d", ret); | ||
| 175 | - return ret; | ||
| 176 | - } | ||
| 177 | - | ||
| 178 | - if ((ret = parse_response(uri, &skt, &res)) != ERROR_SUCCESS) { | ||
| 179 | - srs_error("parse http post response failed. ret=%d", ret); | ||
| 180 | - return ret; | ||
| 181 | - } | ||
| 182 | - srs_info("parse http post response success."); | ||
| 183 | - | ||
| 184 | - return ret; | ||
| 185 | -} | ||
| 186 | - | ||
| 187 | -void SrsHttpClient::disconnect() | ||
| 188 | -{ | ||
| 189 | - connected = false; | ||
| 190 | - | ||
| 191 | - srs_close_stfd(stfd); | ||
| 192 | -} | ||
| 193 | - | ||
| 194 | -int SrsHttpClient::connect(SrsHttpUri* uri) | ||
| 195 | -{ | ||
| 196 | - int ret = ERROR_SUCCESS; | ||
| 197 | - | ||
| 198 | - if (connected) { | ||
| 199 | - return ret; | ||
| 200 | - } | ||
| 201 | - | ||
| 202 | - disconnect(); | ||
| 203 | - | ||
| 204 | - std::string ip = srs_dns_resolve(uri->get_host()); | ||
| 205 | - if (ip.empty()) { | ||
| 206 | - ret = ERROR_SYSTEM_IP_INVALID; | ||
| 207 | - srs_error("dns resolve server error, ip empty. ret=%d", ret); | ||
| 208 | - return ret; | ||
| 209 | - } | ||
| 210 | - | ||
| 211 | - int sock = socket(AF_INET, SOCK_STREAM, 0); | ||
| 212 | - if(sock == -1){ | ||
| 213 | - ret = ERROR_SOCKET_CREATE; | ||
| 214 | - srs_error("create socket error. ret=%d", ret); | ||
| 215 | - return ret; | ||
| 216 | - } | ||
| 217 | - | ||
| 218 | - stfd = st_netfd_open_socket(sock); | ||
| 219 | - if(stfd == NULL){ | ||
| 220 | - ret = ERROR_ST_OPEN_SOCKET; | ||
| 221 | - srs_error("st_netfd_open_socket failed. ret=%d", ret); | ||
| 222 | - return ret; | ||
| 223 | - } | ||
| 224 | - | ||
| 225 | - sockaddr_in addr; | ||
| 226 | - addr.sin_family = AF_INET; | ||
| 227 | - addr.sin_port = htons(uri->get_port()); | ||
| 228 | - addr.sin_addr.s_addr = inet_addr(ip.c_str()); | ||
| 229 | - | ||
| 230 | - if (st_connect(stfd, (const struct sockaddr*)&addr, sizeof(sockaddr_in), ST_UTIME_NO_TIMEOUT) == -1){ | ||
| 231 | - ret = ERROR_ST_CONNECT; | ||
| 232 | - srs_error("connect to server error. " | ||
| 233 | - "ip=%s, port=%d, ret=%d", ip.c_str(), uri->get_port(), ret); | ||
| 234 | - return ret; | ||
| 235 | - } | ||
| 236 | - srs_info("connect to server success. " | ||
| 237 | - "http url=%s, server=%s, ip=%s, port=%d", | ||
| 238 | - uri->get_url(), uri->get_host(), ip.c_str(), uri->get_port()); | ||
| 239 | - | ||
| 240 | - connected = true; | ||
| 241 | - | ||
| 242 | - return ret; | ||
| 243 | -} | ||
| 244 | - | ||
| 245 | -int SrsHttpClient::parse_response(SrsHttpUri* uri, SrsSocket* skt, std::string* response) | ||
| 246 | -{ | ||
| 247 | - int ret = ERROR_SUCCESS; | ||
| 248 | - | ||
| 249 | - int body_received = 0; | ||
| 250 | - if ((ret = parse_response_header(skt, response, body_received)) != ERROR_SUCCESS) { | ||
| 251 | - srs_error("parse response header failed. ret=%d", ret); | ||
| 252 | - return ret; | ||
| 253 | - } | ||
| 254 | - | ||
| 255 | - if ((ret = parse_response_body(uri, skt, response, body_received)) != ERROR_SUCCESS) { | ||
| 256 | - srs_error("parse response body failed. ret=%d", ret); | ||
| 257 | - return ret; | ||
| 258 | - } | ||
| 259 | - | ||
| 260 | - srs_info("url %s download, body size=%"PRId64, uri->get_url(), http_header.content_length); | ||
| 261 | - | ||
| 262 | - return ret; | ||
| 263 | -} | ||
| 264 | - | ||
| 265 | -int SrsHttpClient::parse_response_header(SrsSocket* skt, std::string* response, int& body_received) | ||
| 266 | -{ | ||
| 267 | - int ret = ERROR_SUCCESS; | ||
| 268 | - | ||
| 269 | - http_parser_settings settings; | ||
| 270 | - | ||
| 271 | - memset(&settings, 0, sizeof(settings)); | ||
| 272 | - settings.on_headers_complete = on_headers_complete; | ||
| 273 | - | ||
| 274 | - http_parser parser; | ||
| 275 | - http_parser_init(&parser, HTTP_RESPONSE); | ||
| 276 | - // callback object ptr. | ||
| 277 | - parser.data = (void*)this; | ||
| 278 | - | ||
| 279 | - // reset response header. | ||
| 280 | - memset(&http_header, 0, sizeof(http_header)); | ||
| 281 | - | ||
| 282 | - // parser header. | ||
| 283 | - char buf[SRS_HTTP_HEADER_BUFFER]; | ||
| 284 | - for (;;) { | ||
| 285 | - ssize_t nread; | ||
| 286 | - if ((ret = skt->read(buf, (size_t)sizeof(buf), &nread)) != ERROR_SUCCESS) { | ||
| 287 | - srs_error("read body from server failed. ret=%d", ret); | ||
| 288 | - return ret; | ||
| 289 | - } | ||
| 290 | - | ||
| 291 | - ssize_t nparsed = http_parser_execute(&parser, &settings, buf, nread); | ||
| 292 | - srs_info("read_size=%d, nparsed=%d", (int)nread, (int)nparsed); | ||
| 293 | - | ||
| 294 | - // check header size. | ||
| 295 | - if (http_header.nread != 0) { | ||
| 296 | - body_received = nread - nparsed; | ||
| 297 | - | ||
| 298 | - srs_info("http header parsed, size=%d, content-length=%"PRId64", body-received=%d", | ||
| 299 | - http_header.nread, http_header.content_length, body_received); | ||
| 300 | - | ||
| 301 | - if(response != NULL && body_received > 0){ | ||
| 302 | - response->append(buf + nparsed, body_received); | ||
| 303 | - } | ||
| 304 | - | ||
| 305 | - return ret; | ||
| 306 | - } | ||
| 307 | - | ||
| 308 | - if (nparsed != nread) { | ||
| 309 | - ret = ERROR_HTTP_PARSE_HEADER; | ||
| 310 | - srs_error("parse response error, parsed(%d)!=read(%d), ret=%d", (int)nparsed, (int)nread, ret); | ||
| 311 | - return ret; | ||
| 312 | - } | ||
| 313 | - } | ||
| 314 | - | ||
| 315 | - return ret; | ||
| 316 | -} | ||
| 317 | - | ||
| 318 | -int SrsHttpClient::parse_response_body(SrsHttpUri* uri, SrsSocket* skt, std::string* response, int body_received) | ||
| 319 | -{ | ||
| 320 | - int ret = ERROR_SUCCESS; | ||
| 321 | - | ||
| 322 | - srs_assert(uri != NULL); | ||
| 323 | - | ||
| 324 | - uint64_t body_left = http_header.content_length - body_received; | ||
| 325 | - | ||
| 326 | - if (body_left <= 0) { | ||
| 327 | - return ret; | ||
| 328 | - } | ||
| 329 | - | ||
| 330 | - if (response != NULL) { | ||
| 331 | - char buf[SRS_HTTP_BODY_BUFFER]; | ||
| 332 | - | ||
| 333 | - return parse_response_body_data( | ||
| 334 | - uri, skt, response, (size_t)body_left, | ||
| 335 | - (const void*)buf, (size_t)SRS_HTTP_BODY_BUFFER | ||
| 336 | - ); | ||
| 337 | - } else { | ||
| 338 | - // if ignore response, use shared fast memory. | ||
| 339 | - static char buf[SRS_HTTP_BODY_BUFFER]; | ||
| 340 | - | ||
| 341 | - return parse_response_body_data( | ||
| 342 | - uri, skt, response, (size_t)body_left, | ||
| 343 | - (const void*)buf, (size_t)SRS_HTTP_BODY_BUFFER | ||
| 344 | - ); | ||
| 345 | - } | ||
| 346 | - | ||
| 347 | - return ret; | ||
| 348 | -} | ||
| 349 | - | ||
| 350 | -int SrsHttpClient::parse_response_body_data(SrsHttpUri* uri, SrsSocket* skt, std::string* response, size_t body_left, const void* buf, size_t size) | ||
| 351 | -{ | ||
| 352 | - int ret = ERROR_SUCCESS; | ||
| 353 | - | ||
| 354 | - srs_assert(uri != NULL); | ||
| 355 | - | ||
| 356 | - while (body_left > 0) { | ||
| 357 | - ssize_t nread; | ||
| 358 | - int size_to_read = srs_min(size, body_left); | ||
| 359 | - if ((ret = skt->read(buf, size_to_read, &nread)) != ERROR_SUCCESS) { | ||
| 360 | - srs_error("read header from server failed. ret=%d", ret); | ||
| 361 | - return ret; | ||
| 362 | - } | ||
| 363 | - | ||
| 364 | - if (response != NULL && nread > 0) { | ||
| 365 | - response->append((char*)buf, nread); | ||
| 366 | - } | ||
| 367 | - | ||
| 368 | - body_left -= nread; | ||
| 369 | - srs_info("read url(%s) content partial %"PRId64"/%"PRId64"", | ||
| 370 | - uri->get_url(), http_header.content_length - body_left, http_header.content_length); | ||
| 371 | - } | ||
| 372 | - | ||
| 373 | - return ret; | ||
| 374 | -} | ||
| 375 | - | ||
| 376 | -int SrsHttpClient::on_headers_complete(http_parser* parser) | ||
| 377 | -{ | ||
| 378 | - SrsHttpClient* obj = (SrsHttpClient*)parser->data; | ||
| 379 | - obj->complete_header(parser); | ||
| 380 | - | ||
| 381 | - // see http_parser.c:1570, return 1 to skip body. | ||
| 382 | - return 1; | ||
| 383 | -} | ||
| 384 | - | ||
| 385 | -void SrsHttpClient::complete_header(http_parser* parser) | ||
| 386 | -{ | ||
| 387 | - // save the parser status when header parse completed. | ||
| 388 | - memcpy(&http_header, parser, sizeof(http_header)); | ||
| 389 | -} | ||
| 390 | - | ||
| 391 | -SrsHttpHooks::SrsHttpHooks() | ||
| 392 | -{ | ||
| 393 | -} | ||
| 394 | - | ||
| 395 | -SrsHttpHooks::~SrsHttpHooks() | ||
| 396 | -{ | ||
| 397 | -} | ||
| 398 | - | ||
| 399 | -int SrsHttpHooks::on_connect(std::string url, int client_id, std::string ip, SrsRequest* req) | ||
| 400 | -{ | ||
| 401 | - int ret = ERROR_SUCCESS; | ||
| 402 | - | ||
| 403 | - SrsHttpUri uri; | ||
| 404 | - if ((ret = uri.initialize(url)) != ERROR_SUCCESS) { | ||
| 405 | - srs_error("http uri parse on_connect url failed. " | ||
| 406 | - "client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret); | ||
| 407 | - return ret; | ||
| 408 | - } | ||
| 409 | - | ||
| 410 | - /** | ||
| 411 | - { | ||
| 412 | - "action": "on_connect", | ||
| 413 | - "client_id": 1985, | ||
| 414 | - "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live", | ||
| 415 | - "pageUrl": "http://www.test.com/live.html" | ||
| 416 | - } | ||
| 417 | - */ | ||
| 418 | - std::stringstream ss; | ||
| 419 | - ss << "{" | ||
| 420 | - // action | ||
| 421 | - << '"' << "action" << '"' << ':' | ||
| 422 | - << '"' << "on_connect" << '"' | ||
| 423 | - << ',' | ||
| 424 | - // client_id | ||
| 425 | - << '"' << "client_id" << '"' << ':' | ||
| 426 | - << std::dec << client_id | ||
| 427 | - << ',' | ||
| 428 | - // ip | ||
| 429 | - << '"' << "ip" << '"' << ':' | ||
| 430 | - << '"' << ip << '"' | ||
| 431 | - << ',' | ||
| 432 | - // vhost | ||
| 433 | - << '"' << "vhost" << '"' << ':' | ||
| 434 | - << '"' << req->vhost << '"' | ||
| 435 | - << ',' | ||
| 436 | - // app | ||
| 437 | - << '"' << "app" << '"' << ':' | ||
| 438 | - << '"' << req->app << '"' | ||
| 439 | - << ',' | ||
| 440 | - // pageUrl | ||
| 441 | - << '"' << "pageUrl" << '"' << ':' | ||
| 442 | - << '"' << req->pageUrl << '"' | ||
| 443 | - //<< ',' | ||
| 444 | - << "}"; | ||
| 445 | - std::string data = ss.str(); | ||
| 446 | - std::string res; | ||
| 447 | - | ||
| 448 | - SrsHttpClient http; | ||
| 449 | - if ((ret = http.post(&uri, data, res)) != ERROR_SUCCESS) { | ||
| 450 | - srs_error("http post on_connect uri failed. " | ||
| 451 | - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 452 | - client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 453 | - return ret; | ||
| 454 | - } | ||
| 455 | - | ||
| 456 | - if (res.empty() || res != SRS_HTTP_RESPONSE_OK) { | ||
| 457 | - ret = ERROR_HTTP_DATA_INVLIAD; | ||
| 458 | - srs_error("http hook on_connect validate failed. " | ||
| 459 | - "client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret); | ||
| 460 | - return ret; | ||
| 461 | - } | ||
| 462 | - | ||
| 463 | - srs_trace("http hook on_connect success. " | ||
| 464 | - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 465 | - client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 466 | - | ||
| 467 | - return ret; | ||
| 468 | -} | ||
| 469 | - | ||
| 470 | -void SrsHttpHooks::on_close(std::string url, int client_id, std::string ip, SrsRequest* req) | ||
| 471 | -{ | ||
| 472 | - int ret = ERROR_SUCCESS; | ||
| 473 | - | ||
| 474 | - SrsHttpUri uri; | ||
| 475 | - if ((ret = uri.initialize(url)) != ERROR_SUCCESS) { | ||
| 476 | - srs_warn("http uri parse on_close url failed, ignored. " | ||
| 477 | - "client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret); | ||
| 478 | - return; | ||
| 479 | - } | ||
| 480 | - | ||
| 481 | - /** | ||
| 482 | - { | ||
| 483 | - "action": "on_close", | ||
| 484 | - "client_id": 1985, | ||
| 485 | - "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live", | ||
| 486 | - "stream": "livestream" | ||
| 487 | - } | ||
| 488 | - */ | ||
| 489 | - std::stringstream ss; | ||
| 490 | - ss << "{" | ||
| 491 | - // action | ||
| 492 | - << '"' << "action" << '"' << ':' | ||
| 493 | - << '"' << "on_close" << '"' | ||
| 494 | - << ',' | ||
| 495 | - // client_id | ||
| 496 | - << '"' << "client_id" << '"' << ':' | ||
| 497 | - << std::dec << client_id | ||
| 498 | - << ',' | ||
| 499 | - // ip | ||
| 500 | - << '"' << "ip" << '"' << ':' | ||
| 501 | - << '"' << ip << '"' | ||
| 502 | - << ',' | ||
| 503 | - // vhost | ||
| 504 | - << '"' << "vhost" << '"' << ':' | ||
| 505 | - << '"' << req->vhost << '"' | ||
| 506 | - << ',' | ||
| 507 | - // app | ||
| 508 | - << '"' << "app" << '"' << ':' | ||
| 509 | - << '"' << req->app << '"' | ||
| 510 | - //<< ',' | ||
| 511 | - << "}"; | ||
| 512 | - std::string data = ss.str(); | ||
| 513 | - std::string res; | ||
| 514 | - | ||
| 515 | - SrsHttpClient http; | ||
| 516 | - if ((ret = http.post(&uri, data, res)) != ERROR_SUCCESS) { | ||
| 517 | - srs_warn("http post on_close uri failed, ignored. " | ||
| 518 | - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 519 | - client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 520 | - return; | ||
| 521 | - } | ||
| 522 | - | ||
| 523 | - if (res.empty() || res != SRS_HTTP_RESPONSE_OK) { | ||
| 524 | - ret = ERROR_HTTP_DATA_INVLIAD; | ||
| 525 | - srs_warn("http hook on_close validate failed, ignored. " | ||
| 526 | - "client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret); | ||
| 527 | - return; | ||
| 528 | - } | ||
| 529 | - | ||
| 530 | - srs_trace("http hook on_close success. " | ||
| 531 | - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 532 | - client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 533 | - | ||
| 534 | - return; | ||
| 535 | -} | ||
| 536 | - | ||
| 537 | -int SrsHttpHooks::on_publish(std::string url, int client_id, std::string ip, SrsRequest* req) | ||
| 538 | -{ | ||
| 539 | - int ret = ERROR_SUCCESS; | ||
| 540 | - | ||
| 541 | - SrsHttpUri uri; | ||
| 542 | - if ((ret = uri.initialize(url)) != ERROR_SUCCESS) { | ||
| 543 | - srs_error("http uri parse on_publish url failed. " | ||
| 544 | - "client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret); | ||
| 545 | - return ret; | ||
| 546 | - } | ||
| 547 | - | ||
| 548 | - /** | ||
| 549 | - { | ||
| 550 | - "action": "on_publish", | ||
| 551 | - "client_id": 1985, | ||
| 552 | - "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live", | ||
| 553 | - "stream": "livestream" | ||
| 554 | - } | ||
| 555 | - */ | ||
| 556 | - std::stringstream ss; | ||
| 557 | - ss << "{" | ||
| 558 | - // action | ||
| 559 | - << '"' << "action" << '"' << ':' | ||
| 560 | - << '"' << "on_publish" << '"' | ||
| 561 | - << ',' | ||
| 562 | - // client_id | ||
| 563 | - << '"' << "client_id" << '"' << ':' | ||
| 564 | - << std::dec << client_id | ||
| 565 | - << ',' | ||
| 566 | - // ip | ||
| 567 | - << '"' << "ip" << '"' << ':' | ||
| 568 | - << '"' << ip << '"' | ||
| 569 | - << ',' | ||
| 570 | - // vhost | ||
| 571 | - << '"' << "vhost" << '"' << ':' | ||
| 572 | - << '"' << req->vhost << '"' | ||
| 573 | - << ',' | ||
| 574 | - // app | ||
| 575 | - << '"' << "app" << '"' << ':' | ||
| 576 | - << '"' << req->app << '"' | ||
| 577 | - << ',' | ||
| 578 | - // stream | ||
| 579 | - << '"' << "stream" << '"' << ':' | ||
| 580 | - << '"' << req->stream << '"' | ||
| 581 | - //<< ',' | ||
| 582 | - << "}"; | ||
| 583 | - std::string data = ss.str(); | ||
| 584 | - std::string res; | ||
| 585 | - | ||
| 586 | - SrsHttpClient http; | ||
| 587 | - if ((ret = http.post(&uri, data, res)) != ERROR_SUCCESS) { | ||
| 588 | - srs_error("http post on_publish uri failed. " | ||
| 589 | - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 590 | - client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 591 | - return ret; | ||
| 592 | - } | ||
| 593 | - | ||
| 594 | - if (res.empty() || res != SRS_HTTP_RESPONSE_OK) { | ||
| 595 | - ret = ERROR_HTTP_DATA_INVLIAD; | ||
| 596 | - srs_error("http hook on_publish validate failed. " | ||
| 597 | - "client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret); | ||
| 598 | - return ret; | ||
| 599 | - } | ||
| 600 | - | ||
| 601 | - srs_trace("http hook on_publish success. " | ||
| 602 | - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 603 | - client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 604 | - | ||
| 605 | - return ret; | ||
| 606 | -} | ||
| 607 | - | ||
| 608 | -void SrsHttpHooks::on_unpublish(std::string url, int client_id, std::string ip, SrsRequest* req) | ||
| 609 | -{ | ||
| 610 | - int ret = ERROR_SUCCESS; | ||
| 611 | - | ||
| 612 | - SrsHttpUri uri; | ||
| 613 | - if ((ret = uri.initialize(url)) != ERROR_SUCCESS) { | ||
| 614 | - srs_warn("http uri parse on_unpublish url failed, ignored. " | ||
| 615 | - "client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret); | ||
| 616 | - return; | ||
| 617 | - } | ||
| 618 | - | ||
| 619 | - /** | ||
| 620 | - { | ||
| 621 | - "action": "on_unpublish", | ||
| 622 | - "client_id": 1985, | ||
| 623 | - "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live", | ||
| 624 | - "stream": "livestream" | ||
| 625 | - } | ||
| 626 | - */ | ||
| 627 | - std::stringstream ss; | ||
| 628 | - ss << "{" | ||
| 629 | - // action | ||
| 630 | - << '"' << "action" << '"' << ':' | ||
| 631 | - << '"' << "on_unpublish" << '"' | ||
| 632 | - << ',' | ||
| 633 | - // client_id | ||
| 634 | - << '"' << "client_id" << '"' << ':' | ||
| 635 | - << std::dec << client_id | ||
| 636 | - << ',' | ||
| 637 | - // ip | ||
| 638 | - << '"' << "ip" << '"' << ':' | ||
| 639 | - << '"' << ip << '"' | ||
| 640 | - << ',' | ||
| 641 | - // vhost | ||
| 642 | - << '"' << "vhost" << '"' << ':' | ||
| 643 | - << '"' << req->vhost << '"' | ||
| 644 | - << ',' | ||
| 645 | - // app | ||
| 646 | - << '"' << "app" << '"' << ':' | ||
| 647 | - << '"' << req->app << '"' | ||
| 648 | - << ',' | ||
| 649 | - // stream | ||
| 650 | - << '"' << "stream" << '"' << ':' | ||
| 651 | - << '"' << req->stream << '"' | ||
| 652 | - //<< ',' | ||
| 653 | - << "}"; | ||
| 654 | - std::string data = ss.str(); | ||
| 655 | - std::string res; | ||
| 656 | - | ||
| 657 | - SrsHttpClient http; | ||
| 658 | - if ((ret = http.post(&uri, data, res)) != ERROR_SUCCESS) { | ||
| 659 | - srs_warn("http post on_unpublish uri failed, ignored. " | ||
| 660 | - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 661 | - client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 662 | - return; | ||
| 663 | - } | ||
| 664 | - | ||
| 665 | - if (res.empty() || res != SRS_HTTP_RESPONSE_OK) { | ||
| 666 | - ret = ERROR_HTTP_DATA_INVLIAD; | ||
| 667 | - srs_warn("http hook on_unpublish validate failed, ignored. " | ||
| 668 | - "client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret); | ||
| 669 | - return; | ||
| 670 | - } | ||
| 671 | - | ||
| 672 | - srs_trace("http hook on_unpublish success. " | ||
| 673 | - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 674 | - client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 675 | - | ||
| 676 | - return; | ||
| 677 | -} | ||
| 678 | - | ||
| 679 | -int SrsHttpHooks::on_play(std::string url, int client_id, std::string ip, SrsRequest* req) | ||
| 680 | -{ | ||
| 681 | - int ret = ERROR_SUCCESS; | ||
| 682 | - | ||
| 683 | - SrsHttpUri uri; | ||
| 684 | - if ((ret = uri.initialize(url)) != ERROR_SUCCESS) { | ||
| 685 | - srs_error("http uri parse on_play url failed. " | ||
| 686 | - "client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret); | ||
| 687 | - return ret; | ||
| 688 | - } | ||
| 689 | - | ||
| 690 | - /** | ||
| 691 | - { | ||
| 692 | - "action": "on_play", | ||
| 693 | - "client_id": 1985, | ||
| 694 | - "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live", | ||
| 695 | - "stream": "livestream" | ||
| 696 | - } | ||
| 697 | - */ | ||
| 698 | - std::stringstream ss; | ||
| 699 | - ss << "{" | ||
| 700 | - // action | ||
| 701 | - << '"' << "action" << '"' << ':' | ||
| 702 | - << '"' << "on_play" << '"' | ||
| 703 | - << ',' | ||
| 704 | - // client_id | ||
| 705 | - << '"' << "client_id" << '"' << ':' | ||
| 706 | - << std::dec << client_id | ||
| 707 | - << ',' | ||
| 708 | - // ip | ||
| 709 | - << '"' << "ip" << '"' << ':' | ||
| 710 | - << '"' << ip << '"' | ||
| 711 | - << ',' | ||
| 712 | - // vhost | ||
| 713 | - << '"' << "vhost" << '"' << ':' | ||
| 714 | - << '"' << req->vhost << '"' | ||
| 715 | - << ',' | ||
| 716 | - // app | ||
| 717 | - << '"' << "app" << '"' << ':' | ||
| 718 | - << '"' << req->app << '"' | ||
| 719 | - << ',' | ||
| 720 | - // stream | ||
| 721 | - << '"' << "stream" << '"' << ':' | ||
| 722 | - << '"' << req->stream << '"' | ||
| 723 | - //<< ',' | ||
| 724 | - << "}"; | ||
| 725 | - std::string data = ss.str(); | ||
| 726 | - std::string res; | ||
| 727 | - | ||
| 728 | - SrsHttpClient http; | ||
| 729 | - if ((ret = http.post(&uri, data, res)) != ERROR_SUCCESS) { | ||
| 730 | - srs_error("http post on_play uri failed. " | ||
| 731 | - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 732 | - client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 733 | - return ret; | ||
| 734 | - } | ||
| 735 | - | ||
| 736 | - if (res.empty() || res != SRS_HTTP_RESPONSE_OK) { | ||
| 737 | - ret = ERROR_HTTP_DATA_INVLIAD; | ||
| 738 | - srs_error("http hook on_play validate failed. " | ||
| 739 | - "client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret); | ||
| 740 | - return ret; | ||
| 741 | - } | ||
| 742 | - | ||
| 743 | - srs_trace("http hook on_play success. " | ||
| 744 | - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 745 | - client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 746 | - | ||
| 747 | - return ret; | ||
| 748 | -} | ||
| 749 | - | ||
| 750 | -void SrsHttpHooks::on_stop(std::string url, int client_id, std::string ip, SrsRequest* req) | ||
| 751 | -{ | ||
| 752 | - int ret = ERROR_SUCCESS; | ||
| 753 | - | ||
| 754 | - SrsHttpUri uri; | ||
| 755 | - if ((ret = uri.initialize(url)) != ERROR_SUCCESS) { | ||
| 756 | - srs_warn("http uri parse on_stop url failed, ignored. " | ||
| 757 | - "client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret); | ||
| 758 | - return; | ||
| 759 | - } | ||
| 760 | - | ||
| 761 | - /** | ||
| 762 | - { | ||
| 763 | - "action": "on_stop", | ||
| 764 | - "client_id": 1985, | ||
| 765 | - "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live", | ||
| 766 | - "stream": "livestream" | ||
| 767 | - } | ||
| 768 | - */ | ||
| 769 | - std::stringstream ss; | ||
| 770 | - ss << "{" | ||
| 771 | - // action | ||
| 772 | - << '"' << "action" << '"' << ':' | ||
| 773 | - << '"' << "on_stop" << '"' | ||
| 774 | - << ',' | ||
| 775 | - // client_id | ||
| 776 | - << '"' << "client_id" << '"' << ':' | ||
| 777 | - << std::dec << client_id | ||
| 778 | - << ',' | ||
| 779 | - // ip | ||
| 780 | - << '"' << "ip" << '"' << ':' | ||
| 781 | - << '"' << ip << '"' | ||
| 782 | - << ',' | ||
| 783 | - // vhost | ||
| 784 | - << '"' << "vhost" << '"' << ':' | ||
| 785 | - << '"' << req->vhost << '"' | ||
| 786 | - << ',' | ||
| 787 | - // app | ||
| 788 | - << '"' << "app" << '"' << ':' | ||
| 789 | - << '"' << req->app << '"' | ||
| 790 | - << ',' | ||
| 791 | - // stream | ||
| 792 | - << '"' << "stream" << '"' << ':' | ||
| 793 | - << '"' << req->stream << '"' | ||
| 794 | - //<< ',' | ||
| 795 | - << "}"; | ||
| 796 | - std::string data = ss.str(); | ||
| 797 | - std::string res; | ||
| 798 | - | ||
| 799 | - SrsHttpClient http; | ||
| 800 | - if ((ret = http.post(&uri, data, res)) != ERROR_SUCCESS) { | ||
| 801 | - srs_warn("http post on_stop uri failed, ignored. " | ||
| 802 | - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 803 | - client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 804 | - return; | ||
| 805 | - } | ||
| 806 | - | ||
| 807 | - if (res.empty() || res != SRS_HTTP_RESPONSE_OK) { | ||
| 808 | - ret = ERROR_HTTP_DATA_INVLIAD; | ||
| 809 | - srs_warn("http hook on_stop validate failed, ignored. " | ||
| 810 | - "client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret); | ||
| 811 | - return; | ||
| 812 | - } | ||
| 813 | - | ||
| 814 | - srs_trace("http hook on_stop success. " | ||
| 815 | - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 816 | - client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 817 | - | ||
| 818 | - return; | ||
| 819 | -} | ||
| 820 | - | ||
| 821 | #endif | 153 | #endif |
| @@ -29,9 +29,17 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -29,9 +29,17 @@ 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_HTTP_PARSER | ||
| 33 | + | ||
| 34 | +#include <string> | ||
| 35 | + | ||
| 36 | +#include <http_parser.h> | ||
| 37 | + | ||
| 32 | #include <srs_app_st.hpp> | 38 | #include <srs_app_st.hpp> |
| 33 | 39 | ||
| 34 | -#ifdef SRS_HTTP_PARSER | 40 | +class SrsBuffer; |
| 41 | +class SrsRequest; | ||
| 42 | +class SrsSocket; | ||
| 35 | 43 | ||
| 36 | // http specification | 44 | // http specification |
| 37 | // CR = <US-ASCII CR, carriage return (13)> | 45 | // CR = <US-ASCII CR, carriage return (13)> |
| @@ -49,16 +57,42 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -49,16 +57,42 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 49 | #define __CRLF "\r\n" // 0x0D0A | 57 | #define __CRLF "\r\n" // 0x0D0A |
| 50 | #define __CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A | 58 | #define __CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A |
| 51 | 59 | ||
| 52 | -#endif | ||
| 53 | - | ||
| 54 | -#ifdef SRS_HTTP_CALLBACK | ||
| 55 | - | ||
| 56 | -class SrsRequest; | ||
| 57 | -class SrsSocket; | 60 | +enum SrsHttpParseState { |
| 61 | + SrsHttpParseStateInit = 0, | ||
| 62 | + SrsHttpParseStateStart, | ||
| 63 | + SrsHttpParseStateComplete | ||
| 64 | +}; | ||
| 58 | 65 | ||
| 59 | -#include <string> | 66 | +/** |
| 67 | +* the http message, request or response. | ||
| 68 | +*/ | ||
| 69 | +class SrsHttpMessage | ||
| 70 | +{ | ||
| 71 | +public: | ||
| 72 | + std::string url; | ||
| 73 | + http_parser header; | ||
| 74 | + SrsBuffer* body; | ||
| 75 | + SrsHttpParseState state; | ||
| 76 | + | ||
| 77 | + SrsHttpMessage(); | ||
| 78 | + virtual ~SrsHttpMessage(); | ||
| 79 | + | ||
| 80 | + virtual void reset(); | ||
| 81 | + virtual bool is_complete(); | ||
| 82 | +}; | ||
| 60 | 83 | ||
| 61 | -#include <http_parser.h> | 84 | +/** |
| 85 | +* wrapper for http-parser, | ||
| 86 | +* provides HTTP message originted service. | ||
| 87 | +*/ | ||
| 88 | +class SrsHttpParser | ||
| 89 | +{ | ||
| 90 | +public: | ||
| 91 | + SrsHttpParser(); | ||
| 92 | + virtual ~SrsHttpParser(); | ||
| 93 | +public: | ||
| 94 | + //virtual int parse_requst(SrsHttpMessage** ppreq); | ||
| 95 | +}; | ||
| 62 | 96 | ||
| 63 | /** | 97 | /** |
| 64 | * used to resolve the http uri. | 98 | * used to resolve the http uri. |
| @@ -93,97 +127,6 @@ private: | @@ -93,97 +127,6 @@ private: | ||
| 93 | virtual std::string get_uri_field(std::string uri, http_parser_url* hp_u, http_parser_url_fields field); | 127 | virtual std::string get_uri_field(std::string uri, http_parser_url* hp_u, http_parser_url_fields field); |
| 94 | }; | 128 | }; |
| 95 | 129 | ||
| 96 | -/** | ||
| 97 | -* http client to GET/POST/PUT/DELETE uri | ||
| 98 | -*/ | ||
| 99 | -class SrsHttpClient | ||
| 100 | -{ | ||
| 101 | -private: | ||
| 102 | - bool connected; | ||
| 103 | - st_netfd_t stfd; | ||
| 104 | -private: | ||
| 105 | - http_parser http_header; | ||
| 106 | -public: | ||
| 107 | - SrsHttpClient(); | ||
| 108 | - virtual ~SrsHttpClient(); | ||
| 109 | -public: | ||
| 110 | - /** | ||
| 111 | - * to post data to the uri. | ||
| 112 | - * @param req the data post to uri. | ||
| 113 | - * @param res the response data from server. | ||
| 114 | - */ | ||
| 115 | - virtual int post(SrsHttpUri* uri, std::string req, std::string& res); | ||
| 116 | -private: | ||
| 117 | - virtual void disconnect(); | ||
| 118 | - virtual int connect(SrsHttpUri* uri); | ||
| 119 | -private: | ||
| 120 | - virtual int parse_response(SrsHttpUri* uri, SrsSocket* skt, std::string* response); | ||
| 121 | - virtual int parse_response_header(SrsSocket* skt, std::string* response, int& body_received); | ||
| 122 | - virtual int parse_response_body(SrsHttpUri* uri, SrsSocket* skt, std::string* response, int body_received); | ||
| 123 | - virtual int parse_response_body_data(SrsHttpUri* uri, SrsSocket* skt, std::string* response, size_t body_left, const void* buf, size_t size); | ||
| 124 | -private: | ||
| 125 | - static int on_headers_complete(http_parser* parser); | ||
| 126 | - virtual void complete_header(http_parser* parser); | ||
| 127 | -}; | ||
| 128 | - | ||
| 129 | -/** | ||
| 130 | -* the http hooks, http callback api, | ||
| 131 | -* for some event, such as on_connect, call | ||
| 132 | -* a http api(hooks). | ||
| 133 | -*/ | ||
| 134 | -class SrsHttpHooks | ||
| 135 | -{ | ||
| 136 | -public: | ||
| 137 | - SrsHttpHooks(); | ||
| 138 | - virtual ~SrsHttpHooks(); | ||
| 139 | -public: | ||
| 140 | - /** | ||
| 141 | - * on_connect hook, when client connect to srs. | ||
| 142 | - * @param client_id the id of client on server. | ||
| 143 | - * @param url the api server url, to valid the client. | ||
| 144 | - * ignore if empty. | ||
| 145 | - * @return valid failed or connect to the url failed. | ||
| 146 | - */ | ||
| 147 | - virtual int on_connect(std::string url, int client_id, std::string ip, SrsRequest* req); | ||
| 148 | - /** | ||
| 149 | - * on_close hook, when client disconnect to srs, where client is valid by on_connect. | ||
| 150 | - * @param client_id the id of client on server. | ||
| 151 | - * @param url the api server url, to process the event. | ||
| 152 | - * ignore if empty. | ||
| 153 | - */ | ||
| 154 | - virtual void on_close(std::string url, int client_id, std::string ip, SrsRequest* req); | ||
| 155 | - /** | ||
| 156 | - * on_publish hook, when client(encoder) start to publish stream | ||
| 157 | - * @param client_id the id of client on server. | ||
| 158 | - * @param url the api server url, to valid the client. | ||
| 159 | - * ignore if empty. | ||
| 160 | - * @return valid failed or connect to the url failed. | ||
| 161 | - */ | ||
| 162 | - virtual int on_publish(std::string url, int client_id, std::string ip, SrsRequest* req); | ||
| 163 | - /** | ||
| 164 | - * on_unpublish hook, when client(encoder) stop publish stream. | ||
| 165 | - * @param client_id the id of client on server. | ||
| 166 | - * @param url the api server url, to process the event. | ||
| 167 | - * ignore if empty. | ||
| 168 | - */ | ||
| 169 | - virtual void on_unpublish(std::string url, int client_id, std::string ip, SrsRequest* req); | ||
| 170 | - /** | ||
| 171 | - * on_play hook, when client start to play stream. | ||
| 172 | - * @param client_id the id of client on server. | ||
| 173 | - * @param url the api server url, to valid the client. | ||
| 174 | - * ignore if empty. | ||
| 175 | - * @return valid failed or connect to the url failed. | ||
| 176 | - */ | ||
| 177 | - virtual int on_play(std::string url, int client_id, std::string ip, SrsRequest* req); | ||
| 178 | - /** | ||
| 179 | - * on_stop hook, when client stop to play the stream. | ||
| 180 | - * @param client_id the id of client on server. | ||
| 181 | - * @param url the api server url, to process the event. | ||
| 182 | - * ignore if empty. | ||
| 183 | - */ | ||
| 184 | - virtual void on_stop(std::string url, int client_id, std::string ip, SrsRequest* req); | ||
| 185 | -}; | ||
| 186 | - | ||
| 187 | #endif | 130 | #endif |
| 188 | 131 | ||
| 189 | #endif | 132 | #endif |
| @@ -36,33 +36,10 @@ using namespace std; | @@ -36,33 +36,10 @@ using namespace std; | ||
| 36 | 36 | ||
| 37 | #define SRS_HTTP_HEADER_BUFFER 1024 | 37 | #define SRS_HTTP_HEADER_BUFFER 1024 |
| 38 | 38 | ||
| 39 | -SrsHttpRequest::SrsHttpRequest() | ||
| 40 | -{ | ||
| 41 | - body = new SrsBuffer(); | ||
| 42 | - state = SrsHttpParseStateInit; | ||
| 43 | -} | ||
| 44 | - | ||
| 45 | -SrsHttpRequest::~SrsHttpRequest() | ||
| 46 | -{ | ||
| 47 | - srs_freep(body); | ||
| 48 | -} | ||
| 49 | - | ||
| 50 | -void SrsHttpRequest::reset() | ||
| 51 | -{ | ||
| 52 | - state = SrsHttpParseStateInit; | ||
| 53 | - body->clear(); | ||
| 54 | - url = ""; | ||
| 55 | -} | ||
| 56 | - | ||
| 57 | -bool SrsHttpRequest::is_complete() | ||
| 58 | -{ | ||
| 59 | - return state == SrsHttpParseStateComplete; | ||
| 60 | -} | ||
| 61 | - | ||
| 62 | SrsHttpConn::SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd) | 39 | SrsHttpConn::SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd) |
| 63 | : SrsConnection(srs_server, client_stfd) | 40 | : SrsConnection(srs_server, client_stfd) |
| 64 | { | 41 | { |
| 65 | - req = new SrsHttpRequest(); | 42 | + req = new SrsHttpMessage(); |
| 66 | } | 43 | } |
| 67 | 44 | ||
| 68 | SrsHttpConn::~SrsHttpConn() | 45 | SrsHttpConn::~SrsHttpConn() |
| @@ -38,33 +38,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -38,33 +38,12 @@ 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 SrsBuffer; | ||
| 42 | - | ||
| 43 | -enum SrsHttpParseState { | ||
| 44 | - SrsHttpParseStateInit = 0, | ||
| 45 | - SrsHttpParseStateStart, | ||
| 46 | - SrsHttpParseStateComplete | ||
| 47 | -}; | ||
| 48 | - | ||
| 49 | -class SrsHttpRequest | ||
| 50 | -{ | ||
| 51 | -public: | ||
| 52 | - std::string url; | ||
| 53 | - http_parser header; | ||
| 54 | - SrsBuffer* body; | ||
| 55 | - SrsHttpParseState state; | ||
| 56 | - | ||
| 57 | - SrsHttpRequest(); | ||
| 58 | - virtual ~SrsHttpRequest(); | ||
| 59 | - | ||
| 60 | - virtual void reset(); | ||
| 61 | - virtual bool is_complete(); | ||
| 62 | -}; | 41 | +class SrsHttpMessage; |
| 63 | 42 | ||
| 64 | class SrsHttpConn : public SrsConnection | 43 | class SrsHttpConn : public SrsConnection |
| 65 | { | 44 | { |
| 66 | private: | 45 | private: |
| 67 | - SrsHttpRequest* req; | 46 | + SrsHttpMessage* req; |
| 68 | public: | 47 | public: |
| 69 | SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd); | 48 | SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd); |
| 70 | virtual ~SrsHttpConn(); | 49 | virtual ~SrsHttpConn(); |
trunk/src/app/srs_app_http_hooks.cpp
0 → 100644
| 1 | +/* | ||
| 2 | +The MIT License (MIT) | ||
| 3 | + | ||
| 4 | +Copyright (c) 2013-2014 winlin | ||
| 5 | + | ||
| 6 | +Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
| 7 | +this software and associated documentation files (the "Software"), to deal in | ||
| 8 | +the Software without restriction, including without limitation the rights to | ||
| 9 | +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
| 10 | +the Software, and to permit persons to whom the Software is furnished to do so, | ||
| 11 | +subject to the following conditions: | ||
| 12 | + | ||
| 13 | +The above copyright notice and this permission notice shall be included in all | ||
| 14 | +copies or substantial portions of the Software. | ||
| 15 | + | ||
| 16 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
| 18 | +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
| 19 | +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
| 20 | +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 21 | +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 22 | +*/ | ||
| 23 | + | ||
| 24 | +#include <srs_app_http_hooks.hpp> | ||
| 25 | + | ||
| 26 | +#ifdef SRS_HTTP_CALLBACK | ||
| 27 | + | ||
| 28 | +#include <sstream> | ||
| 29 | +using namespace std; | ||
| 30 | + | ||
| 31 | +#include <arpa/inet.h> | ||
| 32 | + | ||
| 33 | +#include <srs_kernel_error.hpp> | ||
| 34 | +#include <srs_protocol_rtmp.hpp> | ||
| 35 | +#include <srs_kernel_log.hpp> | ||
| 36 | +#include <srs_app_socket.hpp> | ||
| 37 | +#include <srs_app_http.hpp> | ||
| 38 | + | ||
| 39 | +#define SRS_HTTP_RESPONSE_OK "0" | ||
| 40 | + | ||
| 41 | +#define SRS_HTTP_HEADER_BUFFER 1024 | ||
| 42 | +#define SRS_HTTP_BODY_BUFFER 32 * 1024 | ||
| 43 | + | ||
| 44 | +SrsHttpClient::SrsHttpClient() | ||
| 45 | +{ | ||
| 46 | + connected = false; | ||
| 47 | + stfd = NULL; | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | +SrsHttpClient::~SrsHttpClient() | ||
| 51 | +{ | ||
| 52 | + disconnect(); | ||
| 53 | +} | ||
| 54 | + | ||
| 55 | +int SrsHttpClient::post(SrsHttpUri* uri, std::string req, std::string& res) | ||
| 56 | +{ | ||
| 57 | + int ret = ERROR_SUCCESS; | ||
| 58 | + | ||
| 59 | + if ((ret = connect(uri)) != ERROR_SUCCESS) { | ||
| 60 | + srs_error("http connect server failed. ret=%d", ret); | ||
| 61 | + return ret; | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + // send POST request to uri | ||
| 65 | + // POST %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d\r\n\r\n%s | ||
| 66 | + std::stringstream ss; | ||
| 67 | + ss << "POST " << uri->get_path() << " " | ||
| 68 | + << "HTTP/1.1" << __CRLF | ||
| 69 | + << "Host: " << uri->get_host() << __CRLF | ||
| 70 | + << "Connection: Keep-Alive" << __CRLF | ||
| 71 | + << "Content-Length: " << std::dec << req.length() << __CRLF | ||
| 72 | + << "User-Agent: " << RTMP_SIG_SRS_NAME << RTMP_SIG_SRS_VERSION << __CRLF | ||
| 73 | + << "Content-Type: text/html" << __CRLF | ||
| 74 | + << __CRLF | ||
| 75 | + << req; | ||
| 76 | + | ||
| 77 | + SrsSocket skt(stfd); | ||
| 78 | + | ||
| 79 | + std::string data = ss.str(); | ||
| 80 | + ssize_t nwrite; | ||
| 81 | + if ((ret = skt.write(data.c_str(), data.length(), &nwrite)) != ERROR_SUCCESS) { | ||
| 82 | + // disconnect when error. | ||
| 83 | + disconnect(); | ||
| 84 | + | ||
| 85 | + srs_error("write http post failed. ret=%d", ret); | ||
| 86 | + return ret; | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + if ((ret = parse_response(uri, &skt, &res)) != ERROR_SUCCESS) { | ||
| 90 | + srs_error("parse http post response failed. ret=%d", ret); | ||
| 91 | + return ret; | ||
| 92 | + } | ||
| 93 | + srs_info("parse http post response success."); | ||
| 94 | + | ||
| 95 | + return ret; | ||
| 96 | +} | ||
| 97 | + | ||
| 98 | +void SrsHttpClient::disconnect() | ||
| 99 | +{ | ||
| 100 | + connected = false; | ||
| 101 | + | ||
| 102 | + srs_close_stfd(stfd); | ||
| 103 | +} | ||
| 104 | + | ||
| 105 | +int SrsHttpClient::connect(SrsHttpUri* uri) | ||
| 106 | +{ | ||
| 107 | + int ret = ERROR_SUCCESS; | ||
| 108 | + | ||
| 109 | + if (connected) { | ||
| 110 | + return ret; | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + disconnect(); | ||
| 114 | + | ||
| 115 | + std::string ip = srs_dns_resolve(uri->get_host()); | ||
| 116 | + if (ip.empty()) { | ||
| 117 | + ret = ERROR_SYSTEM_IP_INVALID; | ||
| 118 | + srs_error("dns resolve server error, ip empty. ret=%d", ret); | ||
| 119 | + return ret; | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + int sock = socket(AF_INET, SOCK_STREAM, 0); | ||
| 123 | + if(sock == -1){ | ||
| 124 | + ret = ERROR_SOCKET_CREATE; | ||
| 125 | + srs_error("create socket error. ret=%d", ret); | ||
| 126 | + return ret; | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + stfd = st_netfd_open_socket(sock); | ||
| 130 | + if(stfd == NULL){ | ||
| 131 | + ret = ERROR_ST_OPEN_SOCKET; | ||
| 132 | + srs_error("st_netfd_open_socket failed. ret=%d", ret); | ||
| 133 | + return ret; | ||
| 134 | + } | ||
| 135 | + | ||
| 136 | + sockaddr_in addr; | ||
| 137 | + addr.sin_family = AF_INET; | ||
| 138 | + addr.sin_port = htons(uri->get_port()); | ||
| 139 | + addr.sin_addr.s_addr = inet_addr(ip.c_str()); | ||
| 140 | + | ||
| 141 | + if (st_connect(stfd, (const struct sockaddr*)&addr, sizeof(sockaddr_in), ST_UTIME_NO_TIMEOUT) == -1){ | ||
| 142 | + ret = ERROR_ST_CONNECT; | ||
| 143 | + srs_error("connect to server error. " | ||
| 144 | + "ip=%s, port=%d, ret=%d", ip.c_str(), uri->get_port(), ret); | ||
| 145 | + return ret; | ||
| 146 | + } | ||
| 147 | + srs_info("connect to server success. " | ||
| 148 | + "http url=%s, server=%s, ip=%s, port=%d", | ||
| 149 | + uri->get_url(), uri->get_host(), ip.c_str(), uri->get_port()); | ||
| 150 | + | ||
| 151 | + connected = true; | ||
| 152 | + | ||
| 153 | + return ret; | ||
| 154 | +} | ||
| 155 | + | ||
| 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() | ||
| 303 | +{ | ||
| 304 | +} | ||
| 305 | + | ||
| 306 | +SrsHttpHooks::~SrsHttpHooks() | ||
| 307 | +{ | ||
| 308 | +} | ||
| 309 | + | ||
| 310 | +int SrsHttpHooks::on_connect(std::string url, int client_id, std::string ip, SrsRequest* req) | ||
| 311 | +{ | ||
| 312 | + int ret = ERROR_SUCCESS; | ||
| 313 | + | ||
| 314 | + SrsHttpUri uri; | ||
| 315 | + if ((ret = uri.initialize(url)) != ERROR_SUCCESS) { | ||
| 316 | + srs_error("http uri parse on_connect url failed. " | ||
| 317 | + "client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret); | ||
| 318 | + return ret; | ||
| 319 | + } | ||
| 320 | + | ||
| 321 | + /** | ||
| 322 | + { | ||
| 323 | + "action": "on_connect", | ||
| 324 | + "client_id": 1985, | ||
| 325 | + "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live", | ||
| 326 | + "pageUrl": "http://www.test.com/live.html" | ||
| 327 | + } | ||
| 328 | + */ | ||
| 329 | + std::stringstream ss; | ||
| 330 | + ss << "{" | ||
| 331 | + // action | ||
| 332 | + << '"' << "action" << '"' << ':' | ||
| 333 | + << '"' << "on_connect" << '"' | ||
| 334 | + << ',' | ||
| 335 | + // client_id | ||
| 336 | + << '"' << "client_id" << '"' << ':' | ||
| 337 | + << std::dec << client_id | ||
| 338 | + << ',' | ||
| 339 | + // ip | ||
| 340 | + << '"' << "ip" << '"' << ':' | ||
| 341 | + << '"' << ip << '"' | ||
| 342 | + << ',' | ||
| 343 | + // vhost | ||
| 344 | + << '"' << "vhost" << '"' << ':' | ||
| 345 | + << '"' << req->vhost << '"' | ||
| 346 | + << ',' | ||
| 347 | + // app | ||
| 348 | + << '"' << "app" << '"' << ':' | ||
| 349 | + << '"' << req->app << '"' | ||
| 350 | + << ',' | ||
| 351 | + // pageUrl | ||
| 352 | + << '"' << "pageUrl" << '"' << ':' | ||
| 353 | + << '"' << req->pageUrl << '"' | ||
| 354 | + //<< ',' | ||
| 355 | + << "}"; | ||
| 356 | + std::string data = ss.str(); | ||
| 357 | + std::string res; | ||
| 358 | + | ||
| 359 | + SrsHttpClient http; | ||
| 360 | + if ((ret = http.post(&uri, data, res)) != ERROR_SUCCESS) { | ||
| 361 | + srs_error("http post on_connect uri failed. " | ||
| 362 | + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 363 | + client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 364 | + return ret; | ||
| 365 | + } | ||
| 366 | + | ||
| 367 | + if (res.empty() || res != SRS_HTTP_RESPONSE_OK) { | ||
| 368 | + ret = ERROR_HTTP_DATA_INVLIAD; | ||
| 369 | + srs_error("http hook on_connect validate failed. " | ||
| 370 | + "client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret); | ||
| 371 | + return ret; | ||
| 372 | + } | ||
| 373 | + | ||
| 374 | + srs_trace("http hook on_connect success. " | ||
| 375 | + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 376 | + client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 377 | + | ||
| 378 | + return ret; | ||
| 379 | +} | ||
| 380 | + | ||
| 381 | +void SrsHttpHooks::on_close(std::string url, int client_id, std::string ip, SrsRequest* req) | ||
| 382 | +{ | ||
| 383 | + int ret = ERROR_SUCCESS; | ||
| 384 | + | ||
| 385 | + SrsHttpUri uri; | ||
| 386 | + if ((ret = uri.initialize(url)) != ERROR_SUCCESS) { | ||
| 387 | + srs_warn("http uri parse on_close url failed, ignored. " | ||
| 388 | + "client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret); | ||
| 389 | + return; | ||
| 390 | + } | ||
| 391 | + | ||
| 392 | + /** | ||
| 393 | + { | ||
| 394 | + "action": "on_close", | ||
| 395 | + "client_id": 1985, | ||
| 396 | + "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live", | ||
| 397 | + "stream": "livestream" | ||
| 398 | + } | ||
| 399 | + */ | ||
| 400 | + std::stringstream ss; | ||
| 401 | + ss << "{" | ||
| 402 | + // action | ||
| 403 | + << '"' << "action" << '"' << ':' | ||
| 404 | + << '"' << "on_close" << '"' | ||
| 405 | + << ',' | ||
| 406 | + // client_id | ||
| 407 | + << '"' << "client_id" << '"' << ':' | ||
| 408 | + << std::dec << client_id | ||
| 409 | + << ',' | ||
| 410 | + // ip | ||
| 411 | + << '"' << "ip" << '"' << ':' | ||
| 412 | + << '"' << ip << '"' | ||
| 413 | + << ',' | ||
| 414 | + // vhost | ||
| 415 | + << '"' << "vhost" << '"' << ':' | ||
| 416 | + << '"' << req->vhost << '"' | ||
| 417 | + << ',' | ||
| 418 | + // app | ||
| 419 | + << '"' << "app" << '"' << ':' | ||
| 420 | + << '"' << req->app << '"' | ||
| 421 | + //<< ',' | ||
| 422 | + << "}"; | ||
| 423 | + std::string data = ss.str(); | ||
| 424 | + std::string res; | ||
| 425 | + | ||
| 426 | + SrsHttpClient http; | ||
| 427 | + if ((ret = http.post(&uri, data, res)) != ERROR_SUCCESS) { | ||
| 428 | + srs_warn("http post on_close uri failed, ignored. " | ||
| 429 | + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 430 | + client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 431 | + return; | ||
| 432 | + } | ||
| 433 | + | ||
| 434 | + if (res.empty() || res != SRS_HTTP_RESPONSE_OK) { | ||
| 435 | + ret = ERROR_HTTP_DATA_INVLIAD; | ||
| 436 | + srs_warn("http hook on_close validate failed, ignored. " | ||
| 437 | + "client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret); | ||
| 438 | + return; | ||
| 439 | + } | ||
| 440 | + | ||
| 441 | + srs_trace("http hook on_close success. " | ||
| 442 | + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 443 | + client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 444 | + | ||
| 445 | + return; | ||
| 446 | +} | ||
| 447 | + | ||
| 448 | +int SrsHttpHooks::on_publish(std::string url, int client_id, std::string ip, SrsRequest* req) | ||
| 449 | +{ | ||
| 450 | + int ret = ERROR_SUCCESS; | ||
| 451 | + | ||
| 452 | + SrsHttpUri uri; | ||
| 453 | + if ((ret = uri.initialize(url)) != ERROR_SUCCESS) { | ||
| 454 | + srs_error("http uri parse on_publish url failed. " | ||
| 455 | + "client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret); | ||
| 456 | + return ret; | ||
| 457 | + } | ||
| 458 | + | ||
| 459 | + /** | ||
| 460 | + { | ||
| 461 | + "action": "on_publish", | ||
| 462 | + "client_id": 1985, | ||
| 463 | + "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live", | ||
| 464 | + "stream": "livestream" | ||
| 465 | + } | ||
| 466 | + */ | ||
| 467 | + std::stringstream ss; | ||
| 468 | + ss << "{" | ||
| 469 | + // action | ||
| 470 | + << '"' << "action" << '"' << ':' | ||
| 471 | + << '"' << "on_publish" << '"' | ||
| 472 | + << ',' | ||
| 473 | + // client_id | ||
| 474 | + << '"' << "client_id" << '"' << ':' | ||
| 475 | + << std::dec << client_id | ||
| 476 | + << ',' | ||
| 477 | + // ip | ||
| 478 | + << '"' << "ip" << '"' << ':' | ||
| 479 | + << '"' << ip << '"' | ||
| 480 | + << ',' | ||
| 481 | + // vhost | ||
| 482 | + << '"' << "vhost" << '"' << ':' | ||
| 483 | + << '"' << req->vhost << '"' | ||
| 484 | + << ',' | ||
| 485 | + // app | ||
| 486 | + << '"' << "app" << '"' << ':' | ||
| 487 | + << '"' << req->app << '"' | ||
| 488 | + << ',' | ||
| 489 | + // stream | ||
| 490 | + << '"' << "stream" << '"' << ':' | ||
| 491 | + << '"' << req->stream << '"' | ||
| 492 | + //<< ',' | ||
| 493 | + << "}"; | ||
| 494 | + std::string data = ss.str(); | ||
| 495 | + std::string res; | ||
| 496 | + | ||
| 497 | + SrsHttpClient http; | ||
| 498 | + if ((ret = http.post(&uri, data, res)) != ERROR_SUCCESS) { | ||
| 499 | + srs_error("http post on_publish uri failed. " | ||
| 500 | + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 501 | + client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 502 | + return ret; | ||
| 503 | + } | ||
| 504 | + | ||
| 505 | + if (res.empty() || res != SRS_HTTP_RESPONSE_OK) { | ||
| 506 | + ret = ERROR_HTTP_DATA_INVLIAD; | ||
| 507 | + srs_error("http hook on_publish validate failed. " | ||
| 508 | + "client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret); | ||
| 509 | + return ret; | ||
| 510 | + } | ||
| 511 | + | ||
| 512 | + srs_trace("http hook on_publish success. " | ||
| 513 | + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 514 | + client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 515 | + | ||
| 516 | + return ret; | ||
| 517 | +} | ||
| 518 | + | ||
| 519 | +void SrsHttpHooks::on_unpublish(std::string url, int client_id, std::string ip, SrsRequest* req) | ||
| 520 | +{ | ||
| 521 | + int ret = ERROR_SUCCESS; | ||
| 522 | + | ||
| 523 | + SrsHttpUri uri; | ||
| 524 | + if ((ret = uri.initialize(url)) != ERROR_SUCCESS) { | ||
| 525 | + srs_warn("http uri parse on_unpublish url failed, ignored. " | ||
| 526 | + "client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret); | ||
| 527 | + return; | ||
| 528 | + } | ||
| 529 | + | ||
| 530 | + /** | ||
| 531 | + { | ||
| 532 | + "action": "on_unpublish", | ||
| 533 | + "client_id": 1985, | ||
| 534 | + "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live", | ||
| 535 | + "stream": "livestream" | ||
| 536 | + } | ||
| 537 | + */ | ||
| 538 | + std::stringstream ss; | ||
| 539 | + ss << "{" | ||
| 540 | + // action | ||
| 541 | + << '"' << "action" << '"' << ':' | ||
| 542 | + << '"' << "on_unpublish" << '"' | ||
| 543 | + << ',' | ||
| 544 | + // client_id | ||
| 545 | + << '"' << "client_id" << '"' << ':' | ||
| 546 | + << std::dec << client_id | ||
| 547 | + << ',' | ||
| 548 | + // ip | ||
| 549 | + << '"' << "ip" << '"' << ':' | ||
| 550 | + << '"' << ip << '"' | ||
| 551 | + << ',' | ||
| 552 | + // vhost | ||
| 553 | + << '"' << "vhost" << '"' << ':' | ||
| 554 | + << '"' << req->vhost << '"' | ||
| 555 | + << ',' | ||
| 556 | + // app | ||
| 557 | + << '"' << "app" << '"' << ':' | ||
| 558 | + << '"' << req->app << '"' | ||
| 559 | + << ',' | ||
| 560 | + // stream | ||
| 561 | + << '"' << "stream" << '"' << ':' | ||
| 562 | + << '"' << req->stream << '"' | ||
| 563 | + //<< ',' | ||
| 564 | + << "}"; | ||
| 565 | + std::string data = ss.str(); | ||
| 566 | + std::string res; | ||
| 567 | + | ||
| 568 | + SrsHttpClient http; | ||
| 569 | + if ((ret = http.post(&uri, data, res)) != ERROR_SUCCESS) { | ||
| 570 | + srs_warn("http post on_unpublish uri failed, ignored. " | ||
| 571 | + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 572 | + client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 573 | + return; | ||
| 574 | + } | ||
| 575 | + | ||
| 576 | + if (res.empty() || res != SRS_HTTP_RESPONSE_OK) { | ||
| 577 | + ret = ERROR_HTTP_DATA_INVLIAD; | ||
| 578 | + srs_warn("http hook on_unpublish validate failed, ignored. " | ||
| 579 | + "client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret); | ||
| 580 | + return; | ||
| 581 | + } | ||
| 582 | + | ||
| 583 | + srs_trace("http hook on_unpublish success. " | ||
| 584 | + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 585 | + client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 586 | + | ||
| 587 | + return; | ||
| 588 | +} | ||
| 589 | + | ||
| 590 | +int SrsHttpHooks::on_play(std::string url, int client_id, std::string ip, SrsRequest* req) | ||
| 591 | +{ | ||
| 592 | + int ret = ERROR_SUCCESS; | ||
| 593 | + | ||
| 594 | + SrsHttpUri uri; | ||
| 595 | + if ((ret = uri.initialize(url)) != ERROR_SUCCESS) { | ||
| 596 | + srs_error("http uri parse on_play url failed. " | ||
| 597 | + "client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret); | ||
| 598 | + return ret; | ||
| 599 | + } | ||
| 600 | + | ||
| 601 | + /** | ||
| 602 | + { | ||
| 603 | + "action": "on_play", | ||
| 604 | + "client_id": 1985, | ||
| 605 | + "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live", | ||
| 606 | + "stream": "livestream" | ||
| 607 | + } | ||
| 608 | + */ | ||
| 609 | + std::stringstream ss; | ||
| 610 | + ss << "{" | ||
| 611 | + // action | ||
| 612 | + << '"' << "action" << '"' << ':' | ||
| 613 | + << '"' << "on_play" << '"' | ||
| 614 | + << ',' | ||
| 615 | + // client_id | ||
| 616 | + << '"' << "client_id" << '"' << ':' | ||
| 617 | + << std::dec << client_id | ||
| 618 | + << ',' | ||
| 619 | + // ip | ||
| 620 | + << '"' << "ip" << '"' << ':' | ||
| 621 | + << '"' << ip << '"' | ||
| 622 | + << ',' | ||
| 623 | + // vhost | ||
| 624 | + << '"' << "vhost" << '"' << ':' | ||
| 625 | + << '"' << req->vhost << '"' | ||
| 626 | + << ',' | ||
| 627 | + // app | ||
| 628 | + << '"' << "app" << '"' << ':' | ||
| 629 | + << '"' << req->app << '"' | ||
| 630 | + << ',' | ||
| 631 | + // stream | ||
| 632 | + << '"' << "stream" << '"' << ':' | ||
| 633 | + << '"' << req->stream << '"' | ||
| 634 | + //<< ',' | ||
| 635 | + << "}"; | ||
| 636 | + std::string data = ss.str(); | ||
| 637 | + std::string res; | ||
| 638 | + | ||
| 639 | + SrsHttpClient http; | ||
| 640 | + if ((ret = http.post(&uri, data, res)) != ERROR_SUCCESS) { | ||
| 641 | + srs_error("http post on_play uri failed. " | ||
| 642 | + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 643 | + client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 644 | + return ret; | ||
| 645 | + } | ||
| 646 | + | ||
| 647 | + if (res.empty() || res != SRS_HTTP_RESPONSE_OK) { | ||
| 648 | + ret = ERROR_HTTP_DATA_INVLIAD; | ||
| 649 | + srs_error("http hook on_play validate failed. " | ||
| 650 | + "client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret); | ||
| 651 | + return ret; | ||
| 652 | + } | ||
| 653 | + | ||
| 654 | + srs_trace("http hook on_play success. " | ||
| 655 | + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 656 | + client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 657 | + | ||
| 658 | + return ret; | ||
| 659 | +} | ||
| 660 | + | ||
| 661 | +void SrsHttpHooks::on_stop(std::string url, int client_id, std::string ip, SrsRequest* req) | ||
| 662 | +{ | ||
| 663 | + int ret = ERROR_SUCCESS; | ||
| 664 | + | ||
| 665 | + SrsHttpUri uri; | ||
| 666 | + if ((ret = uri.initialize(url)) != ERROR_SUCCESS) { | ||
| 667 | + srs_warn("http uri parse on_stop url failed, ignored. " | ||
| 668 | + "client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret); | ||
| 669 | + return; | ||
| 670 | + } | ||
| 671 | + | ||
| 672 | + /** | ||
| 673 | + { | ||
| 674 | + "action": "on_stop", | ||
| 675 | + "client_id": 1985, | ||
| 676 | + "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live", | ||
| 677 | + "stream": "livestream" | ||
| 678 | + } | ||
| 679 | + */ | ||
| 680 | + std::stringstream ss; | ||
| 681 | + ss << "{" | ||
| 682 | + // action | ||
| 683 | + << '"' << "action" << '"' << ':' | ||
| 684 | + << '"' << "on_stop" << '"' | ||
| 685 | + << ',' | ||
| 686 | + // client_id | ||
| 687 | + << '"' << "client_id" << '"' << ':' | ||
| 688 | + << std::dec << client_id | ||
| 689 | + << ',' | ||
| 690 | + // ip | ||
| 691 | + << '"' << "ip" << '"' << ':' | ||
| 692 | + << '"' << ip << '"' | ||
| 693 | + << ',' | ||
| 694 | + // vhost | ||
| 695 | + << '"' << "vhost" << '"' << ':' | ||
| 696 | + << '"' << req->vhost << '"' | ||
| 697 | + << ',' | ||
| 698 | + // app | ||
| 699 | + << '"' << "app" << '"' << ':' | ||
| 700 | + << '"' << req->app << '"' | ||
| 701 | + << ',' | ||
| 702 | + // stream | ||
| 703 | + << '"' << "stream" << '"' << ':' | ||
| 704 | + << '"' << req->stream << '"' | ||
| 705 | + //<< ',' | ||
| 706 | + << "}"; | ||
| 707 | + std::string data = ss.str(); | ||
| 708 | + std::string res; | ||
| 709 | + | ||
| 710 | + SrsHttpClient http; | ||
| 711 | + if ((ret = http.post(&uri, data, res)) != ERROR_SUCCESS) { | ||
| 712 | + srs_warn("http post on_stop uri failed, ignored. " | ||
| 713 | + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 714 | + client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 715 | + return; | ||
| 716 | + } | ||
| 717 | + | ||
| 718 | + if (res.empty() || res != SRS_HTTP_RESPONSE_OK) { | ||
| 719 | + ret = ERROR_HTTP_DATA_INVLIAD; | ||
| 720 | + srs_warn("http hook on_stop validate failed, ignored. " | ||
| 721 | + "client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret); | ||
| 722 | + return; | ||
| 723 | + } | ||
| 724 | + | ||
| 725 | + srs_trace("http hook on_stop success. " | ||
| 726 | + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 727 | + client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 728 | + | ||
| 729 | + return; | ||
| 730 | +} | ||
| 731 | + | ||
| 732 | +#endif |
trunk/src/app/srs_app_http_hooks.hpp
0 → 100644
| 1 | +/* | ||
| 2 | +The MIT License (MIT) | ||
| 3 | + | ||
| 4 | +Copyright (c) 2013-2014 winlin | ||
| 5 | + | ||
| 6 | +Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
| 7 | +this software and associated documentation files (the "Software"), to deal in | ||
| 8 | +the Software without restriction, including without limitation the rights to | ||
| 9 | +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
| 10 | +the Software, and to permit persons to whom the Software is furnished to do so, | ||
| 11 | +subject to the following conditions: | ||
| 12 | + | ||
| 13 | +The above copyright notice and this permission notice shall be included in all | ||
| 14 | +copies or substantial portions of the Software. | ||
| 15 | + | ||
| 16 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
| 18 | +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
| 19 | +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
| 20 | +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 21 | +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 22 | +*/ | ||
| 23 | + | ||
| 24 | +#ifndef SRS_APP_HTTP_HOOKS_HPP | ||
| 25 | +#define SRS_APP_HTTP_HOOKS_HPP | ||
| 26 | + | ||
| 27 | +/* | ||
| 28 | +#include <srs_app_http_hooks.hpp> | ||
| 29 | +*/ | ||
| 30 | +#include <srs_core.hpp> | ||
| 31 | + | ||
| 32 | +#ifdef SRS_HTTP_CALLBACK | ||
| 33 | + | ||
| 34 | +#include <http_parser.h> | ||
| 35 | + | ||
| 36 | +class SrsHttpUri; | ||
| 37 | +class SrsSocket; | ||
| 38 | +class SrsRequest; | ||
| 39 | + | ||
| 40 | +#include <srs_app_st.hpp> | ||
| 41 | + | ||
| 42 | +/** | ||
| 43 | +* http client to GET/POST/PUT/DELETE uri | ||
| 44 | +*/ | ||
| 45 | +class SrsHttpClient | ||
| 46 | +{ | ||
| 47 | +private: | ||
| 48 | + bool connected; | ||
| 49 | + st_netfd_t stfd; | ||
| 50 | +private: | ||
| 51 | + http_parser http_header; | ||
| 52 | +public: | ||
| 53 | + SrsHttpClient(); | ||
| 54 | + virtual ~SrsHttpClient(); | ||
| 55 | +public: | ||
| 56 | + /** | ||
| 57 | + * to post data to the uri. | ||
| 58 | + * @param req the data post to uri. | ||
| 59 | + * @param res the response data from server. | ||
| 60 | + */ | ||
| 61 | + virtual int post(SrsHttpUri* uri, std::string req, std::string& res); | ||
| 62 | +private: | ||
| 63 | + virtual void disconnect(); | ||
| 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 | +}; | ||
| 74 | + | ||
| 75 | +/** | ||
| 76 | +* the http hooks, http callback api, | ||
| 77 | +* for some event, such as on_connect, call | ||
| 78 | +* a http api(hooks). | ||
| 79 | +*/ | ||
| 80 | +class SrsHttpHooks | ||
| 81 | +{ | ||
| 82 | +public: | ||
| 83 | + SrsHttpHooks(); | ||
| 84 | + virtual ~SrsHttpHooks(); | ||
| 85 | +public: | ||
| 86 | + /** | ||
| 87 | + * on_connect hook, when client connect to srs. | ||
| 88 | + * @param client_id the id of client on server. | ||
| 89 | + * @param url the api server url, to valid the client. | ||
| 90 | + * ignore if empty. | ||
| 91 | + * @return valid failed or connect to the url failed. | ||
| 92 | + */ | ||
| 93 | + virtual int on_connect(std::string url, int client_id, std::string ip, SrsRequest* req); | ||
| 94 | + /** | ||
| 95 | + * on_close hook, when client disconnect to srs, where client is valid by on_connect. | ||
| 96 | + * @param client_id the id of client on server. | ||
| 97 | + * @param url the api server url, to process the event. | ||
| 98 | + * ignore if empty. | ||
| 99 | + */ | ||
| 100 | + virtual void on_close(std::string url, int client_id, std::string ip, SrsRequest* req); | ||
| 101 | + /** | ||
| 102 | + * on_publish hook, when client(encoder) start to publish stream | ||
| 103 | + * @param client_id the id of client on server. | ||
| 104 | + * @param url the api server url, to valid the client. | ||
| 105 | + * ignore if empty. | ||
| 106 | + * @return valid failed or connect to the url failed. | ||
| 107 | + */ | ||
| 108 | + virtual int on_publish(std::string url, int client_id, std::string ip, SrsRequest* req); | ||
| 109 | + /** | ||
| 110 | + * on_unpublish hook, when client(encoder) stop publish stream. | ||
| 111 | + * @param client_id the id of client on server. | ||
| 112 | + * @param url the api server url, to process the event. | ||
| 113 | + * ignore if empty. | ||
| 114 | + */ | ||
| 115 | + virtual void on_unpublish(std::string url, int client_id, std::string ip, SrsRequest* req); | ||
| 116 | + /** | ||
| 117 | + * on_play hook, when client start to play stream. | ||
| 118 | + * @param client_id the id of client on server. | ||
| 119 | + * @param url the api server url, to valid the client. | ||
| 120 | + * ignore if empty. | ||
| 121 | + * @return valid failed or connect to the url failed. | ||
| 122 | + */ | ||
| 123 | + virtual int on_play(std::string url, int client_id, std::string ip, SrsRequest* req); | ||
| 124 | + /** | ||
| 125 | + * on_stop hook, when client stop to play the stream. | ||
| 126 | + * @param client_id the id of client on server. | ||
| 127 | + * @param url the api server url, to process the event. | ||
| 128 | + * ignore if empty. | ||
| 129 | + */ | ||
| 130 | + virtual void on_stop(std::string url, int client_id, std::string ip, SrsRequest* req); | ||
| 131 | +}; | ||
| 132 | + | ||
| 133 | +#endif | ||
| 134 | + | ||
| 135 | +#endif |
| @@ -41,6 +41,7 @@ using namespace std; | @@ -41,6 +41,7 @@ using namespace std; | ||
| 41 | #include <srs_app_http.hpp> | 41 | #include <srs_app_http.hpp> |
| 42 | #include <srs_app_bandwidth.hpp> | 42 | #include <srs_app_bandwidth.hpp> |
| 43 | #include <srs_app_socket.hpp> | 43 | #include <srs_app_socket.hpp> |
| 44 | +#include <srs_app_http_hooks.hpp> | ||
| 44 | 45 | ||
| 45 | SrsRtmpConn::SrsRtmpConn(SrsServer* srs_server, st_netfd_t client_stfd) | 46 | SrsRtmpConn::SrsRtmpConn(SrsServer* srs_server, st_netfd_t client_stfd) |
| 46 | : SrsConnection(srs_server, client_stfd) | 47 | : SrsConnection(srs_server, client_stfd) |
| @@ -59,6 +59,8 @@ file | @@ -59,6 +59,8 @@ file | ||
| 59 | ..\app\srs_app_http_api.cpp, | 59 | ..\app\srs_app_http_api.cpp, |
| 60 | ..\app\srs_app_http_conn.hpp, | 60 | ..\app\srs_app_http_conn.hpp, |
| 61 | ..\app\srs_app_http_conn.cpp, | 61 | ..\app\srs_app_http_conn.cpp, |
| 62 | + ..\app\srs_app_http_hooks.hpp, | ||
| 63 | + ..\app\srs_app_http_hooks.cpp, | ||
| 62 | ..\app\srs_app_log.hpp, | 64 | ..\app\srs_app_log.hpp, |
| 63 | ..\app\srs_app_log.cpp, | 65 | ..\app\srs_app_log.cpp, |
| 64 | ..\app\srs_app_refer.hpp, | 66 | ..\app\srs_app_refer.hpp, |
-
请 注册 或 登录 后发表评论