winlin

refine hls on_hls_notify, read a little of ts.

@@ -53,6 +53,9 @@ using namespace std; @@ -53,6 +53,9 @@ using namespace std;
53 #define SRS_CONSTS_HTTP_PUT HTTP_PUT 53 #define SRS_CONSTS_HTTP_PUT HTTP_PUT
54 #define SRS_CONSTS_HTTP_DELETE HTTP_DELETE 54 #define SRS_CONSTS_HTTP_DELETE HTTP_DELETE
55 55
  56 +// for ead all of http body, read each time.
  57 +#define SRS_HTTP_READ_CACHE_BYTES 4096
  58 +
56 #define SRS_HTTP_DEFAULT_PAGE "index.html" 59 #define SRS_HTTP_DEFAULT_PAGE "index.html"
57 60
58 int srs_go_http_response_json(ISrsHttpResponseWriter* w, string data) 61 int srs_go_http_response_json(ISrsHttpResponseWriter* w, string data)
@@ -889,7 +892,8 @@ SrsHttpResponseReader::SrsHttpResponseReader(SrsHttpMessage* msg, SrsStSocket* i @@ -889,7 +892,8 @@ SrsHttpResponseReader::SrsHttpResponseReader(SrsHttpMessage* msg, SrsStSocket* i
889 skt = io; 892 skt = io;
890 owner = msg; 893 owner = msg;
891 is_eof = false; 894 is_eof = false;
892 - nb_read = 0; 895 + nb_total_read = 0;
  896 + nb_left_chunk = 0;
893 buffer = NULL; 897 buffer = NULL;
894 } 898 }
895 899
@@ -901,6 +905,8 @@ int SrsHttpResponseReader::initialize(SrsFastBuffer* body) @@ -901,6 +905,8 @@ int SrsHttpResponseReader::initialize(SrsFastBuffer* body)
901 { 905 {
902 int ret = ERROR_SUCCESS; 906 int ret = ERROR_SUCCESS;
903 907
  908 + nb_left_chunk = 0;
  909 + nb_total_read = 0;
904 buffer = body; 910 buffer = body;
905 911
906 return ret; 912 return ret;
@@ -911,7 +917,7 @@ bool SrsHttpResponseReader::eof() @@ -911,7 +917,7 @@ bool SrsHttpResponseReader::eof()
911 return is_eof; 917 return is_eof;
912 } 918 }
913 919
914 -int SrsHttpResponseReader::read(std::string& data) 920 +int SrsHttpResponseReader::read(char* data, int nb_data, int* nb_read)
915 { 921 {
916 int ret = ERROR_SUCCESS; 922 int ret = ERROR_SUCCESS;
917 923
@@ -923,23 +929,28 @@ int SrsHttpResponseReader::read(std::string& data) @@ -923,23 +929,28 @@ int SrsHttpResponseReader::read(std::string& data)
923 929
924 // chunked encoding. 930 // chunked encoding.
925 if (owner->is_chunked()) { 931 if (owner->is_chunked()) {
926 - return read_chunked(data); 932 + return read_chunked(data, nb_data, nb_read);
927 } 933 }
928 934
929 // read by specified content-length 935 // read by specified content-length
930 - int max = (int)owner->content_length() - (int)nb_read; 936 + int max = (int)owner->content_length() - (int)nb_total_read;
931 if (max <= 0) { 937 if (max <= 0) {
932 is_eof = true; 938 is_eof = true;
933 return ret; 939 return ret;
934 } 940 }
935 - return read_specified(max, data); 941 +
  942 + // change the max to read.
  943 + nb_data = srs_min(nb_data, max);
  944 + return read_specified(data, nb_data, nb_read);
936 } 945 }
937 946
938 -int SrsHttpResponseReader::read_chunked(std::string& data) 947 +int SrsHttpResponseReader::read_chunked(char* data, int nb_data, int* nb_read)
939 { 948 {
940 int ret = ERROR_SUCCESS; 949 int ret = ERROR_SUCCESS;
941 950
  951 + // when no bytes left in chunk,
942 // parse the chunk length first. 952 // parse the chunk length first.
  953 + if (nb_left_chunk <= 0) {
943 char* at = NULL; 954 char* at = NULL;
944 int length = 0; 955 int length = 0;
945 while (!at) { 956 while (!at) {
@@ -987,31 +998,46 @@ int SrsHttpResponseReader::read_chunked(std::string& data) @@ -987,31 +998,46 @@ int SrsHttpResponseReader::read_chunked(std::string& data)
987 return ret; 998 return ret;
988 } 999 }
989 1000
990 - // when empty, only grow 1bytes, but the buffer will cache more.  
991 - if ((ret = buffer->grow(skt, ilength + 2)) != ERROR_SUCCESS) {  
992 - if (!srs_is_client_gracefully_close(ret)) {  
993 - srs_error("read body from server failed. ret=%d", ret); 1001 + // all bytes in chunk is left now.
  1002 + nb_left_chunk = ilength;
994 } 1003 }
  1004 +
  1005 + // left bytes in chunk, read some.
  1006 + srs_assert(nb_left_chunk);
  1007 +
  1008 + int nb_bytes = srs_min(nb_left_chunk, nb_data);
  1009 + ret = read_specified(data, nb_bytes, &nb_bytes);
  1010 +
  1011 + // the nb_bytes used for output already read size of bytes.
  1012 + if (nb_read) {
  1013 + *nb_read = nb_bytes;
  1014 + }
  1015 + nb_left_chunk -= nb_bytes;
  1016 +
  1017 + // error or still left bytes in chunk, ignore and read in future.
  1018 + if (nb_left_chunk > 0 || (ret != ERROR_SUCCESS)) {
995 return ret; 1019 return ret;
996 } 1020 }
997 - srs_info("http: read %d chunk", ilength); 1021 + srs_info("http: read %d bytes of chunk", nb_bytes);
998 1022
999 // read payload when length specifies some payload. 1023 // read payload when length specifies some payload.
1000 - if (ilength <= 0) { 1024 + if (nb_left_chunk <= 0) {
1001 is_eof = true; 1025 is_eof = true;
1002 - } else {  
1003 - srs_assert(ilength);  
1004 - data.append(buffer->read_slice(ilength), ilength);  
1005 - nb_read += ilength;  
1006 } 1026 }
1007 1027
1008 // the CRLF of chunk payload end. 1028 // the CRLF of chunk payload end.
  1029 + if ((ret = buffer->grow(skt, 2)) != ERROR_SUCCESS) {
  1030 + if (!srs_is_client_gracefully_close(ret)) {
  1031 + srs_error("read EOF of chunk from server failed. ret=%d", ret);
  1032 + }
  1033 + return ret;
  1034 + }
1009 buffer->read_slice(2); 1035 buffer->read_slice(2);
1010 1036
1011 return ret; 1037 return ret;
1012 } 1038 }
1013 1039
1014 -int SrsHttpResponseReader::read_specified(int max, std::string& data) 1040 +int SrsHttpResponseReader::read_specified(char* data, int nb_data, int* nb_read)
1015 { 1041 {
1016 int ret = ERROR_SUCCESS; 1042 int ret = ERROR_SUCCESS;
1017 1043
@@ -1025,14 +1051,21 @@ int SrsHttpResponseReader::read_specified(int max, std::string& data) @@ -1025,14 +1051,21 @@ int SrsHttpResponseReader::read_specified(int max, std::string& data)
1025 } 1051 }
1026 } 1052 }
1027 1053
1028 - int nb_bytes = srs_min(max, buffer->size()); 1054 + int nb_bytes = srs_min(nb_data, buffer->size());
1029 1055
  1056 + // read data to buffer.
