正在显示
9 个修改的文件
包含
190 行增加
和
16 行删除
| @@ -409,7 +409,7 @@ LIBS_OBJS="${MODULE_OBJS[@]}" | @@ -409,7 +409,7 @@ LIBS_OBJS="${MODULE_OBJS[@]}" | ||
| 409 | if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then | 409 | if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then |
| 410 | MODULE_ID="MAIN" | 410 | MODULE_ID="MAIN" |
| 411 | MODULE_DEPENDS=("CORE" "KERNEL" "RTMP" "APP") | 411 | MODULE_DEPENDS=("CORE" "KERNEL" "RTMP" "APP") |
| 412 | - ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibGperfRoot}) | 412 | + ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibGperfRoot} ${LibHttpParserRoot}) |
| 413 | MODULE_FILES=("srs_main_server") | 413 | MODULE_FILES=("srs_main_server") |
| 414 | MAIN_INCS="src/main"; MODULE_DIR=${MAIN_INCS} . auto/modules.sh | 414 | MAIN_INCS="src/main"; MODULE_DIR=${MAIN_INCS} . auto/modules.sh |
| 415 | MAIN_OBJS="${MODULE_OBJS[@]}" | 415 | MAIN_OBJS="${MODULE_OBJS[@]}" |
| 1 | <?xml version="1.0" encoding="UTF-8"?> | 1 | <?xml version="1.0" encoding="UTF-8"?> |
| 2 | <!DOCTYPE QtCreatorProject> | 2 | <!DOCTYPE QtCreatorProject> |
| 3 | -<!-- Written by QtCreator 3.1.1, 2015-01-29T11:22:06. --> | 3 | +<!-- Written by QtCreator 3.1.1, 2015-03-05T20:44:44. --> |
| 4 | <qtcreator> | 4 | <qtcreator> |
| 5 | <data> | 5 | <data> |
| 6 | <variable>ProjectExplorer.Project.ActiveTarget</variable> | 6 | <variable>ProjectExplorer.Project.ActiveTarget</variable> |
| @@ -56,12 +56,12 @@ | @@ -56,12 +56,12 @@ | ||
| 56 | <valuemap type="QVariantMap"> | 56 | <valuemap type="QVariantMap"> |
| 57 | <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value> | 57 | <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value> |
| 58 | <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value> | 58 | <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value> |
| 59 | - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{fa2d28f9-85de-4a75-8e79-69d805f974bf}</value> | 59 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{fdda5a74-8ef6-4e67-b28c-c5be6c667578}</value> |
| 60 | <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value> | 60 | <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value> |
| 61 | <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value> | 61 | <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value> |
| 62 | <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value> | 62 | <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value> |
| 63 | <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0"> | 63 | <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0"> |
| 64 | - <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/winlin/git/simple-rtmp-server/trunk/src/build-qt-Desktop-Debug</value> | 64 | + <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/winlin/git/simple-rtmp-server/trunk/ide/build-srs-qt-Desktop-Debug</value> |
| 65 | <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | 65 | <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> |
| 66 | <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | 66 | <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> |
| 67 | <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | 67 | <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> |
| @@ -119,7 +119,66 @@ | @@ -119,7 +119,66 @@ | ||
| 119 | <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value> | 119 | <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value> |
| 120 | <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value> | 120 | <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value> |
| 121 | </valuemap> | 121 | </valuemap> |
| 122 | - <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value> | 122 | + <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1"> |
| 123 | + <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/winlin/git/simple-rtmp-server/trunk/ide/build-srs-qt-Desktop-Release</value> | ||
| 124 | + <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | ||
| 125 | + <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | ||
| 126 | + <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | ||
| 127 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value> | ||
| 128 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> | ||
| 129 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> | ||
| 130 | + <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value> | ||
| 131 | + <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value> | ||
| 132 | + <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value> | ||
| 133 | + <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> | ||
| 134 | + </valuemap> | ||
| 135 | + <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> | ||
| 136 | + <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | ||
| 137 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value> | ||
| 138 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> | ||
| 139 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | ||
| 140 | + <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments"> | ||
| 141 | + <value type="QString">-w</value> | ||
| 142 | + <value type="QString">-r</value> | ||
| 143 | + </valuelist> | ||
| 144 | + <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value> | ||
| 145 | + <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value> | ||
| 146 | + <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | ||
| 147 | + </valuemap> | ||
| 148 | + <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> | ||
| 149 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value> | ||
| 150 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> | ||
| 151 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> | ||
| 152 | + </valuemap> | ||
| 153 | + <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> | ||
| 154 | + <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> | ||
| 155 | + <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> | ||
| 156 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value> | ||
| 157 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> | ||
| 158 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> | ||
| 159 | + <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments"> | ||
| 160 | + <value type="QString">-w</value> | ||
| 161 | + <value type="QString">-r</value> | ||
| 162 | + </valuelist> | ||
| 163 | + <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value> | ||
| 164 | + <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> | ||
| 165 | + <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> | ||
| 166 | + </valuemap> | ||
| 167 | + <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> | ||
| 168 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value> | ||
| 169 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> | ||
| 170 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> | ||
| 171 | + </valuemap> | ||
| 172 | + <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> | ||
| 173 | + <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> | ||
| 174 | + <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> | ||
| 175 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value> | ||
| 176 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> | ||
| 177 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> | ||
| 178 | + <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value> | ||
| 179 | + <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value> | ||
| 180 | + </valuemap> | ||
| 181 | + <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value> | ||
| 123 | <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0"> | 182 | <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0"> |
| 124 | <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> | 183 | <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> |
| 125 | <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value> | 184 | <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value> |
| @@ -172,13 +231,13 @@ | @@ -172,13 +231,13 @@ | ||
| 172 | <value type="int" key="PE.EnvironmentAspect.Base">2</value> | 231 | <value type="int" key="PE.EnvironmentAspect.Base">2</value> |
| 173 | <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/> | 232 | <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/> |
| 174 | <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">srs-qt</value> | 233 | <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">srs-qt</value> |
| 175 | - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">srs-qt2</value> | 234 | + <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> |
| 176 | <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/winlin/git/simple-rtmp-server/trunk/ide/srs_qt/srs-qt.pro</value> | 235 | <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/winlin/git/simple-rtmp-server/trunk/ide/srs_qt/srs-qt.pro</value> |
| 177 | - <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments">-c console.conf</value> | 236 | + <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value> |
| 178 | <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">srs-qt.pro</value> | 237 | <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">srs-qt.pro</value> |
| 179 | <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value> | 238 | <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value> |
| 180 | <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">true</value> | 239 | <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">true</value> |
| 181 | - <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory">/home/winlin/srs</value> | 240 | + <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value> |
| 182 | <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value> | 241 | <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value> |
| 183 | <value type="bool" key="RunConfiguration.UseCppDebugger">false</value> | 242 | <value type="bool" key="RunConfiguration.UseCppDebugger">false</value> |
| 184 | <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value> | 243 | <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value> |
| @@ -904,6 +904,7 @@ int SrsHttpResponseReader::read(int max, std::string& data) | @@ -904,6 +904,7 @@ int SrsHttpResponseReader::read(int max, std::string& data) | ||
| 904 | 904 | ||
| 905 | SrsHttpMessage::SrsHttpMessage(SrsStSocket* io) | 905 | SrsHttpMessage::SrsHttpMessage(SrsStSocket* io) |
| 906 | { | 906 | { |
| 907 | + chunked = false; | ||
| 907 | _uri = new SrsHttpUri(); | 908 | _uri = new SrsHttpUri(); |
| 908 | _body = new SrsHttpResponseReader(this, io); | 909 | _body = new SrsHttpResponseReader(this, io); |
| 909 | _http_ts_send_buffer = new char[__SRS_HTTP_TS_SEND_BUFFER_SIZE]; | 910 | _http_ts_send_buffer = new char[__SRS_HTTP_TS_SEND_BUFFER_SIZE]; |
| @@ -924,6 +925,11 @@ int SrsHttpMessage::initialize(string url, http_parser* header, string body, vec | @@ -924,6 +925,11 @@ int SrsHttpMessage::initialize(string url, http_parser* header, string body, vec | ||
| 924 | _header = *header; | 925 | _header = *header; |
| 925 | _headers = headers; | 926 | _headers = headers; |
| 926 | 927 | ||
| 928 | + // whether chunked. | ||
| 929 | + std::string transfer_encoding = get_request_header("Transfer-Encoding"); | ||
| 930 | + chunked = (transfer_encoding == "chunked"); | ||
| 931 | + | ||
| 932 | + // TODO: FIXME: remove it, use fast buffer instead. | ||
| 927 | if (!body.empty()) { | 933 | if (!body.empty()) { |
| 928 | _body->append((char*)body.data(), (int)body.length()); | 934 | _body->append((char*)body.data(), (int)body.length()); |
| 929 | } | 935 | } |
| @@ -1031,6 +1037,11 @@ bool SrsHttpMessage::is_http_options() | @@ -1031,6 +1037,11 @@ bool SrsHttpMessage::is_http_options() | ||
| 1031 | return _header.method == SRS_CONSTS_HTTP_OPTIONS; | 1037 | return _header.method == SRS_CONSTS_HTTP_OPTIONS; |
| 1032 | } | 1038 | } |
| 1033 | 1039 | ||
| 1040 | +bool SrsHttpMessage::is_chunked() | ||
| 1041 | +{ | ||
| 1042 | + return chunked; | ||
| 1043 | +} | ||
| 1044 | + | ||
| 1034 | string SrsHttpMessage::uri() | 1045 | string SrsHttpMessage::uri() |
| 1035 | { | 1046 | { |
| 1036 | std::string uri = _uri->get_schema(); | 1047 | std::string uri = _uri->get_schema(); |
| @@ -1104,6 +1115,11 @@ int SrsHttpMessage::body_read_all(string body) | @@ -1104,6 +1115,11 @@ int SrsHttpMessage::body_read_all(string body) | ||
| 1104 | return ret; | 1115 | return ret; |
| 1105 | } | 1116 | } |
| 1106 | 1117 | ||
| 1118 | +ISrsHttpResponseReader* SrsHttpMessage::body_reader() | ||
| 1119 | +{ | ||
| 1120 | + return _body; | ||
| 1121 | +} | ||
| 1122 | + | ||
| 1107 | int64_t SrsHttpMessage::content_length() | 1123 | int64_t SrsHttpMessage::content_length() |
| 1108 | { | 1124 | { |
| 1109 | return _header.content_length; | 1125 | return _header.content_length; |
| @@ -1258,6 +1274,11 @@ int SrsHttpParser::parse_message_imp(SrsStSocket* skt) | @@ -1258,6 +1274,11 @@ int SrsHttpParser::parse_message_imp(SrsStSocket* skt) | ||
| 1258 | return ret; | 1274 | return ret; |
| 1259 | } | 1275 | } |
| 1260 | } | 1276 | } |
| 1277 | + | ||
| 1278 | + // parse last header. | ||
| 1279 | + if (!filed_name.empty() && !field_value.empty()) { | ||
| 1280 | + headers.push_back(std::make_pair(filed_name, field_value)); | ||
| 1281 | + } | ||
| 1261 | 1282 | ||
| 1262 | // when parse completed, cache the left body. | 1283 | // when parse completed, cache the left body. |
| 1263 | if (nread && nparsed < nread) { | 1284 | if (nread && nparsed < nread) { |
| @@ -1341,7 +1362,7 @@ int SrsHttpParser::on_header_field(http_parser* parser, const char* at, size_t l | @@ -1341,7 +1362,7 @@ int SrsHttpParser::on_header_field(http_parser* parser, const char* at, size_t l | ||
| 1341 | obj->filed_name.append(at, (int)length); | 1362 | obj->filed_name.append(at, (int)length); |
| 1342 | } | 1363 | } |
| 1343 | 1364 | ||
| 1344 | - srs_trace("Header field(%d bytes): %.*s", (int)length, (int)length, at); | 1365 | + srs_info("Header field(%d bytes): %.*s", (int)length, (int)length, at); |
| 1345 | return 0; | 1366 | return 0; |
| 1346 | } | 1367 | } |
| 1347 | 1368 | ||
| @@ -1355,7 +1376,7 @@ int SrsHttpParser::on_header_value(http_parser* parser, const char* at, size_t l | @@ -1355,7 +1376,7 @@ int SrsHttpParser::on_header_value(http_parser* parser, const char* at, size_t l | ||
| 1355 | } | 1376 | } |
| 1356 | obj->expect_filed_name = false; | 1377 | obj->expect_filed_name = false; |
| 1357 | 1378 | ||
| 1358 | - srs_trace("Header value(%d bytes): %.*s", (int)length, (int)length, at); | 1379 | + srs_info("Header value(%d bytes): %.*s", (int)length, (int)length, at); |
| 1359 | return 0; | 1380 | return 0; |
| 1360 | } | 1381 | } |
| 1361 | 1382 |
| @@ -49,6 +49,7 @@ class SrsFileReader; | @@ -49,6 +49,7 @@ class SrsFileReader; | ||
| 49 | class SrsSimpleBuffer; | 49 | class SrsSimpleBuffer; |
| 50 | class SrsHttpMuxEntry; | 50 | class SrsHttpMuxEntry; |
| 51 | class ISrsHttpResponseWriter; | 51 | class ISrsHttpResponseWriter; |
| 52 | +class SrsFastBuffer; | ||
| 52 | 53 | ||
| 53 | // http specification | 54 | // http specification |
| 54 | // CR = <US-ASCII CR, carriage return (13)> | 55 | // CR = <US-ASCII CR, carriage return (13)> |
| @@ -442,6 +443,10 @@ private: | @@ -442,6 +443,10 @@ private: | ||
| 442 | */ | 443 | */ |
| 443 | SrsHttpResponseReader* _body; | 444 | SrsHttpResponseReader* _body; |
| 444 | /** | 445 | /** |
| 446 | + * whether the body is chunked. | ||
| 447 | + */ | ||
| 448 | + bool chunked; | ||
| 449 | + /** | ||
| 445 | * uri parser | 450 | * uri parser |
| 446 | */ | 451 | */ |
| 447 | SrsHttpUri* _uri; | 452 | SrsHttpUri* _uri; |
| @@ -474,12 +479,14 @@ public: | @@ -474,12 +479,14 @@ public: | ||
| 474 | virtual bool is_http_post(); | 479 | virtual bool is_http_post(); |
| 475 | virtual bool is_http_delete(); | 480 | virtual bool is_http_delete(); |
| 476 | virtual bool is_http_options(); | 481 | virtual bool is_http_options(); |
| 482 | + virtual bool is_chunked(); | ||
| 477 | virtual std::string uri(); | 483 | virtual std::string uri(); |
| 478 | virtual std::string url(); | 484 | virtual std::string url(); |
| 479 | virtual std::string host(); | 485 | virtual std::string host(); |
| 480 | virtual std::string path(); | 486 | virtual std::string path(); |
| 481 | public: | 487 | public: |
| 482 | virtual int body_read_all(std::string body); | 488 | virtual int body_read_all(std::string body); |
| 489 | + virtual ISrsHttpResponseReader* body_reader(); | ||
| 483 | virtual int64_t content_length(); | 490 | virtual int64_t content_length(); |
| 484 | /** | 491 | /** |
| 485 | * get the param in query string, | 492 | * get the param in query string, |
| @@ -502,6 +509,8 @@ class SrsHttpParser | @@ -502,6 +509,8 @@ class SrsHttpParser | ||
| 502 | private: | 509 | private: |
| 503 | http_parser_settings settings; | 510 | http_parser_settings settings; |
| 504 | http_parser parser; | 511 | http_parser parser; |
| 512 | + // the global parse buffer. | ||
| 513 | + SrsFastBuffer* fbuffer; | ||
| 505 | private: | 514 | private: |
| 506 | // http parse data, reset before parse message. | 515 | // http parse data, reset before parse message. |
| 507 | bool expect_filed_name; | 516 | bool expect_filed_name; |
| @@ -45,6 +45,7 @@ SrsHttpClient::SrsHttpClient() | @@ -45,6 +45,7 @@ SrsHttpClient::SrsHttpClient() | ||
| 45 | connected = false; | 45 | connected = false; |
| 46 | stfd = NULL; | 46 | stfd = NULL; |
| 47 | parser = NULL; | 47 | parser = NULL; |
| 48 | + skt = NULL; | ||
| 48 | } | 49 | } |
| 49 | 50 | ||
| 50 | SrsHttpClient::~SrsHttpClient() | 51 | SrsHttpClient::~SrsHttpClient() |
| @@ -86,10 +87,8 @@ int SrsHttpClient::post(SrsHttpUri* uri, string req, int& status_code, string& r | @@ -86,10 +87,8 @@ int SrsHttpClient::post(SrsHttpUri* uri, string req, int& status_code, string& r | ||
| 86 | << __SRS_HTTP_CRLF | 87 | << __SRS_HTTP_CRLF |
| 87 | << req; | 88 | << req; |
| 88 | 89 | ||
| 89 | - SrsStSocket skt(stfd); | ||
| 90 | - | ||
| 91 | std::string data = ss.str(); | 90 | std::string data = ss.str(); |
| 92 | - if ((ret = skt.write((void*)data.c_str(), data.length(), NULL)) != ERROR_SUCCESS) { | 91 | + if ((ret = skt->write((void*)data.c_str(), data.length(), NULL)) != ERROR_SUCCESS) { |
| 93 | // disconnect when error. | 92 | // disconnect when error. |
| 94 | disconnect(); | 93 | disconnect(); |
| 95 | 94 | ||
| @@ -98,7 +97,7 @@ int SrsHttpClient::post(SrsHttpUri* uri, string req, int& status_code, string& r | @@ -98,7 +97,7 @@ int SrsHttpClient::post(SrsHttpUri* uri, string req, int& status_code, string& r | ||
| 98 | } | 97 | } |
| 99 | 98 | ||
| 100 | SrsHttpMessage* msg = NULL; | 99 | SrsHttpMessage* msg = NULL; |
| 101 | - if ((ret = parser->parse_message(&skt, &msg)) != ERROR_SUCCESS) { | 100 | + if ((ret = parser->parse_message(skt, &msg)) != ERROR_SUCCESS) { |
| 102 | srs_error("parse http post response failed. ret=%d", ret); | 101 | srs_error("parse http post response failed. ret=%d", ret); |
| 103 | return ret; | 102 | return ret; |
| 104 | } | 103 | } |
| @@ -119,11 +118,67 @@ int SrsHttpClient::post(SrsHttpUri* uri, string req, int& status_code, string& r | @@ -119,11 +118,67 @@ int SrsHttpClient::post(SrsHttpUri* uri, string req, int& status_code, string& r | ||
| 119 | return ret; | 118 | return ret; |
| 120 | } | 119 | } |
| 121 | 120 | ||
| 121 | +int SrsHttpClient::get(SrsHttpUri* uri, std::string req, SrsHttpMessage** ppmsg) | ||
| 122 | +{ | ||
| 123 | + *ppmsg = NULL; | ||
| 124 | + | ||
| 125 | + int ret = ERROR_SUCCESS; | ||
| 126 | + | ||
| 127 | + if (!parser) { | ||
| 128 | + parser = new SrsHttpParser(); | ||
| 129 | + | ||
| 130 | + if ((ret = parser->initialize(HTTP_RESPONSE)) != ERROR_SUCCESS) { | ||
| 131 | + srs_error("initialize parser failed. ret=%d", ret); | ||
| 132 | + return ret; | ||
| 133 | + } | ||
| 134 | + } | ||
| 135 | + | ||
| 136 | + if ((ret = connect(uri)) != ERROR_SUCCESS) { | ||
| 137 | + srs_warn("http connect server failed. ret=%d", ret); | ||
| 138 | + return ret; | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + // send POST request to uri | ||
| 142 | + // GET %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d\r\n\r\n%s | ||
| 143 | + std::stringstream ss; | ||
| 144 | + ss << "GET " << uri->get_path() << " " | ||
| 145 | + << "HTTP/1.1" << __SRS_HTTP_CRLF | ||
| 146 | + << "Host: " << uri->get_host() << __SRS_HTTP_CRLF | ||
| 147 | + << "Connection: Keep-Alive" << __SRS_HTTP_CRLF | ||
| 148 | + << "Content-Length: " << std::dec << req.length() << __SRS_HTTP_CRLF | ||
| 149 | + << "User-Agent: " << RTMP_SIG_SRS_NAME << RTMP_SIG_SRS_VERSION << __SRS_HTTP_CRLF | ||
| 150 | + << "Content-Type: application/json" << __SRS_HTTP_CRLF | ||
| 151 | + << __SRS_HTTP_CRLF | ||
| 152 | + << req; | ||
| 153 | + | ||
| 154 | + std::string data = ss.str(); | ||
| 155 | + if ((ret = skt->write((void*)data.c_str(), data.length(), NULL)) != ERROR_SUCCESS) { | ||
| 156 | + // disconnect when error. | ||
| 157 | + disconnect(); | ||
| 158 | + | ||
| 159 | + srs_error("write http get failed. ret=%d", ret); | ||
| 160 | + return ret; | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + SrsHttpMessage* msg = NULL; | ||
| 164 | + if ((ret = parser->parse_message(skt, &msg)) != ERROR_SUCCESS) { | ||
| 165 | + srs_error("parse http post response failed. ret=%d", ret); | ||
| 166 | + return ret; | ||
| 167 | + } | ||
| 168 | + | ||
| 169 | + srs_assert(msg); | ||
| 170 | + *ppmsg = msg; | ||
| 171 | + srs_info("parse http get response success."); | ||
| 172 | + | ||
| 173 | + return ret; | ||
| 174 | +} | ||
| 175 | + | ||
| 122 | void SrsHttpClient::disconnect() | 176 | void SrsHttpClient::disconnect() |
| 123 | { | 177 | { |
| 124 | connected = false; | 178 | connected = false; |
| 125 | 179 | ||
| 126 | srs_close_stfd(stfd); | 180 | srs_close_stfd(stfd); |
| 181 | + srs_freep(skt); | ||
| 127 | } | 182 | } |
| 128 | 183 | ||
| 129 | int SrsHttpClient::connect(SrsHttpUri* uri) | 184 | int SrsHttpClient::connect(SrsHttpUri* uri) |
| @@ -149,6 +204,8 @@ int SrsHttpClient::connect(SrsHttpUri* uri) | @@ -149,6 +204,8 @@ int SrsHttpClient::connect(SrsHttpUri* uri) | ||
| 149 | srs_info("connect to server success. http url=%s, server=%s, port=%d", | 204 | srs_info("connect to server success. http url=%s, server=%s, port=%d", |
| 150 | uri->get_url(), uri->get_host(), uri->get_port()); | 205 | uri->get_url(), uri->get_host(), uri->get_port()); |
| 151 | 206 | ||
| 207 | + srs_assert(!skt); | ||
| 208 | + skt = new SrsStSocket(stfd); | ||
| 152 | connected = true; | 209 | connected = true; |
| 153 | 210 | ||
| 154 | return ret; | 211 | return ret; |
| @@ -37,6 +37,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -37,6 +37,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 37 | 37 | ||
| 38 | class SrsHttpUri; | 38 | class SrsHttpUri; |
| 39 | class SrsHttpParser; | 39 | class SrsHttpParser; |
| 40 | +class SrsHttpMessage; | ||
| 41 | +class SrsStSocket; | ||
| 40 | 42 | ||
| 41 | /** | 43 | /** |
| 42 | * http client to GET/POST/PUT/DELETE uri | 44 | * http client to GET/POST/PUT/DELETE uri |
| @@ -46,6 +48,7 @@ class SrsHttpClient | @@ -46,6 +48,7 @@ class SrsHttpClient | ||
| 46 | private: | 48 | private: |
| 47 | bool connected; | 49 | bool connected; |
| 48 | st_netfd_t stfd; | 50 | st_netfd_t stfd; |
| 51 | + SrsStSocket* skt; | ||
| 49 | SrsHttpParser* parser; | 52 | SrsHttpParser* parser; |
| 50 | public: | 53 | public: |
| 51 | SrsHttpClient(); | 54 | SrsHttpClient(); |
| @@ -53,11 +56,17 @@ public: | @@ -53,11 +56,17 @@ public: | ||
| 53 | public: | 56 | public: |
| 54 | /** | 57 | /** |
| 55 | * to post data to the uri. | 58 | * to post data to the uri. |
| 56 | - * @param req the data post to uri. | 59 | + * @param req the data post to uri. empty string to ignore. |
| 57 | * @param status_code the output status code response by server. | 60 | * @param status_code the output status code response by server. |
| 58 | * @param res output the response data from server. | 61 | * @param res output the response data from server. |
| 59 | */ | 62 | */ |
| 60 | virtual int post(SrsHttpUri* uri, std::string req, int& status_code, std::string& res); | 63 | virtual int post(SrsHttpUri* uri, std::string req, int& status_code, std::string& res); |
| 64 | + /** | ||
| 65 | + * to get data from the uri. | ||
| 66 | + * @param req the data post to uri. empty string to ignore. | ||
| 67 | + * @param ppmsg output the http message to read the response. | ||
| 68 | + */ | ||
| 69 | + virtual int get(SrsHttpUri* uri, std::string req, SrsHttpMessage** ppmsg); | ||
| 61 | private: | 70 | private: |
| 62 | virtual void disconnect(); | 71 | virtual void disconnect(); |
| 63 | virtual int connect(SrsHttpUri* uri); | 72 | virtual int connect(SrsHttpUri* uri); |
| @@ -131,7 +131,7 @@ int SrsRtpConn::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf) | @@ -131,7 +131,7 @@ int SrsRtpConn::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf) | ||
| 131 | 131 | ||
| 132 | SrsRtspAudioCache::SrsRtspAudioCache() | 132 | SrsRtspAudioCache::SrsRtspAudioCache() |
| 133 | { | 133 | { |
| 134 | - dts = NULL; | 134 | + dts = 0; |
| 135 | audio_samples = NULL; | 135 | audio_samples = NULL; |
| 136 | payload = NULL; | 136 | payload = NULL; |
| 137 | } | 137 | } |
| @@ -312,6 +312,8 @@ int run() | @@ -312,6 +312,8 @@ 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> | ||
| 315 | int run_master() | 317 | int run_master() |
| 316 | { | 318 | { |
| 317 | int ret = ERROR_SUCCESS; | 319 | int ret = ERROR_SUCCESS; |
| @@ -327,6 +329,22 @@ int run_master() | @@ -327,6 +329,22 @@ int run_master() | ||
| 327 | if ((ret = _srs_server->initialize_st()) != ERROR_SUCCESS) { | 329 | if ((ret = _srs_server->initialize_st()) != ERROR_SUCCESS) { |
| 328 | return ret; | 330 | return ret; |
| 329 | } | 331 | } |
| 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 | +}*/ | ||
| 330 | 348 | ||
| 331 | if ((ret = _srs_server->listen()) != ERROR_SUCCESS) { | 349 | if ((ret = _srs_server->listen()) != ERROR_SUCCESS) { |
| 332 | return ret; | 350 | return ret; |
| @@ -130,6 +130,7 @@ public: | @@ -130,6 +130,7 @@ public: | ||
| 130 | * @param v true to ename merged read. | 130 | * @param v true to ename merged read. |
| 131 | * @param handler the handler when merge read is enabled. | 131 | * @param handler the handler when merge read is enabled. |
| 132 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/241 | 132 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/241 |
| 133 | + * @remark the merged read is optional, ignore if not specifies. | ||
| 133 | */ | 134 | */ |
| 134 | virtual void set_merge_read(bool v, IMergeReadHandler* handler); | 135 | virtual void set_merge_read(bool v, IMergeReadHandler* handler); |
| 135 | #endif | 136 | #endif |
-
请 注册 或 登录 后发表评论