正在显示
9 个修改的文件
包含
223 行增加
和
123 行删除
| @@ -550,7 +550,8 @@ Supported operating systems and hardware: | @@ -550,7 +550,8 @@ Supported operating systems and hardware: | ||
| 550 | ## History | 550 | ## History |
| 551 | 551 | ||
| 552 | ### SRS 2.0 history | 552 | ### SRS 2.0 history |
| 553 | -. | 553 | + |
| 554 | +* v2.0, 2015-03-06, refine http request parse. 2.0.132. | ||
| 554 | * v2.0, 2015-03-01, for [#179](https://github.com/winlinvip/simple-rtmp-server/issues/179), revert dvr http api. 2.0.128. | 555 | * v2.0, 2015-03-01, for [#179](https://github.com/winlinvip/simple-rtmp-server/issues/179), revert dvr http api. 2.0.128. |
| 555 | * v2.0, 2015-02-24, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), fix hls bug, write pts/dts error. 2.0.124 | 556 | * v2.0, 2015-02-24, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), fix hls bug, write pts/dts error. 2.0.124 |
| 556 | * v2.0, 2015-02-19, refine dvr, append file when dvr file exists. 2.0.122. | 557 | * v2.0, 2015-02-19, refine dvr, append file when dvr file exists. 2.0.122. |
| @@ -39,6 +39,7 @@ using namespace std; | @@ -39,6 +39,7 @@ using namespace std; | ||
| 39 | #include <srs_rtmp_buffer.hpp> | 39 | #include <srs_rtmp_buffer.hpp> |
| 40 | #include <srs_kernel_file.hpp> | 40 | #include <srs_kernel_file.hpp> |
| 41 | #include <srs_core_autofree.hpp> | 41 | #include <srs_core_autofree.hpp> |
| 42 | +#include <srs_rtmp_buffer.hpp> | ||
| 42 | 43 | ||
| 43 | #define SRS_DEFAULT_HTTP_PORT 80 | 44 | #define SRS_DEFAULT_HTTP_PORT 80 |
| 44 | 45 | ||
| @@ -846,57 +847,152 @@ SrsHttpResponseReader::SrsHttpResponseReader(SrsHttpMessage* msg, SrsStSocket* i | @@ -846,57 +847,152 @@ SrsHttpResponseReader::SrsHttpResponseReader(SrsHttpMessage* msg, SrsStSocket* i | ||
| 846 | { | 847 | { |
| 847 | skt = io; | 848 | skt = io; |
| 848 | owner = msg; | 849 | owner = msg; |
| 849 | - cache = new SrsSimpleBuffer(); | 850 | + is_eof = false; |
| 851 | + nb_read = 0; | ||
| 852 | + buffer = NULL; | ||
| 850 | } | 853 | } |
| 851 | 854 | ||
| 852 | SrsHttpResponseReader::~SrsHttpResponseReader() | 855 | SrsHttpResponseReader::~SrsHttpResponseReader() |
| 853 | { | 856 | { |
| 854 | - srs_freep(cache); | ||
| 855 | } | 857 | } |
| 856 | 858 | ||
| 857 | -bool SrsHttpResponseReader::empty() | 859 | +int SrsHttpResponseReader::initialize(SrsFastBuffer* body) |
| 858 | { | 860 | { |
| 859 | - return cache->length() == 0; | 861 | + int ret = ERROR_SUCCESS; |
| 862 | + | ||
| 863 | + buffer = body; | ||
| 864 | + | ||
| 865 | + return ret; | ||
| 860 | } | 866 | } |
| 861 | 867 | ||
| 862 | -int SrsHttpResponseReader::append(char* data, int size) | 868 | +bool SrsHttpResponseReader::eof() |
| 869 | +{ | ||
| 870 | + return is_eof; | ||
| 871 | +} | ||
| 872 | + | ||
| 873 | +int SrsHttpResponseReader::read(std::string& data) | ||
| 863 | { | 874 | { |
| 864 | int ret = ERROR_SUCCESS; | 875 | int ret = ERROR_SUCCESS; |
| 865 | 876 | ||
| 866 | - cache->append(data, size); | 877 | + if (is_eof) { |
| 878 | + ret = ERROR_HTTP_RESPONSE_EOF; | ||
| 879 | + srs_error("http: response EOF. ret=%d", ret); | ||
| 880 | + return ret; | ||
| 881 | + } | ||
| 882 | + | ||
| 883 | + // chunked encoding. | ||
| 884 | + if (owner->is_chunked()) { | ||
| 885 | + return read_chunked(data); | ||
| 886 | + } | ||
| 867 | 887 | ||
| 888 | + // read by specified content-length | ||
| 889 | + int max = (int)owner->content_length() - nb_read; | ||
| 890 | + if (max <= 0) { | ||
| 891 | + is_eof = true; | ||
| 868 | return ret; | 892 | return ret; |
| 893 | + } | ||
| 894 | + return read_specified(max, data); | ||
| 869 | } | 895 | } |
| 870 | 896 | ||
| 871 | -int SrsHttpResponseReader::read(int max, std::string& data) | 897 | +int SrsHttpResponseReader::read_chunked(std::string& data) |
| 872 | { | 898 | { |
| 873 | int ret = ERROR_SUCCESS; | 899 | int ret = ERROR_SUCCESS; |
| 874 | 900 | ||
| 875 | - // TODO: FIXME: decode the chunked bytes. | 901 | + // parse the chunk length first. |
| 902 | + char* at = NULL; | ||
| 903 | + int length = 0; | ||
| 904 | + while (!at) { | ||
| 905 | + // find the CRLF of chunk header end. | ||
| 906 | + char* start = buffer->bytes(); | ||
| 907 | + char* end = start + buffer->size(); | ||
| 908 | + for (char* p = start; p < end - 1; p++) { | ||
| 909 | + if (p[0] == __SRS_HTTP_CR && p[1] == __SRS_HTTP_LF) { | ||
| 910 | + // invalid chunk, ignore. | ||
| 911 | + if (p == start) { | ||
| 912 | + ret = ERROR_HTTP_INVALID_CHUNK_HEADER; | ||
| 913 | + srs_error("chunk header start with CRLF. ret=%d", ret); | ||
| 914 | + return ret; | ||
| 915 | + } | ||
| 916 | + length = p - start + 2; | ||
| 917 | + at = buffer->read_slice(length); | ||
| 918 | + break; | ||
| 919 | + } | ||
| 920 | + } | ||
| 876 | 921 | ||
| 877 | - // read from cache first. | ||
| 878 | - if (cache->length() > 0) { | ||
| 879 | - int nb_bytes = srs_min(cache->length(), max); | ||
| 880 | - data.append(cache->bytes(), nb_bytes); | ||
| 881 | - cache->erase(nb_bytes); | 922 | + // got at, ok. |
| 923 | + if (at) { | ||
| 924 | + break; | ||
| 925 | + } | ||
| 882 | 926 | ||
| 927 | + // when empty, only grow 1bytes, but the buffer will cache more. | ||
| 928 | + if ((ret = buffer->grow(skt, buffer->size() + 1)) != ERROR_SUCCESS) { | ||
| 929 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 930 | + srs_error("read body from server failed. ret=%d", ret); | ||
| 931 | + } | ||
| 883 | return ret; | 932 | return ret; |
| 884 | } | 933 | } |
| 934 | + } | ||
| 935 | + srs_assert(length >= 3); | ||
| 885 | 936 | ||
| 886 | - // read some from underlayer. | ||
| 887 | - int left = srs_max(SRS_HTTP_BODY_BUFFER, max); | 937 | + // it's ok to set the pos and pos+1 to NULL. |
| 938 | + at[length - 1] = NULL; | ||
| 939 | + at[length - 2] = NULL; | ||
| 888 | 940 | ||
| 889 | - // read from io. | ||
| 890 | - char* buf = new char[left]; | ||
| 891 | - SrsAutoFree(char, buf); | 941 | + // size is the bytes size, excludes the chunk header and end CRLF. |
| 942 | + int ilength = ::strtol(at, NULL, 16); | ||
| 943 | + if (ilength < 0) { | ||
| 944 | + ret = ERROR_HTTP_INVALID_CHUNK_HEADER; | ||
| 945 | + srs_error("chunk header negative, length=%d. ret=%d", ilength, ret); | ||
| 946 | + return ret; | ||
| 947 | + } | ||
| 892 | 948 | ||
| 893 | - ssize_t nread = 0; | ||
| 894 | - if ((ret = skt->read(buf, left, &nread)) != ERROR_SUCCESS) { | 949 | + // when empty, only grow 1bytes, but the buffer will cache more. |
| 950 | + if ((ret = buffer->grow(skt, ilength + 2)) != ERROR_SUCCESS) { | ||
| 951 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 952 | + srs_error("read body from server failed. ret=%d", ret); | ||
| 953 | + } | ||
| 895 | return ret; | 954 | return ret; |
| 896 | } | 955 | } |
| 956 | + srs_trace("http: read %d chunk", ilength); | ||
| 897 | 957 | ||
| 898 | - if (nread) { | ||
| 899 | - data.append(buf, nread); | 958 | + // read payload when length specifies some payload. |
| 959 | + if (ilength <= 0) { | ||
| 960 | + is_eof = true; | ||
| 961 | + } else { | ||
| 962 | + srs_assert(ilength); | ||
| 963 | + data.append(buffer->read_slice(ilength), ilength); | ||
| 964 | + nb_read += ilength; | ||
| 965 | + } | ||
| 966 | + | ||
| 967 | + // the CRLF of chunk payload end. | ||
| 968 | + buffer->read_slice(2); | ||
| 969 | + | ||
| 970 | + return ret; | ||
| 971 | +} | ||
| 972 | + | ||
| 973 | +int SrsHttpResponseReader::read_specified(int max, std::string& data) | ||
| 974 | +{ | ||
| 975 | + int ret = ERROR_SUCCESS; | ||
| 976 | + | ||
| 977 | + if (buffer->size() <= 0) { | ||
| 978 | + // when empty, only grow 1bytes, but the buffer will cache more. | ||
| 979 | + if ((ret = buffer->grow(skt, 1)) != ERROR_SUCCESS) { | ||
| 980 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 981 | + srs_error("read body from server failed. ret=%d", ret); | ||
| 982 | + } | ||
| 983 | + return ret; | ||
| 984 | + } | ||
| 985 | + } | ||
| 986 | + | ||
| 987 | + int nb_bytes = srs_min(max, buffer->size()); | ||
| 988 | + | ||
| 989 | + srs_assert(nb_bytes); | ||
| 990 | + data.append(buffer->read_slice(nb_bytes), nb_bytes); | ||
| 991 | + nb_read += nb_bytes; | ||
| 992 | + | ||
| 993 | + // when read completed, eof. | ||
| 994 | + if (nb_read >= (int)owner->content_length()) { | ||
| 995 | + is_eof = true; | ||
| 900 | } | 996 | } |
| 901 | 997 | ||
| 902 | return ret; | 998 | return ret; |
| @@ -917,7 +1013,7 @@ SrsHttpMessage::~SrsHttpMessage() | @@ -917,7 +1013,7 @@ SrsHttpMessage::~SrsHttpMessage() | ||
| 917 | srs_freep(_http_ts_send_buffer); | 1013 | srs_freep(_http_ts_send_buffer); |
| 918 | } | 1014 | } |
| 919 | 1015 | ||
| 920 | -int SrsHttpMessage::initialize(string url, http_parser* header, string body, vector<SrsHttpHeaderField>& headers) | 1016 | +int SrsHttpMessage::update(string url, http_parser* header, SrsFastBuffer* body, vector<SrsHttpHeaderField>& headers) |
| 921 | { | 1017 | { |
| 922 | int ret = ERROR_SUCCESS; | 1018 | int ret = ERROR_SUCCESS; |
| 923 | 1019 | ||
| @@ -929,9 +1025,9 @@ int SrsHttpMessage::initialize(string url, http_parser* header, string body, vec | @@ -929,9 +1025,9 @@ int SrsHttpMessage::initialize(string url, http_parser* header, string body, vec | ||
| 929 | std::string transfer_encoding = get_request_header("Transfer-Encoding"); | 1025 | std::string transfer_encoding = get_request_header("Transfer-Encoding"); |
| 930 | chunked = (transfer_encoding == "chunked"); | 1026 | chunked = (transfer_encoding == "chunked"); |
| 931 | 1027 | ||
| 932 | - // TODO: FIXME: remove it, use fast buffer instead. | ||
| 933 | - if (!body.empty()) { | ||
| 934 | - _body->append((char*)body.data(), (int)body.length()); | 1028 | + // set the buffer. |
| 1029 | + if ((ret = _body->initialize(body)) != ERROR_SUCCESS) { | ||
| 1030 | + return ret; | ||
| 935 | } | 1031 | } |
| 936 | 1032 | ||
| 937 | // parse uri from url. | 1033 | // parse uri from url. |
| @@ -946,6 +1042,18 @@ int SrsHttpMessage::initialize(string url, http_parser* header, string body, vec | @@ -946,6 +1042,18 @@ int SrsHttpMessage::initialize(string url, http_parser* header, string body, vec | ||
| 946 | 1042 | ||
| 947 | // parse uri to schema/server:port/path?query | 1043 | // parse uri to schema/server:port/path?query |
| 948 | std::string uri = "http://" + host + _url; | 1044 | std::string uri = "http://" + host + _url; |
| 1045 | + | ||
| 1046 | + return update(uri); | ||
| 1047 | +} | ||
| 1048 | + | ||
| 1049 | +int SrsHttpMessage::update(string uri) | ||
| 1050 | +{ | ||
| 1051 | + int ret = ERROR_SUCCESS; | ||
| 1052 | + | ||
| 1053 | + if (uri.empty()) { | ||
| 1054 | + return ret; | ||
| 1055 | + } | ||
| 1056 | + | ||
| 949 | if ((ret = _uri->initialize(uri)) != ERROR_SUCCESS) { | 1057 | if ((ret = _uri->initialize(uri)) != ERROR_SUCCESS) { |
| 950 | return ret; | 1058 | return ret; |
| 951 | } | 1059 | } |
| @@ -1069,47 +1177,29 @@ string SrsHttpMessage::path() | @@ -1069,47 +1177,29 @@ string SrsHttpMessage::path() | ||
| 1069 | return _uri->get_path(); | 1177 | return _uri->get_path(); |
| 1070 | } | 1178 | } |
| 1071 | 1179 | ||
| 1072 | -int SrsHttpMessage::body_read_all(string body) | 1180 | +int SrsHttpMessage::body_read_all(string& body) |
| 1073 | { | 1181 | { |
| 1074 | int ret = ERROR_SUCCESS; | 1182 | int ret = ERROR_SUCCESS; |
| 1075 | 1183 | ||
| 1076 | - int64_t content_length = (int64_t)_header.content_length; | 1184 | + // chunked, always read with |
| 1185 | + if (chunked) { | ||
| 1186 | + return _body->read(body); | ||
| 1187 | + } | ||
| 1188 | + | ||
| 1189 | + int content_length = (int)(int64_t)_header.content_length; | ||
| 1077 | 1190 | ||
| 1078 | // ignore if not set, should be zero length body. | 1191 | // ignore if not set, should be zero length body. |
| 1079 | - if (content_length < 0) { | ||
| 1080 | - if (!_body->empty()) { | ||
| 1081 | - srs_warn("unspecified content-length with body cached."); | ||
| 1082 | - } else { | 1192 | + if (content_length <= 0) { |
| 1083 | srs_info("unspecified content-length with body empty."); | 1193 | srs_info("unspecified content-length with body empty."); |
| 1084 | - } | ||
| 1085 | return ret; | 1194 | return ret; |
| 1086 | } | 1195 | } |
| 1087 | 1196 | ||
| 1088 | // when content length specified, read specified length. | 1197 | // when content length specified, read specified length. |
| 1089 | - if (content_length > 0) { | ||
| 1090 | - int left = (int)content_length; | ||
| 1091 | - while (left > 0) { | ||
| 1092 | - int nb_read = (int)body.length(); | ||
| 1093 | - if ((ret = _body->read(left, body)) != ERROR_SUCCESS) { | 1198 | + int expect = content_length + (int)body.length(); |
| 1199 | + while ((int)body.length() < expect) { | ||
| 1200 | + if ((ret = _body->read(body)) != ERROR_SUCCESS) { | ||
| 1094 | return ret; | 1201 | return ret; |
| 1095 | } | 1202 | } |
| 1096 | - | ||
| 1097 | - left -= (int)body.length() - nb_read; | ||
| 1098 | - } | ||
| 1099 | - return ret; | ||
| 1100 | - } | ||
| 1101 | - | ||
| 1102 | - // chunked encoding, read util got size=0 chunk. | ||
| 1103 | - for (;;) { | ||
| 1104 | - int nb_read = (int)body.length(); | ||
| 1105 | - if ((ret = _body->read(0, body)) != ERROR_SUCCESS) { | ||
| 1106 | - return ret; | ||
| 1107 | - } | ||
| 1108 | - | ||
| 1109 | - // eof. | ||
| 1110 | - if (nb_read == (int)body.length()) { | ||
| 1111 | - break; | ||
| 1112 | - } | ||
| 1113 | } | 1203 | } |
| 1114 | 1204 | ||
| 1115 | return ret; | 1205 | return ret; |
| @@ -1173,10 +1263,12 @@ string SrsHttpMessage::get_request_header(string name) | @@ -1173,10 +1263,12 @@ string SrsHttpMessage::get_request_header(string name) | ||
| 1173 | 1263 | ||
| 1174 | SrsHttpParser::SrsHttpParser() | 1264 | SrsHttpParser::SrsHttpParser() |
| 1175 | { | 1265 | { |
| 1266 | + buffer = new SrsFastBuffer(); | ||
| 1176 | } | 1267 | } |
| 1177 | 1268 | ||
| 1178 | SrsHttpParser::~SrsHttpParser() | 1269 | SrsHttpParser::~SrsHttpParser() |
| 1179 | { | 1270 | { |
| 1271 | + srs_freep(buffer); | ||
| 1180 | } | 1272 | } |
| 1181 | 1273 | ||
| 1182 | int SrsHttpParser::initialize(enum http_parser_type type) | 1274 | int SrsHttpParser::initialize(enum http_parser_type type) |
| @@ -1213,7 +1305,7 @@ int SrsHttpParser::parse_message(SrsStSocket* skt, SrsHttpMessage** ppmsg) | @@ -1213,7 +1305,7 @@ int SrsHttpParser::parse_message(SrsStSocket* skt, SrsHttpMessage** ppmsg) | ||
| 1213 | header = http_parser(); | 1305 | header = http_parser(); |
| 1214 | url = ""; | 1306 | url = ""; |
| 1215 | headers.clear(); | 1307 | headers.clear(); |
| 1216 | - body = ""; | 1308 | + body_parsed = 0; |
| 1217 | 1309 | ||
| 1218 | // do parse | 1310 | // do parse |
| 1219 | if ((ret = parse_message_imp(skt)) != ERROR_SUCCESS) { | 1311 | if ((ret = parse_message_imp(skt)) != ERROR_SUCCESS) { |
| @@ -1227,7 +1319,7 @@ int SrsHttpParser::parse_message(SrsStSocket* skt, SrsHttpMessage** ppmsg) | @@ -1227,7 +1319,7 @@ int SrsHttpParser::parse_message(SrsStSocket* skt, SrsHttpMessage** ppmsg) | ||
| 1227 | SrsHttpMessage* msg = new SrsHttpMessage(skt); | 1319 | SrsHttpMessage* msg = new SrsHttpMessage(skt); |
| 1228 | 1320 | ||
| 1229 | // initalize http msg, parse url. | 1321 | // initalize http msg, parse url. |
| 1230 | - if ((ret = msg->initialize(url, &header, body, headers)) != ERROR_SUCCESS) { | 1322 | + if ((ret = msg->update(url, &header, buffer, headers)) != ERROR_SUCCESS) { |
| 1231 | srs_error("initialize http msg failed. ret=%d", ret); | 1323 | srs_error("initialize http msg failed. ret=%d", ret); |
| 1232 | srs_freep(msg); | 1324 | srs_freep(msg); |
| 1233 | return ret; | 1325 | return ret; |
| @@ -1243,36 +1335,29 @@ int SrsHttpParser::parse_message_imp(SrsStSocket* skt) | @@ -1243,36 +1335,29 @@ int SrsHttpParser::parse_message_imp(SrsStSocket* skt) | ||
| 1243 | { | 1335 | { |
| 1244 | int ret = ERROR_SUCCESS; | 1336 | int ret = ERROR_SUCCESS; |
| 1245 | 1337 | ||
| 1246 | - ssize_t nread = 0; | ||
| 1247 | - ssize_t nparsed = 0; | ||
| 1248 | - | ||
| 1249 | - char* buf = new char[SRS_HTTP_HEADER_BUFFER]; | ||
| 1250 | - SrsAutoFree(char, buf); | ||
| 1251 | - | ||
| 1252 | - // parser header. | ||
| 1253 | - for (;;) { | ||
| 1254 | - if ((ret = skt->read(buf, (size_t)sizeof(buf), &nread)) != ERROR_SUCCESS) { | 1338 | + while (true) { |
| 1339 | + if (buffer->size() <= 0) { | ||
| 1340 | + // when empty, only grow 1bytes, but the buffer will cache more. | ||
| 1341 | + if ((ret = buffer->grow(skt, 1)) != ERROR_SUCCESS) { | ||
| 1255 | if (!srs_is_client_gracefully_close(ret)) { | 1342 | if (!srs_is_client_gracefully_close(ret)) { |
| 1256 | srs_error("read body from server failed. ret=%d", ret); | 1343 | srs_error("read body from server failed. ret=%d", ret); |
| 1257 | } | 1344 | } |
| 1258 | return ret; | 1345 | return ret; |
| 1259 | } | 1346 | } |
| 1347 | + } | ||
| 1260 | 1348 | ||
| 1261 | - nparsed = http_parser_execute(&parser, &settings, buf, nread); | ||
| 1262 | - srs_info("read_size=%d, nparsed=%d", (int)nread, (int)nparsed); | 1349 | + int nb_header = srs_min(SRS_HTTP_HEADER_BUFFER, buffer->size()); |
| 1350 | + ssize_t nparsed = http_parser_execute(&parser, &settings, buffer->bytes(), nb_header); | ||
| 1351 | + srs_info("buffer=%d, nparsed=%d, body=%d", buffer->size(), (int)nparsed, body_parsed); | ||
| 1352 | + if (nparsed - body_parsed > 0) { | ||
| 1353 | + buffer->read_slice(nparsed - body_parsed); | ||
| 1354 | + } | ||
| 1263 | 1355 | ||
| 1264 | // ok atleast header completed, | 1356 | // ok atleast header completed, |
| 1265 | // never wait for body completed, for maybe chunked. | 1357 | // never wait for body completed, for maybe chunked. |
| 1266 | if (state == SrsHttpParseStateHeaderComplete || state == SrsHttpParseStateMessageComplete) { | 1358 | if (state == SrsHttpParseStateHeaderComplete || state == SrsHttpParseStateMessageComplete) { |
| 1267 | break; | 1359 | break; |
| 1268 | } | 1360 | } |
| 1269 | - | ||
| 1270 | - // when not complete, the parser should consume all bytes. | ||
| 1271 | - if (nparsed != nread) { | ||
| 1272 | - ret = ERROR_HTTP_PARSE_HEADER; | ||
| 1273 | - srs_error("parse response error, parsed(%d)!=read(%d), ret=%d", (int)nparsed, (int)nread, ret); | ||
| 1274 | - return ret; | ||
| 1275 | - } | ||
| 1276 | } | 1361 | } |
| 1277 | 1362 | ||
| 1278 | // parse last header. | 1363 | // parse last header. |
| @@ -1280,12 +1365,6 @@ int SrsHttpParser::parse_message_imp(SrsStSocket* skt) | @@ -1280,12 +1365,6 @@ int SrsHttpParser::parse_message_imp(SrsStSocket* skt) | ||
| 1280 | headers.push_back(std::make_pair(filed_name, field_value)); | 1365 | headers.push_back(std::make_pair(filed_name, field_value)); |
| 1281 | } | 1366 | } |
| 1282 | 1367 | ||
| 1283 | - // when parse completed, cache the left body. | ||
| 1284 | - if (nread && nparsed < nread) { | ||
| 1285 | - body.append(buf + nparsed, nread - nparsed); | ||
| 1286 | - srs_info("cache %d bytes read body.", nread - nparsed); | ||
| 1287 | - } | ||
| 1288 | - | ||
| 1289 | return ret; | 1368 | return ret; |
| 1290 | } | 1369 | } |
| 1291 | 1370 | ||
| @@ -1385,9 +1464,7 @@ int SrsHttpParser::on_body(http_parser* parser, const char* at, size_t length) | @@ -1385,9 +1464,7 @@ int SrsHttpParser::on_body(http_parser* parser, const char* at, size_t length) | ||
| 1385 | SrsHttpParser* obj = (SrsHttpParser*)parser->data; | 1464 | SrsHttpParser* obj = (SrsHttpParser*)parser->data; |
| 1386 | srs_assert(obj); | 1465 | srs_assert(obj); |
| 1387 | 1466 | ||
| 1388 | - if (length > 0) { | ||
| 1389 | - obj->body.append(at, (int)length); | ||
| 1390 | - } | 1467 | + obj->body_parsed += length; |
| 1391 | 1468 | ||
| 1392 | srs_info("Body: %.*s", (int)length, at); | 1469 | srs_info("Body: %.*s", (int)length, at); |
| 1393 | 1470 |
| @@ -192,10 +192,14 @@ public: | @@ -192,10 +192,14 @@ public: | ||
| 192 | virtual ~ISrsHttpResponseReader(); | 192 | virtual ~ISrsHttpResponseReader(); |
| 193 | public: | 193 | public: |
| 194 | /** | 194 | /** |
| 195 | + * whether response read EOF. | ||
| 196 | + */ | ||
| 197 | + virtual bool eof() = 0; | ||
| 198 | + /** | ||
| 195 | * read from the response body. | 199 | * read from the response body. |
| 196 | - * @param max the max size to read. 0 to ignore. | 200 | + * @remark when eof(), return error. |
| 197 | */ | 201 | */ |
| 198 | - virtual int read(int max, std::string& data) = 0; | 202 | + virtual int read(std::string& data) = 0; |
| 199 | }; | 203 | }; |
| 200 | 204 | ||
| 201 | // Objects implementing the Handler interface can be | 205 | // Objects implementing the Handler interface can be |
| @@ -394,24 +398,24 @@ class SrsHttpResponseReader : virtual public ISrsHttpResponseReader | @@ -394,24 +398,24 @@ class SrsHttpResponseReader : virtual public ISrsHttpResponseReader | ||
| 394 | private: | 398 | private: |
| 395 | SrsStSocket* skt; | 399 | SrsStSocket* skt; |
| 396 | SrsHttpMessage* owner; | 400 | SrsHttpMessage* owner; |
| 397 | - SrsSimpleBuffer* cache; | 401 | + SrsFastBuffer* buffer; |
| 402 | + bool is_eof; | ||
| 403 | + int64_t nb_read; | ||
| 398 | public: | 404 | public: |
| 399 | SrsHttpResponseReader(SrsHttpMessage* msg, SrsStSocket* io); | 405 | SrsHttpResponseReader(SrsHttpMessage* msg, SrsStSocket* io); |
| 400 | virtual ~SrsHttpResponseReader(); | 406 | virtual ~SrsHttpResponseReader(); |
| 401 | public: | 407 | public: |
| 402 | /** | 408 | /** |
| 403 | - * whether the cache is empty. | ||
| 404 | - */ | ||
| 405 | - virtual bool empty(); | ||
| 406 | - /** | ||
| 407 | - * append specified size of bytes data to reader. | ||
| 408 | - * when we read http message from socket, we maybe read header+body, | ||
| 409 | - * so the reader should provides stream cache feature. | 409 | + * initialize the response reader with buffer. |
| 410 | */ | 410 | */ |
| 411 | - virtual int append(char* data, int size); | 411 | + virtual int initialize(SrsFastBuffer* buffer); |
| 412 | // interface ISrsHttpResponseReader | 412 | // interface ISrsHttpResponseReader |
| 413 | public: | 413 | public: |
| 414 | - virtual int read(int max, std::string& data); | 414 | + virtual bool eof(); |
| 415 | + virtual int read(std::string& data); | ||
| 416 | +private: | ||
| 417 | + virtual int read_chunked(std::string& data); | ||
| 418 | + virtual int read_specified(int max, std::string& data); | ||
| 415 | }; | 419 | }; |
| 416 | 420 | ||
| 417 | // for http header. | 421 | // for http header. |
| @@ -453,6 +457,7 @@ private: | @@ -453,6 +457,7 @@ private: | ||
| 453 | /** | 457 | /** |
| 454 | * use a buffer to read and send ts file. | 458 | * use a buffer to read and send ts file. |
| 455 | */ | 459 | */ |
| 460 | + // TODO: FIXME: remove it. | ||
| 456 | char* _http_ts_send_buffer; | 461 | char* _http_ts_send_buffer; |
| 457 | // http headers | 462 | // http headers |
| 458 | std::vector<SrsHttpHeaderField> _headers; | 463 | std::vector<SrsHttpHeaderField> _headers; |
| @@ -463,11 +468,16 @@ public: | @@ -463,11 +468,16 @@ public: | ||
| 463 | virtual ~SrsHttpMessage(); | 468 | virtual ~SrsHttpMessage(); |
| 464 | public: | 469 | public: |
| 465 | /** | 470 | /** |
| 466 | - * set the original messages, then initialize the message. | 471 | + * set the original messages, then update the message. |
| 467 | */ | 472 | */ |
| 468 | - virtual int initialize(std::string url, http_parser* header, | ||
| 469 | - std::string body, std::vector<SrsHttpHeaderField>& headers | 473 | + virtual int update(std::string url, http_parser* header, |
| 474 | + SrsFastBuffer* body, std::vector<SrsHttpHeaderField>& headers | ||
| 470 | ); | 475 | ); |
| 476 | + /** | ||
| 477 | + * update the request with uri. | ||
| 478 | + * @remark user can invoke this multiple times. | ||
| 479 | + */ | ||
| 480 | + virtual int update(std::string uri); | ||
| 471 | public: | 481 | public: |
| 472 | virtual char* http_ts_send_buffer(); | 482 | virtual char* http_ts_send_buffer(); |
| 473 | public: | 483 | public: |
| @@ -485,7 +495,7 @@ public: | @@ -485,7 +495,7 @@ public: | ||
| 485 | virtual std::string host(); | 495 | virtual std::string host(); |
| 486 | virtual std::string path(); | 496 | virtual std::string path(); |
| 487 | public: | 497 | public: |
| 488 | - virtual int body_read_all(std::string body); | 498 | + virtual int body_read_all(std::string& body); |
| 489 | virtual ISrsHttpResponseReader* body_reader(); | 499 | virtual ISrsHttpResponseReader* body_reader(); |
| 490 | virtual int64_t content_length(); | 500 | virtual int64_t content_length(); |
| 491 | /** | 501 | /** |
| @@ -510,7 +520,7 @@ private: | @@ -510,7 +520,7 @@ private: | ||
| 510 | http_parser_settings settings; | 520 | http_parser_settings settings; |
| 511 | http_parser parser; | 521 | http_parser parser; |
| 512 | // the global parse buffer. | 522 | // the global parse buffer. |
| 513 | - SrsFastBuffer* fbuffer; | 523 | + SrsFastBuffer* buffer; |
| 514 | private: | 524 | private: |
| 515 | // http parse data, reset before parse message. | 525 | // http parse data, reset before parse message. |
| 516 | bool expect_filed_name; | 526 | bool expect_filed_name; |
| @@ -520,7 +530,7 @@ private: | @@ -520,7 +530,7 @@ private: | ||
| 520 | http_parser header; | 530 | http_parser header; |
| 521 | std::string url; | 531 | std::string url; |
| 522 | std::vector<SrsHttpHeaderField> headers; | 532 | std::vector<SrsHttpHeaderField> headers; |
| 523 | - std::string body; | 533 | + int body_parsed; |
| 524 | public: | 534 | public: |
| 525 | SrsHttpParser(); | 535 | SrsHttpParser(); |
| 526 | virtual ~SrsHttpParser(); | 536 | virtual ~SrsHttpParser(); |
| @@ -165,8 +165,14 @@ int SrsHttpClient::get(SrsHttpUri* uri, std::string req, SrsHttpMessage** ppmsg) | @@ -165,8 +165,14 @@ int SrsHttpClient::get(SrsHttpUri* uri, std::string req, SrsHttpMessage** ppmsg) | ||
| 165 | srs_error("parse http post response failed. ret=%d", ret); | 165 | srs_error("parse http post response failed. ret=%d", ret); |
| 166 | return ret; | 166 | return ret; |
| 167 | } | 167 | } |
| 168 | - | ||
| 169 | srs_assert(msg); | 168 | srs_assert(msg); |
| 169 | + | ||
| 170 | + // for GET, server response no uri, we update with request uri. | ||
| 171 | + if ((ret = msg->update(uri->get_url())) != ERROR_SUCCESS) { | ||
| 172 | + srs_freep(msg); | ||
| 173 | + return ret; | ||
| 174 | + } | ||
| 175 | + | ||
| 170 | *ppmsg = msg; | 176 | *ppmsg = msg; |
| 171 | srs_info("parse http get response success."); | 177 | srs_info("parse http get response success."); |
| 172 | 178 |
| @@ -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 2 | 32 | #define VERSION_MAJOR 2 |
| 33 | #define VERSION_MINOR 0 | 33 | #define VERSION_MINOR 0 |
| 34 | -#define VERSION_REVISION 131 | 34 | +#define VERSION_REVISION 132 |
| 35 | 35 | ||
| 36 | // server info. | 36 | // server info. |
| 37 | #define RTMP_SIG_SRS_KEY "SRS" | 37 | #define RTMP_SIG_SRS_KEY "SRS" |
| @@ -243,6 +243,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -243,6 +243,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 243 | #define ERROR_STREAM_CASTER_AVC_SPS 4022 | 243 | #define ERROR_STREAM_CASTER_AVC_SPS 4022 |
| 244 | #define ERROR_STREAM_CASTER_AVC_PPS 4023 | 244 | #define ERROR_STREAM_CASTER_AVC_PPS 4023 |
| 245 | #define ERROR_STREAM_CASTER_FLV_TAG 4024 | 245 | #define ERROR_STREAM_CASTER_FLV_TAG 4024 |
| 246 | +#define ERROR_HTTP_RESPONSE_EOF 4025 | ||
| 247 | +#define ERROR_HTTP_INVALID_CHUNK_HEADER 4026 | ||
| 246 | 248 | ||
| 247 | /** | 249 | /** |
| 248 | * whether the error code is an system control error. | 250 | * whether the error code is an system control error. |
| @@ -312,8 +312,6 @@ int run() | @@ -312,8 +312,6 @@ int run() | ||
| 312 | return run_master(); | 312 | return run_master(); |
| 313 | } | 313 | } |
| 314 | 314 | ||
| 315 | -#include <srs_app_http.hpp> | ||
| 316 | -#include <srs_app_http_client.hpp> | ||
| 317 | int run_master() | 315 | int run_master() |
| 318 | { | 316 | { |
| 319 | int ret = ERROR_SUCCESS; | 317 | int ret = ERROR_SUCCESS; |
| @@ -329,22 +327,6 @@ int run_master() | @@ -329,22 +327,6 @@ int run_master() | ||
| 329 | if ((ret = _srs_server->initialize_st()) != ERROR_SUCCESS) { | 327 | if ((ret = _srs_server->initialize_st()) != ERROR_SUCCESS) { |
| 330 | return ret; | 328 | return ret; |
| 331 | } | 329 | } |
| 332 | -/*SrsHttpClient client; | ||
| 333 | -SrsHttpUri uri; | ||
| 334 | -if ((ret = uri.initialize("http://ossrs.net:8081/live/livestream.flv")) != ERROR_SUCCESS) { | ||
| 335 | - return ret; | ||
| 336 | -} | ||
| 337 | -SrsHttpMessage* msg = NULL; | ||
| 338 | -if ((ret = client.get(&uri, "", &msg)) != ERROR_SUCCESS) { | ||
| 339 | - return ret; | ||
| 340 | -} | ||
| 341 | -for (;;) { | ||
| 342 | - ISrsHttpResponseReader* br = msg->body_reader(); | ||
| 343 | - std::string data; | ||
| 344 | - if ((ret = br->read(0, data)) != ERROR_SUCCESS) { | ||
| 345 | - return ret; | ||
| 346 | - } | ||
| 347 | -}*/ | ||
| 348 | 330 | ||
| 349 | if ((ret = _srs_server->listen()) != ERROR_SUCCESS) { | 331 | if ((ret = _srs_server->listen()) != ERROR_SUCCESS) { |
| 350 | return ret; | 332 | return ret; |
| @@ -62,6 +62,16 @@ SrsFastBuffer::SrsFastBuffer() | @@ -62,6 +62,16 @@ SrsFastBuffer::SrsFastBuffer() | ||
| 62 | p = end = buffer; | 62 | p = end = buffer; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | +int SrsFastBuffer::size() | ||
| 66 | +{ | ||
| 67 | + return end - p; | ||
| 68 | +} | ||
| 69 | + | ||
| 70 | +char* SrsFastBuffer::bytes() | ||
| 71 | +{ | ||
| 72 | + return p; | ||
| 73 | +} | ||
| 74 | + | ||
| 65 | void SrsFastBuffer::set_buffer(int buffer_size) | 75 | void SrsFastBuffer::set_buffer(int buffer_size) |
| 66 | { | 76 | { |
| 67 | // the user-space buffer size limit to a max value. | 77 | // the user-space buffer size limit to a max value. |
| @@ -86,6 +86,16 @@ public: | @@ -86,6 +86,16 @@ public: | ||
| 86 | virtual ~SrsFastBuffer(); | 86 | virtual ~SrsFastBuffer(); |
| 87 | public: | 87 | public: |
| 88 | /** | 88 | /** |
| 89 | + * get the size of current bytes in buffer. | ||
| 90 | + */ | ||
| 91 | + virtual int size(); | ||
| 92 | + /** | ||
| 93 | + * get the current bytes in buffer. | ||
| 94 | + * @remark user should use read_slice() if possible, | ||
| 95 | + * the bytes() is used to test bytes, for example, to detect the bytes schema. | ||
| 96 | + */ | ||
| 97 | + virtual char* bytes(); | ||
| 98 | + /** | ||
| 89 | * create buffer with specifeid size. | 99 | * create buffer with specifeid size. |
| 90 | * @param buffer the size of buffer. | 100 | * @param buffer the size of buffer. |
| 91 | * @remark when MR(SRS_PERF_MERGED_READ) disabled, always set to 8K. | 101 | * @remark when MR(SRS_PERF_MERGED_READ) disabled, always set to 8K. |
| @@ -110,6 +120,8 @@ public: | @@ -110,6 +120,8 @@ public: | ||
| 110 | * skip some bytes in buffer. | 120 | * skip some bytes in buffer. |
| 111 | * @param size the bytes to skip. positive to next; negative to previous. | 121 | * @param size the bytes to skip. positive to next; negative to previous. |
| 112 | * @remark assert buffer already grow(size). | 122 | * @remark assert buffer already grow(size). |
| 123 | + * @remark always use read_slice to consume bytes, which will reset for EOF. | ||
| 124 | + * while skip never consume bytes. | ||
| 113 | */ | 125 | */ |
| 114 | virtual void skip(int size); | 126 | virtual void skip(int size); |
| 115 | public: | 127 | public: |
-
请 注册 或 登录 后发表评论