正在显示
3 个修改的文件
包含
118 行增加
和
72 行删除
| @@ -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,95 +929,115 @@ int SrsHttpResponseReader::read(std::string& data) | @@ -923,95 +929,115 @@ 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. |
| 943 | - char* at = NULL; | ||
| 944 | - int length = 0; | ||
| 945 | - while (!at) { | ||
| 946 | - // find the CRLF of chunk header end. | ||
| 947 | - char* start = buffer->bytes(); | ||
| 948 | - char* end = start + buffer->size(); | ||
| 949 | - for (char* p = start; p < end - 1; p++) { | ||
| 950 | - if (p[0] == SRS_HTTP_CR && p[1] == SRS_HTTP_LF) { | ||
| 951 | - // invalid chunk, ignore. | ||
| 952 | - if (p == start) { | ||
| 953 | - ret = ERROR_HTTP_INVALID_CHUNK_HEADER; | ||
| 954 | - srs_error("chunk header start with CRLF. ret=%d", ret); | ||
| 955 | - return ret; | 953 | + if (nb_left_chunk <= 0) { |
| 954 | + char* at = NULL; | ||
| 955 | + int length = 0; | ||
| 956 | + while (!at) { | ||
| 957 | + // find the CRLF of chunk header end. | ||
| 958 | + char* start = buffer->bytes(); | ||
| 959 | + char* end = start + buffer->size(); | ||
| 960 | + for (char* p = start; p < end - 1; p++) { | ||
| 961 | + if (p[0] == SRS_HTTP_CR && p[1] == SRS_HTTP_LF) { | ||
| 962 | + // invalid chunk, ignore. | ||
| 963 | + if (p == start) { | ||
| 964 | + ret = ERROR_HTTP_INVALID_CHUNK_HEADER; | ||
| 965 | + srs_error("chunk header start with CRLF. ret=%d", ret); | ||
| 966 | + return ret; | ||
| 967 | + } | ||
| 968 | + length = (int)(p - start + 2); | ||
| 969 | + at = buffer->read_slice(length); | ||
| 970 | + break; | ||
| 956 | } | 971 | } |
| 957 | - length = (int)(p - start + 2); | ||
| 958 | - at = buffer->read_slice(length); | 972 | + } |
| 973 | + | ||
| 974 | + // got at, ok. | ||
| 975 | + if (at) { | ||
| 959 | break; | 976 | break; |
| 960 | } | 977 | } |
| 978 | + | ||
| 979 | + // when empty, only grow 1bytes, but the buffer will cache more. | ||
| 980 | + if ((ret = buffer->grow(skt, buffer->size() + 1)) != ERROR_SUCCESS) { | ||
| 981 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 982 | + srs_error("read body from server failed. ret=%d", ret); | ||
| 983 | + } | ||
| 984 | + return ret; | ||
| 985 | + } | ||
| 961 | } | 986 | } |
| 987 | + srs_assert(length >= 3); | ||
| 962 | 988 | ||
| 963 | - // got at, ok. | ||
| 964 | - if (at) { | ||
| 965 | - break; | ||
| 966 | - } | 989 | + // it's ok to set the pos and pos+1 to NULL. |
| 990 | + at[length - 1] = 0; | ||
| 991 | + at[length - 2] = 0; | ||
| 967 | 992 | ||
| 968 | - // when empty, only grow 1bytes, but the buffer will cache more. | ||
| 969 | - if ((ret = buffer->grow(skt, buffer->size() + 1)) != ERROR_SUCCESS) { | ||
| 970 | - if (!srs_is_client_gracefully_close(ret)) { | ||
| 971 | - srs_error("read body from server failed. ret=%d", ret); | ||
| 972 | - } | 993 | + // size is the bytes size, excludes the chunk header and end CRLF. |
| 994 | + int ilength = (int)::strtol(at, NULL, 16); | ||
| 995 | + if (ilength < 0) { | ||
| 996 | + ret = ERROR_HTTP_INVALID_CHUNK_HEADER; | ||
| 997 | + srs_error("chunk header negative, length=%d. ret=%d", ilength, ret); | ||
| 973 | return ret; | 998 | return ret; |
| 974 | } | 999 | } |
| 1000 | + | ||
| 1001 | + // all bytes in chunk is left now. | ||
| 1002 | + nb_left_chunk = ilength; | ||
| 975 | } | 1003 | } |
| 976 | - srs_assert(length >= 3); | ||
| 977 | 1004 | ||
| 978 | - // it's ok to set the pos and pos+1 to NULL. | ||
| 979 | - at[length - 1] = 0; | ||
| 980 | - at[length - 2] = 0; | 1005 | + // left bytes in chunk, read some. |
| 1006 | + srs_assert(nb_left_chunk); | ||
| 981 | 1007 | ||
| 982 | - // size is the bytes size, excludes the chunk header and end CRLF. | ||
| 983 | - int ilength = (int)::strtol(at, NULL, 16); | ||
| 984 | - if (ilength < 0) { | ||
| 985 | - ret = ERROR_HTTP_INVALID_CHUNK_HEADER; | ||
| 986 | - srs_error("chunk header negative, length=%d. ret=%d", ilength, ret); | ||
| 987 | - return ret; | 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; | ||
| 988 | } | 1014 | } |
| 1015 | + nb_left_chunk -= nb_bytes; | ||
| 989 | 1016 | ||
| 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); | ||
| 994 | - } | 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; |
| @@ -196,10 +196,13 @@ public: | @@ -196,10 +196,13 @@ public: | ||
| 196 | */ | 196 | */ |
| 197 | virtual bool eof() = 0; | 197 | virtual bool eof() = 0; |
| 198 | /** | 198 | /** |
| 199 | - * read from the response body. | ||
| 200 | - * @remark when eof(), return error. | ||
| 201 | - */ | ||
| 202 | - virtual int read(std::string& data) = 0; | 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. | ||
| 203 | + * @remark when eof(), return error. | ||
| 204 | + */ | ||
| 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; |
-
请 注册 或 登录 后发表评论