winlin

optimizm the http server for send ts file

@@ -163,50 +163,106 @@ int SrsHttpVhost::do_process_request(SrsSocket* skt, SrsHttpMessage* req) @@ -163,50 +163,106 @@ int SrsHttpVhost::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
163 163
164 std::string fullpath = get_request_file(req); 164 std::string fullpath = get_request_file(req);
165 165
166 - // TODO: FIXME: refine the file stream.  
167 - int fd = ::open(fullpath.c_str(), O_RDONLY);  
168 - if (fd < 0) {  
169 - ret = ERROR_HTTP_OPEN_FILE;  
170 - srs_warn("open file %s failed, ret=%d", fullpath.c_str(), ret);  
171 - return ret;  
172 - }  
173 -  
174 - int64_t length = (int64_t)::lseek(fd, 0, SEEK_END);  
175 - ::lseek(fd, 0, SEEK_SET); 166 + if (srs_string_ends_with(fullpath, ".ts")) {
  167 + // TODO: FIXME: use more advance cache.
  168 + // for ts video large file, use bytes to write it.
  169 + int fd = ::open(fullpath.c_str(), O_RDONLY);
  170 + if (fd < 0) {
  171 + ret = ERROR_HTTP_OPEN_FILE;
  172 + srs_warn("open file %s failed, ret=%d", fullpath.c_str(), ret);
  173 + return ret;
  174 + }
176 175
177 - char* buf = new char[length];  
178 - SrsAutoFree(char, buf, true); 176 + int64_t length = (int64_t)::lseek(fd, 0, SEEK_END);
  177 + ::lseek(fd, 0, SEEK_SET);
179 178
180 - // TODO: FIXME: use st_read.  
181 - if (::read(fd, buf, length) < 0) { 179 + // write http header for ts.
  180 + std::stringstream ss;
  181 +
  182 + res_status_line(ss)->res_content_type_mpegts(ss)
  183 + ->res_content_length(ss, (int)length);
  184 +
  185 + if (req->requires_crossdomain()) {
  186 + res_enable_crossdomain(ss);
  187 + }
  188 +
  189 + res_header_eof(ss);
  190 +
  191 + // flush http header to peer
  192 + if ((ret = res_flush(skt, ss)) != ERROR_SUCCESS) {
  193 + return ret;
  194 + }
  195 +
  196 + // write body.
  197 + int64_t left = length;
  198 + const static int HTTP_PKT_SIZE = 4096;
  199 + char* buf = new char[HTTP_PKT_SIZE];
  200 + SrsAutoFree(char, buf, true);
  201 +
  202 + while (left > 0) {
  203 + ssize_t nread = -1;
  204 + // TODO: FIXME: use st_read.
  205 + if ((nread = ::read(fd, buf, HTTP_PKT_SIZE)) < 0) {
  206 + ::close(fd);
  207 + ret = ERROR_HTTP_READ_FILE;
  208 + srs_warn("read file %s failed, ret=%d", fullpath.c_str(), ret);
  209 + return ret;
  210 + }
  211 +
  212 + left -= nread;
  213 + if ((ret = skt->write(buf, nread, NULL)) != ERROR_SUCCESS) {
  214 + break;
  215 + }
  216 + }
182 ::close(fd); 217 ::close(fd);
183 - ret = ERROR_HTTP_READ_FILE;  
184 - srs_warn("read file %s failed, ret=%d", fullpath.c_str(), ret); 218 +
185 return ret; 219 return ret;
186 - }  
187 - ::close(fd);  
188 -  
189 - std::string str;  
190 - str.append(buf, length);  
191 -  
192 - if (srs_string_ends_with(fullpath, ".ts")) {  
193 - return res_mpegts(skt, req, str);  
194 - } else if (srs_string_ends_with(fullpath, ".m3u8")) {  
195 - return res_m3u8(skt, req, str);  
196 - } else if (srs_string_ends_with(fullpath, ".xml")) {  
197 - return res_xml(skt, req, str);  
198 - } else if (srs_string_ends_with(fullpath, ".js")) {  
199 - return res_javascript(skt, req, str);  
200 - } else if (srs_string_ends_with(fullpath, ".json")) {  
201 - return res_json(skt, req, str);  
202 - } else if (srs_string_ends_with(fullpath, ".swf")) {  
203 - return res_swf(skt, req, str);  
204 - } else if (srs_string_ends_with(fullpath, ".css")) {  
205 - return res_css(skt, req, str);  
206 - } else if (srs_string_ends_with(fullpath, ".ico")) {  
207 - return res_ico(skt, req, str);  
208 } else { 220 } else {
209 - return res_text(skt, req, str); 221 + // TODO: FIXME: refine the file stream.
  222 + int fd = ::open(fullpath.c_str(), O_RDONLY);
  223 + if (fd < 0) {
  224 + ret = ERROR_HTTP_OPEN_FILE;
  225 + srs_warn("open file %s failed, ret=%d", fullpath.c_str(), ret);
  226 + return ret;
  227 + }
  228 +
  229 + int64_t length = (int64_t)::lseek(fd, 0, SEEK_END);
  230 + ::lseek(fd, 0, SEEK_SET);
  231 +
  232 + char* buf = new char[length];
  233 + SrsAutoFree(char, buf, true);
  234 +
  235 + // TODO: FIXME: use st_read.
  236 + if (::read(fd, buf, length) < 0) {
  237 + ::close(fd);
  238 + ret = ERROR_HTTP_READ_FILE;
  239 + srs_warn("read file %s failed, ret=%d", fullpath.c_str(), ret);
  240 + return ret;
  241 + }
  242 + ::close(fd);
  243 +
  244 + std::string str;
  245 + str.append(buf, length);
  246 +
  247 + if (srs_string_ends_with(fullpath, ".ts")) {
  248 + return res_mpegts(skt, req, str);
  249 + } else if (srs_string_ends_with(fullpath, ".m3u8")) {
  250 + return res_m3u8(skt, req, str);
  251 + } else if (srs_string_ends_with(fullpath, ".xml")) {
  252 + return res_xml(skt, req, str);
  253 + } else if (srs_string_ends_with(fullpath, ".js")) {
  254 + return res_javascript(skt, req, str);
  255 + } else if (srs_string_ends_with(fullpath, ".json")) {
  256 + return res_json(skt, req, str);
  257 + } else if (srs_string_ends_with(fullpath, ".swf")) {
  258 + return res_swf(skt, req, str);
  259 + } else if (srs_string_ends_with(fullpath, ".css")) {
  260 + return res_css(skt, req, str);
  261 + } else if (srs_string_ends_with(fullpath, ".ico")) {
  262 + return res_ico(skt, req, str);
  263 + } else {
  264 + return res_text(skt, req, str);
  265 + }
210 } 266 }
211 267
212 return ret; 268 return ret;
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR "0" 32 #define VERSION_MAJOR "0"
33 #define VERSION_MINOR "9" 33 #define VERSION_MINOR "9"
34 -#define VERSION_REVISION "72" 34 +#define VERSION_REVISION "73"
35 #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION 35 #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
36 // server info. 36 // server info.
37 #define RTMP_SIG_SRS_KEY "srs" 37 #define RTMP_SIG_SRS_KEY "srs"