1030 srs_assert(nb_bytes); 1057 srs_assert(nb_bytes);
1031 - data.append(buffer->read_slice(nb_bytes), nb_bytes);  
1032 - nb_read += nb_bytes; 1058 + char* p = buffer->read_slice(nb_bytes);
  1059 + memcpy(data, p, nb_bytes);
  1060 + if (nb_read) {
  1061 + *nb_read = nb_bytes;
  1062 + }
  1063 +
  1064 + // increase the total read to determine whether EOF.
  1065 + nb_total_read += nb_bytes;
1033 1066
1034 // when read completed, eof. 1067 // when read completed, eof.
1035 - if (nb_read >= (int)owner->content_length()) { 1068 + if (nb_total_read >= (int)owner->content_length()) {
1036 is_eof = true; 1069 is_eof = true;
1037 } 1070 }
1038 1071
@@ -1223,11 +1256,19 @@ int SrsHttpMessage::body_read_all(string& body) @@ -1223,11 +1256,19 @@ int SrsHttpMessage::body_read_all(string& body)
1223 { 1256 {
1224 int ret = ERROR_SUCCESS; 1257 int ret = ERROR_SUCCESS;
1225 1258
  1259 + // cache to read.
  1260 + char* buf = new char[SRS_HTTP_READ_CACHE_BYTES];
  1261 + SrsAutoFree(char, buf);
  1262 +
1226 // whatever, read util EOF. 1263 // whatever, read util EOF.
1227 while (!_body->eof()) { 1264 while (!_body->eof()) {
1228 - if ((ret = _body->read(body)) != ERROR_SUCCESS) { 1265 + int nb_read = 0;
  1266 + if ((ret = _body->read(buf, SRS_HTTP_READ_CACHE_BYTES, &nb_read)) != ERROR_SUCCESS) {
1229 return ret; 1267 return ret;
1230 } 1268 }
  1269 +
  1270 + srs_assert (nb_read > 0);
  1271 + body.append(buf, nb_read);
1231 } 1272 }
1232 1273
1233 return ret; 1274 return ret;
@@ -197,9 +197,12 @@ public: @@ -197,9 +197,12 @@ public:
197 virtual bool eof() = 0; 197 virtual bool eof() = 0;
198 /** 198 /**
199 * read from the response body. 199 * read from the response body.
  200 + * @param data, the buffer to read data buffer to.
  201 + * @param nb_data, the max size of data buffer.
  202 + * @param nb_read, the actual read size of bytes. NULL to ignore.
200 * @remark when eof(), return error. 203 * @remark when eof(), return error.
201 */ 204 */
202 - virtual int read(std::string& data) = 0; 205 + virtual int read(char* data, int nb_data, int* nb_read) = 0;
203 }; 206 };
204 207
205 // Objects implementing the Handler interface can be 208 // Objects implementing the Handler interface can be
@@ -431,7 +434,10 @@ private: @@ -431,7 +434,10 @@ private:
431 SrsHttpMessage* owner; 434 SrsHttpMessage* owner;
432 SrsFastBuffer* buffer; 435 SrsFastBuffer* buffer;
433 bool is_eof; 436 bool is_eof;
434 - int64_t nb_read; 437 + // the left bytes in chunk.
  438 + int nb_left_chunk;
  439 + // already read total bytes.
  440 + int64_t nb_total_read;
