From 6fba0db9b5ac5d1badeb30dda6851d435676a099 Mon Sep 17 00:00:00 2001 From: winlin Date: Fri, 23 May 2014 14:26:11 +0800 Subject: [PATCH] refine http stream server --- trunk/src/app/srs_app_http_conn.cpp | 188 +++++++++++++++------------- trunk/src/app/srs_app_http_conn.hpp | 2 + 2 files changed, 104 insertions(+), 86 deletions(-) diff --git a/trunk/src/app/srs_app_http_conn.cpp b/trunk/src/app/srs_app_http_conn.cpp index 32231ce6f..acc33ac59 100644 --- a/trunk/src/app/srs_app_http_conn.cpp +++ b/trunk/src/app/srs_app_http_conn.cpp @@ -164,104 +164,120 @@ int SrsHttpVhost::do_process_request(SrsSocket* skt, SrsHttpMessage* req) std::string fullpath = get_request_file(req); if (srs_string_ends_with(fullpath, ".ts")) { - // TODO: FIXME: use more advance cache. - // for ts video large file, use bytes to write it. - int fd = ::open(fullpath.c_str(), O_RDONLY); - if (fd < 0) { - ret = ERROR_HTTP_OPEN_FILE; - srs_warn("open file %s failed, ret=%d", fullpath.c_str(), ret); - return ret; - } - - int64_t length = (int64_t)::lseek(fd, 0, SEEK_END); - ::lseek(fd, 0, SEEK_SET); - - // write http header for ts. - std::stringstream ss; - - res_status_line(ss)->res_content_type_mpegts(ss) - ->res_content_length(ss, (int)length); - - if (req->requires_crossdomain()) { - res_enable_crossdomain(ss); - } - - res_header_eof(ss); - - // flush http header to peer - if ((ret = res_flush(skt, ss)) != ERROR_SUCCESS) { - return ret; - } - - // write body. - int64_t left = length; - char* buf = req->http_ts_send_buffer(); - - while (left > 0) { - ssize_t nread = -1; - // TODO: FIXME: use st_read. - if ((nread = ::read(fd, buf, HTTP_TS_SEND_BUFFER_SIZE)) < 0) { - ::close(fd); - ret = ERROR_HTTP_READ_FILE; - srs_warn("read file %s failed, ret=%d", fullpath.c_str(), ret); - return ret; - } - - left -= nread; - if ((ret = skt->write(buf, nread, NULL)) != ERROR_SUCCESS) { - break; - } - } - ::close(fd); - - return ret; + return response_ts_file(skt, req, fullpath); } else { - // TODO: FIXME: refine the file stream. - int fd = ::open(fullpath.c_str(), O_RDONLY); - if (fd < 0) { - ret = ERROR_HTTP_OPEN_FILE; - srs_warn("open file %s failed, ret=%d", fullpath.c_str(), ret); - return ret; - } + return response_regular_file(skt, req, fullpath); + } - int64_t length = (int64_t)::lseek(fd, 0, SEEK_END); - ::lseek(fd, 0, SEEK_SET); - - char* buf = new char[length]; - SrsAutoFree(char, buf); + return ret; +} + +int SrsHttpVhost::response_regular_file(SrsSocket* skt, SrsHttpMessage* req, string fullpath) +{ + int ret = ERROR_SUCCESS; + + // TODO: FIXME: refine the file stream. + int fd = ::open(fullpath.c_str(), O_RDONLY); + if (fd < 0) { + ret = ERROR_HTTP_OPEN_FILE; + srs_warn("open file %s failed, ret=%d", fullpath.c_str(), ret); + return ret; + } + + int64_t length = (int64_t)::lseek(fd, 0, SEEK_END); + ::lseek(fd, 0, SEEK_SET); + + char* buf = new char[length]; + SrsAutoFree(char, buf); + + // TODO: FIXME: use st_read. + if (::read(fd, buf, length) < 0) { + ::close(fd); + ret = ERROR_HTTP_READ_FILE; + srs_warn("read file %s failed, ret=%d", fullpath.c_str(), ret); + return ret; + } + ::close(fd); + + std::string str; + str.append(buf, length); + + if (srs_string_ends_with(fullpath, ".ts")) { + return res_mpegts(skt, req, str); + } else if (srs_string_ends_with(fullpath, ".m3u8")) { + return res_m3u8(skt, req, str); + } else if (srs_string_ends_with(fullpath, ".xml")) { + return res_xml(skt, req, str); + } else if (srs_string_ends_with(fullpath, ".js")) { + return res_javascript(skt, req, str); + } else if (srs_string_ends_with(fullpath, ".json")) { + return res_json(skt, req, str); + } else if (srs_string_ends_with(fullpath, ".swf")) { + return res_swf(skt, req, str); + } else if (srs_string_ends_with(fullpath, ".css")) { + return res_css(skt, req, str); + } else if (srs_string_ends_with(fullpath, ".ico")) { + return res_ico(skt, req, str); + } else { + return res_text(skt, req, str); + } + + return ret; +} + +int SrsHttpVhost::response_ts_file(SrsSocket* skt, SrsHttpMessage* req, string fullpath) +{ + int ret = ERROR_SUCCESS; + + // TODO: FIXME: use more advance cache. + // for ts video large file, use bytes to write it. + int fd = ::open(fullpath.c_str(), O_RDONLY); + if (fd < 0) { + ret = ERROR_HTTP_OPEN_FILE; + srs_warn("open file %s failed, ret=%d", fullpath.c_str(), ret); + return ret; + } + + int64_t length = (int64_t)::lseek(fd, 0, SEEK_END); + ::lseek(fd, 0, SEEK_SET); + + // write http header for ts. + std::stringstream ss; + + res_status_line(ss)->res_content_type_mpegts(ss) + ->res_content_length(ss, (int)length); + if (req->requires_crossdomain()) { + res_enable_crossdomain(ss); + } + + res_header_eof(ss); + + // flush http header to peer + if ((ret = res_flush(skt, ss)) != ERROR_SUCCESS) { + return ret; + } + + // write body. + int64_t left = length; + char* buf = req->http_ts_send_buffer(); + + while (left > 0) { + ssize_t nread = -1; // TODO: FIXME: use st_read. - if (::read(fd, buf, length) < 0) { + if ((nread = ::read(fd, buf, HTTP_TS_SEND_BUFFER_SIZE)) < 0) { ::close(fd); ret = ERROR_HTTP_READ_FILE; srs_warn("read file %s failed, ret=%d", fullpath.c_str(), ret); return ret; } - ::close(fd); - std::string str; - str.append(buf, length); - - if (srs_string_ends_with(fullpath, ".ts")) { - return res_mpegts(skt, req, str); - } else if (srs_string_ends_with(fullpath, ".m3u8")) { - return res_m3u8(skt, req, str); - } else if (srs_string_ends_with(fullpath, ".xml")) { - return res_xml(skt, req, str); - } else if (srs_string_ends_with(fullpath, ".js")) { - return res_javascript(skt, req, str); - } else if (srs_string_ends_with(fullpath, ".json")) { - return res_json(skt, req, str); - } else if (srs_string_ends_with(fullpath, ".swf")) { - return res_swf(skt, req, str); - } else if (srs_string_ends_with(fullpath, ".css")) { - return res_css(skt, req, str); - } else if (srs_string_ends_with(fullpath, ".ico")) { - return res_ico(skt, req, str); - } else { - return res_text(skt, req, str); + left -= nread; + if ((ret = skt->write(buf, nread, NULL)) != ERROR_SUCCESS) { + break; } } + ::close(fd); return ret; } diff --git a/trunk/src/app/srs_app_http_conn.hpp b/trunk/src/app/srs_app_http_conn.hpp index c959f5cfe..a9d3a116d 100644 --- a/trunk/src/app/srs_app_http_conn.hpp +++ b/trunk/src/app/srs_app_http_conn.hpp @@ -70,6 +70,8 @@ protected: virtual bool is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase); virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); private: + virtual int response_regular_file(SrsSocket* skt, SrsHttpMessage* req, std::string fullpath); + virtual int response_ts_file(SrsSocket* skt, SrsHttpMessage* req, std::string fullpath); virtual std::string get_request_file(SrsHttpMessage* req); public: virtual std::string vhost();