winlin

for #293, #277, support http chunked encoding

@@ -339,7 +339,8 @@ int SrsGoHttpFileServer::serve_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage* @@ -339,7 +339,8 @@ int SrsGoHttpFileServer::serve_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage*
339 339
340 int64_t length = fs.filesize(); 340 int64_t length = fs.filesize();
341 341
342 - w->header()->set_content_length(length); 342 + // unset the content length in chunked encoding.
  343 + //w->header()->set_content_length(length);
343 344
344 static std::map<std::string, std::string> _mime; 345 static std::map<std::string, std::string> _mime;
345 if (_mime.empty()) { 346 if (_mime.empty()) {
@@ -391,7 +392,7 @@ int SrsGoHttpFileServer::serve_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage* @@ -391,7 +392,7 @@ int SrsGoHttpFileServer::serve_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage*
391 return ret; 392 return ret;
392 } 393 }
393 394
394 - return ret; 395 + return w->final_request();
395 } 396 }
396 397
397 int SrsGoHttpFileServer::serve_flv_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int offset) 398 int SrsGoHttpFileServer::serve_flv_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int offset)
@@ -653,6 +654,20 @@ SrsGoHttpResponseWriter::~SrsGoHttpResponseWriter() @@ -653,6 +654,20 @@ SrsGoHttpResponseWriter::~SrsGoHttpResponseWriter()
653 srs_freep(hdr); 654 srs_freep(hdr);
654 } 655 }
655 656
  657 +int SrsGoHttpResponseWriter::final_request()
  658 +{
  659 + // complete the chunked encoding.
  660 + if (content_length == -1) {
  661 + std::stringstream ss;
  662 + ss << 0 << __SRS_CRLF << __SRS_CRLF;
  663 + std::string ch = ss.str();
  664 + return skt->write((void*)ch.data(), (int)ch.length(), NULL);
  665 + }
  666 +
  667 + // ignore when send with content length
  668 + return ERROR_SUCCESS;
  669 +}
  670 +
656 SrsGoHttpHeader* SrsGoHttpResponseWriter::header() 671 SrsGoHttpHeader* SrsGoHttpResponseWriter::header()
657 { 672 {
658 return hdr; 673 return hdr;
@@ -678,7 +693,26 @@ int SrsGoHttpResponseWriter::write(char* data, int size) @@ -678,7 +693,26 @@ int SrsGoHttpResponseWriter::write(char* data, int size)
678 return ret; 693 return ret;
679 } 694 }
680 695
681 - return skt->write((void*)data, size, NULL); 696 + // directly send with content length
  697 + if (content_length != -1) {
  698 + return skt->write((void*)data, size, NULL);
  699 + }
  700 +
  701 + // send in chunked encoding.
  702 + std::stringstream ss;
  703 + ss << hex << size << __SRS_CRLF;
  704 + std::string ch = ss.str();
  705 + if ((ret = skt->write((void*)ch.data(), (int)ch.length(), NULL)) != ERROR_SUCCESS) {
  706 + return ret;
  707 + }
  708 + if ((ret = skt->write((void*)data, size, NULL)) != ERROR_SUCCESS) {
  709 + return ret;
  710 + }
  711 + if ((ret = skt->write((void*)__SRS_CRLF, 2, NULL)) != ERROR_SUCCESS) {
  712 + return ret;
  713 + }
  714 +
  715 + return ret;
682 } 716 }
683 717
684 void SrsGoHttpResponseWriter::write_header(int code) 718 void SrsGoHttpResponseWriter::write_header(int code)
@@ -722,6 +756,11 @@ int SrsGoHttpResponseWriter::send_header(char* data, int size) @@ -722,6 +756,11 @@ int SrsGoHttpResponseWriter::send_header(char* data, int size)
722 hdr->set("Server", RTMP_SIG_SRS_KEY"/"RTMP_SIG_SRS_VERSION); 756 hdr->set("Server", RTMP_SIG_SRS_KEY"/"RTMP_SIG_SRS_VERSION);
723 } 757 }
724 758
  759 + // chunked encoding
  760 + if (content_length == -1) {
  761 + hdr->set("Transfer-Encoding", "chunked");
  762 + }
  763 +
725 // write headers 764 // write headers
726 hdr->write(ss); 765 hdr->write(ss);
727 766
@@ -128,6 +128,10 @@ public: @@ -128,6 +128,10 @@ public:
128 ISrsGoHttpResponseWriter(); 128 ISrsGoHttpResponseWriter();
129 virtual ~ISrsGoHttpResponseWriter(); 129 virtual ~ISrsGoHttpResponseWriter();
130 public: 130 public:
  131 + // when chunked mode,
  132 + // final the request to complete the chunked encoding.
  133 + virtual int final_request() = 0;
  134 +
131 // Header returns the header map that will be sent by WriteHeader. 135 // Header returns the header map that will be sent by WriteHeader.
132 // Changing the header after a call to WriteHeader (or Write) has 136 // Changing the header after a call to WriteHeader (or Write) has
133 // no effect. 137 // no effect.
@@ -319,6 +323,7 @@ public: @@ -319,6 +323,7 @@ public:
319 SrsGoHttpResponseWriter(SrsStSocket* io); 323 SrsGoHttpResponseWriter(SrsStSocket* io);
320 virtual ~SrsGoHttpResponseWriter(); 324 virtual ~SrsGoHttpResponseWriter();
321 public: 325 public:
  326 + virtual int final_request();
322 virtual SrsGoHttpHeader* header(); 327 virtual SrsGoHttpHeader* header();
323 virtual int write(char* data, int size); 328 virtual int write(char* data, int size);
324 virtual void write_header(int code); 329 virtual void write_header(int code);
@@ -304,7 +304,7 @@ int SrsLiveStream::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r) @@ -304,7 +304,7 @@ int SrsLiveStream::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
304 // TODO: FIMXE: add pithy print. 304 // TODO: FIMXE: add pithy print.
305 305
306 // write http header for streaming. 306 // write http header for streaming.
307 - w->header()->set_content_length((int64_t)2 * 1024 * 1024 * 1024); 307 + // use chunked encoding, for we donot specifes the content length.
308 if (serve_flv_streaming) { 308 if (serve_flv_streaming) {
309 w->header()->set_content_type("video/x-flv"); 309 w->header()->set_content_type("video/x-flv");
310 } 310 }