435 public: 441 public:
436 SrsHttpResponseReader(SrsHttpMessage* msg, SrsStSocket* io); 442 SrsHttpResponseReader(SrsHttpMessage* msg, SrsStSocket* io);
437 virtual ~SrsHttpResponseReader(); 443 virtual ~SrsHttpResponseReader();
@@ -443,10 +449,10 @@ public: @@ -443,10 +449,10 @@ public:
443 // interface ISrsHttpResponseReader 449 // interface ISrsHttpResponseReader
444 public: 450 public:
445 virtual bool eof(); 451 virtual bool eof();
446 - virtual int read(std::string& data); 452 + virtual int read(char* data, int nb_data, int* nb_read);
447 private: 453 private:
448 - virtual int read_chunked(std::string& data);  
449 - virtual int read_specified(int max, std::string& data); 454 + virtual int read_chunked(char* data, int nb_data, int* nb_read);
  455 + virtual int read_specified(char* data, int nb_data, int* nb_read);
450 }; 456 };
451 457
452 // for http header. 458 // for http header.
@@ -363,17 +363,16 @@ int SrsHttpHooks::on_hls_notify(std::string url, SrsRequest* req, std::string ts @@ -363,17 +363,16 @@ int SrsHttpHooks::on_hls_notify(std::string url, SrsRequest* req, std::string ts
363 } 363 }
364 SrsAutoFree(SrsHttpMessage, msg); 364 SrsAutoFree(SrsHttpMessage, msg);
365 365
  366 + int nb_read = 0;
366 ISrsHttpResponseReader* br = msg->body_reader(); 367 ISrsHttpResponseReader* br = msg->body_reader();
367 - while (!br->eof()) {  
368 - std::string data;  
369 - // for notify, only read some data.  
370 - ret = br->read(data);  
371 - break; 368 + if (!br->eof()) {
  369 + char buf[64]; // only read a little of bytes of ts.
  370 + ret = br->read(buf, 64, &nb_read);
372 } 371 }
373 372
374 int spenttime = (int)(srs_update_system_time_ms() - starttime); 373 int spenttime = (int)(srs_update_system_time_ms() - starttime);
375 - srs_trace("http hook on_hls_notify success. client_id=%d, url=%s, code=%d, spent=%dms, ret=%d",  
376 - client_id, url.c_str(), msg->status_code(), spenttime, ret); 374 + srs_trace("http hook on_hls_notify success. client_id=%d, url=%s, code=%d, spent=%dms, read=%dB, ret=%d",
  375 + client_id, url.c_str(), msg->status_code(), spenttime, nb_read, ret);
377 376
378 // ignore any error for on_hls_notify. 377 // ignore any error for on_hls_notify.
379 ret = ERROR_SUCCESS; 378 ret = ERROR_SUCCESS;