正在显示
42 个修改的文件
包含
1541 行增加
和
1979 行删除
| @@ -566,6 +566,7 @@ Supported operating systems and hardware: | @@ -566,6 +566,7 @@ Supported operating systems and hardware: | ||
| 566 | 566 | ||
| 567 | ### SRS 2.0 history | 567 | ### SRS 2.0 history |
| 568 | 568 | ||
| 569 | +* v2.0, 2015-05-23, fix [#391](https://github.com/simple-rtmp-server/srs/issues/391) copy request for async call. | ||
| 569 | * v2.0, 2015-05-22, fix [#397](https://github.com/simple-rtmp-server/srs/issues/397) the USER_HZ maybe not 100. 2.0.165 | 570 | * v2.0, 2015-05-22, fix [#397](https://github.com/simple-rtmp-server/srs/issues/397) the USER_HZ maybe not 100. 2.0.165 |
| 570 | * v2.0, 2015-05-22, for [#400](https://github.com/simple-rtmp-server/srs/issues/400), parse when got entire http header, by feilong. 2.0.164. | 571 | * v2.0, 2015-05-22, for [#400](https://github.com/simple-rtmp-server/srs/issues/400), parse when got entire http header, by feilong. 2.0.164. |
| 571 | * v2.0, 2015-05-19, merge from bravo system, add the rtmfp to bms(commercial srs). 2.0.163. | 572 | * v2.0, 2015-05-19, merge from bravo system, add the rtmfp to bms(commercial srs). 2.0.163. |
| @@ -159,7 +159,7 @@ MODULE_DEPENDS=("CORE" "KERNEL") | @@ -159,7 +159,7 @@ MODULE_DEPENDS=("CORE" "KERNEL") | ||
| 159 | ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSSLRoot}) | 159 | ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSSLRoot}) |
| 160 | MODULE_FILES=("srs_rtmp_amf0" "srs_rtmp_io" "srs_rtmp_stack" "srs_rtmp_sdk" | 160 | MODULE_FILES=("srs_rtmp_amf0" "srs_rtmp_io" "srs_rtmp_stack" "srs_rtmp_sdk" |
| 161 | "srs_rtmp_handshake" "srs_rtmp_utility" "srs_rtmp_msg_array" "srs_rtmp_buffer" | 161 | "srs_rtmp_handshake" "srs_rtmp_utility" "srs_rtmp_msg_array" "srs_rtmp_buffer" |
| 162 | - "srs_raw_avc" "srs_rtsp_stack") | 162 | + "srs_raw_avc" "srs_rtsp_stack" "srs_http_stack") |
| 163 | RTMP_INCS="src/protocol"; MODULE_DIR=${RTMP_INCS} . auto/modules.sh | 163 | RTMP_INCS="src/protocol"; MODULE_DIR=${RTMP_INCS} . auto/modules.sh |
| 164 | RTMP_OBJS="${MODULE_OBJS[@]}" | 164 | RTMP_OBJS="${MODULE_OBJS[@]}" |
| 165 | # | 165 | # |
| @@ -169,7 +169,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then | @@ -169,7 +169,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then | ||
| 169 | MODULE_DEPENDS=("CORE" "KERNEL" "RTMP") | 169 | MODULE_DEPENDS=("CORE" "KERNEL" "RTMP") |
| 170 | ModuleLibIncs=(${LibSTRoot} ${LibHttpParserRoot} ${SRS_OBJS_DIR}) | 170 | ModuleLibIncs=(${LibSTRoot} ${LibHttpParserRoot} ${SRS_OBJS_DIR}) |
| 171 | MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_st_socket" "srs_app_source" | 171 | MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_st_socket" "srs_app_source" |
| 172 | - "srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder" "srs_app_http" | 172 | + "srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder" |
| 173 | "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config" | 173 | "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config" |
| 174 | "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks" | 174 | "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks" |
| 175 | "srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge" | 175 | "srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge" |
| @@ -46,6 +46,8 @@ file | @@ -46,6 +46,8 @@ file | ||
| 46 | ../../src/kernel/srs_kernel_utility.hpp, | 46 | ../../src/kernel/srs_kernel_utility.hpp, |
| 47 | ../../src/kernel/srs_kernel_utility.cpp, | 47 | ../../src/kernel/srs_kernel_utility.cpp, |
| 48 | protocol readonly separator, | 48 | protocol readonly separator, |
| 49 | + ../../src/protocol/srs_http_stack.hpp, | ||
| 50 | + ../../src/protocol/srs_http_stack.cpp, | ||
| 49 | ../../src/protocol/srs_raw_avc.hpp, | 51 | ../../src/protocol/srs_raw_avc.hpp, |
| 50 | ../../src/protocol/srs_raw_avc.cpp, | 52 | ../../src/protocol/srs_raw_avc.cpp, |
| 51 | ../../src/protocol/srs_rtmp_amf0.hpp, | 53 | ../../src/protocol/srs_rtmp_amf0.hpp, |
| @@ -91,8 +93,6 @@ file | @@ -91,8 +93,6 @@ file | ||
| 91 | ../../src/app/srs_app_heartbeat.cpp, | 93 | ../../src/app/srs_app_heartbeat.cpp, |
| 92 | ../../src/app/srs_app_hls.hpp, | 94 | ../../src/app/srs_app_hls.hpp, |
| 93 | ../../src/app/srs_app_hls.cpp, | 95 | ../../src/app/srs_app_hls.cpp, |
| 94 | - ../../src/app/srs_app_http.hpp, | ||
| 95 | - ../../src/app/srs_app_http.cpp, | ||
| 96 | ../../src/app/srs_app_http_api.hpp, | 96 | ../../src/app/srs_app_http_api.hpp, |
| 97 | ../../src/app/srs_app_http_api.cpp, | 97 | ../../src/app/srs_app_http_api.cpp, |
| 98 | ../../src/app/srs_app_http_client.hpp, | 98 | ../../src/app/srs_app_http_client.hpp, |
| @@ -74,7 +74,6 @@ | @@ -74,7 +74,6 @@ | ||
| 74 | <ClInclude Include="..\..\src\app\srs_app_forward.hpp" /> | 74 | <ClInclude Include="..\..\src\app\srs_app_forward.hpp" /> |
| 75 | <ClInclude Include="..\..\src\app\srs_app_heartbeat.hpp" /> | 75 | <ClInclude Include="..\..\src\app\srs_app_heartbeat.hpp" /> |
| 76 | <ClInclude Include="..\..\src\app\srs_app_hls.hpp" /> | 76 | <ClInclude Include="..\..\src\app\srs_app_hls.hpp" /> |
| 77 | - <ClInclude Include="..\..\src\app\srs_app_http.hpp" /> | ||
| 78 | <ClInclude Include="..\..\src\app\srs_app_http_api.hpp" /> | 77 | <ClInclude Include="..\..\src\app\srs_app_http_api.hpp" /> |
| 79 | <ClInclude Include="..\..\src\app\srs_app_http_client.hpp" /> | 78 | <ClInclude Include="..\..\src\app\srs_app_http_client.hpp" /> |
| 80 | <ClInclude Include="..\..\src\app\srs_app_http_conn.hpp" /> | 79 | <ClInclude Include="..\..\src\app\srs_app_http_conn.hpp" /> |
| @@ -119,6 +118,7 @@ | @@ -119,6 +118,7 @@ | ||
| 119 | <ClInclude Include="..\..\src\libs\srs_librtmp.hpp" /> | 118 | <ClInclude Include="..\..\src\libs\srs_librtmp.hpp" /> |
| 120 | <ClInclude Include="..\..\src\libs\srs_lib_bandwidth.hpp" /> | 119 | <ClInclude Include="..\..\src\libs\srs_lib_bandwidth.hpp" /> |
| 121 | <ClInclude Include="..\..\src\libs\srs_lib_simple_socket.hpp" /> | 120 | <ClInclude Include="..\..\src\libs\srs_lib_simple_socket.hpp" /> |
| 121 | + <ClInclude Include="..\..\src\protocol\srs_http_stack.hpp" /> | ||
| 122 | <ClInclude Include="..\..\src\protocol\srs_raw_avc.hpp" /> | 122 | <ClInclude Include="..\..\src\protocol\srs_raw_avc.hpp" /> |
| 123 | <ClInclude Include="..\..\src\protocol\srs_rtmp_amf0.hpp" /> | 123 | <ClInclude Include="..\..\src\protocol\srs_rtmp_amf0.hpp" /> |
| 124 | <ClInclude Include="..\..\src\protocol\srs_rtmp_buffer.hpp" /> | 124 | <ClInclude Include="..\..\src\protocol\srs_rtmp_buffer.hpp" /> |
| @@ -155,7 +155,6 @@ | @@ -155,7 +155,6 @@ | ||
| 155 | <ClCompile Include="..\..\src\app\srs_app_forward.cpp" /> | 155 | <ClCompile Include="..\..\src\app\srs_app_forward.cpp" /> |
| 156 | <ClCompile Include="..\..\src\app\srs_app_heartbeat.cpp" /> | 156 | <ClCompile Include="..\..\src\app\srs_app_heartbeat.cpp" /> |
| 157 | <ClCompile Include="..\..\src\app\srs_app_hls.cpp" /> | 157 | <ClCompile Include="..\..\src\app\srs_app_hls.cpp" /> |
| 158 | - <ClCompile Include="..\..\src\app\srs_app_http.cpp" /> | ||
| 159 | <ClCompile Include="..\..\src\app\srs_app_http_api.cpp" /> | 158 | <ClCompile Include="..\..\src\app\srs_app_http_api.cpp" /> |
| 160 | <ClCompile Include="..\..\src\app\srs_app_http_client.cpp" /> | 159 | <ClCompile Include="..\..\src\app\srs_app_http_client.cpp" /> |
| 161 | <ClCompile Include="..\..\src\app\srs_app_http_conn.cpp" /> | 160 | <ClCompile Include="..\..\src\app\srs_app_http_conn.cpp" /> |
| @@ -201,6 +200,7 @@ | @@ -201,6 +200,7 @@ | ||
| 201 | <ClCompile Include="..\..\src\libs\srs_lib_bandwidth.cpp" /> | 200 | <ClCompile Include="..\..\src\libs\srs_lib_bandwidth.cpp" /> |
| 202 | <ClCompile Include="..\..\src\libs\srs_lib_simple_socket.cpp" /> | 201 | <ClCompile Include="..\..\src\libs\srs_lib_simple_socket.cpp" /> |
| 203 | <ClCompile Include="..\..\src\main\srs_main_server.cpp" /> | 202 | <ClCompile Include="..\..\src\main\srs_main_server.cpp" /> |
| 203 | + <ClCompile Include="..\..\src\protocol\srs_http_stack.cpp" /> | ||
| 204 | <ClCompile Include="..\..\src\protocol\srs_raw_avc.cpp" /> | 204 | <ClCompile Include="..\..\src\protocol\srs_raw_avc.cpp" /> |
| 205 | <ClCompile Include="..\..\src\protocol\srs_rtmp_amf0.cpp" /> | 205 | <ClCompile Include="..\..\src\protocol\srs_rtmp_amf0.cpp" /> |
| 206 | <ClCompile Include="..\..\src\protocol\srs_rtmp_buffer.cpp" /> | 206 | <ClCompile Include="..\..\src\protocol\srs_rtmp_buffer.cpp" /> |
| @@ -7,6 +7,7 @@ | @@ -7,6 +7,7 @@ | ||
| 7 | objects = { | 7 | objects = { |
| 8 | 8 | ||
| 9 | /* Begin PBXBuildFile section */ | 9 | /* Begin PBXBuildFile section */ |
| 10 | + 3C0E1B8D1B0F5ADF003ADEF7 /* srs_http_stack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C0E1B8B1B0F5ADF003ADEF7 /* srs_http_stack.cpp */; }; | ||
| 10 | 3C1231F61AAE652D00CE8F6C /* srs_core_autofree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1231F01AAE652C00CE8F6C /* srs_core_autofree.cpp */; }; | 11 | 3C1231F61AAE652D00CE8F6C /* srs_core_autofree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1231F01AAE652C00CE8F6C /* srs_core_autofree.cpp */; }; |
| 11 | 3C1231F71AAE652D00CE8F6C /* srs_core_performance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1231F21AAE652C00CE8F6C /* srs_core_performance.cpp */; }; | 12 | 3C1231F71AAE652D00CE8F6C /* srs_core_performance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1231F21AAE652C00CE8F6C /* srs_core_performance.cpp */; }; |
| 12 | 3C1231F81AAE652D00CE8F6C /* srs_core.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1231F41AAE652D00CE8F6C /* srs_core.cpp */; }; | 13 | 3C1231F81AAE652D00CE8F6C /* srs_core.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1231F41AAE652D00CE8F6C /* srs_core.cpp */; }; |
| @@ -48,7 +49,6 @@ | @@ -48,7 +49,6 @@ | ||
| 48 | 3C1232A01AAE81D900CE8F6C /* srs_app_http_client.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232641AAE81D900CE8F6C /* srs_app_http_client.cpp */; }; | 49 | 3C1232A01AAE81D900CE8F6C /* srs_app_http_client.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232641AAE81D900CE8F6C /* srs_app_http_client.cpp */; }; |
| 49 | 3C1232A11AAE81D900CE8F6C /* srs_app_http_conn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232661AAE81D900CE8F6C /* srs_app_http_conn.cpp */; }; | 50 | 3C1232A11AAE81D900CE8F6C /* srs_app_http_conn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232661AAE81D900CE8F6C /* srs_app_http_conn.cpp */; }; |
| 50 | 3C1232A21AAE81D900CE8F6C /* srs_app_http_hooks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232681AAE81D900CE8F6C /* srs_app_http_hooks.cpp */; }; | 51 | 3C1232A21AAE81D900CE8F6C /* srs_app_http_hooks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232681AAE81D900CE8F6C /* srs_app_http_hooks.cpp */; }; |
| 51 | - 3C1232A31AAE81D900CE8F6C /* srs_app_http.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12326A1AAE81D900CE8F6C /* srs_app_http.cpp */; }; | ||
| 52 | 3C1232A41AAE81D900CE8F6C /* srs_app_ingest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */; }; | 52 | 3C1232A41AAE81D900CE8F6C /* srs_app_ingest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */; }; |
| 53 | 3C1232A51AAE81D900CE8F6C /* srs_app_json.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12326E1AAE81D900CE8F6C /* srs_app_json.cpp */; }; | 53 | 3C1232A51AAE81D900CE8F6C /* srs_app_json.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12326E1AAE81D900CE8F6C /* srs_app_json.cpp */; }; |
| 54 | 3C1232A61AAE81D900CE8F6C /* srs_app_kbps.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232701AAE81D900CE8F6C /* srs_app_kbps.cpp */; }; | 54 | 3C1232A61AAE81D900CE8F6C /* srs_app_kbps.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232701AAE81D900CE8F6C /* srs_app_kbps.cpp */; }; |
| @@ -122,6 +122,8 @@ | @@ -122,6 +122,8 @@ | ||
| 122 | /* End PBXCopyFilesBuildPhase section */ | 122 | /* End PBXCopyFilesBuildPhase section */ |
| 123 | 123 | ||
| 124 | /* Begin PBXFileReference section */ | 124 | /* Begin PBXFileReference section */ |
| 125 | + 3C0E1B8B1B0F5ADF003ADEF7 /* srs_http_stack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_http_stack.cpp; path = ../../../src/protocol/srs_http_stack.cpp; sourceTree = "<group>"; }; | ||
| 126 | + 3C0E1B8C1B0F5ADF003ADEF7 /* srs_http_stack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_http_stack.hpp; path = ../../../src/protocol/srs_http_stack.hpp; sourceTree = "<group>"; }; | ||
| 125 | 3C1231E51AAE64A400CE8F6C /* srs_xcode */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = srs_xcode; sourceTree = BUILT_PRODUCTS_DIR; }; | 127 | 3C1231E51AAE64A400CE8F6C /* srs_xcode */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = srs_xcode; sourceTree = BUILT_PRODUCTS_DIR; }; |
| 126 | 3C1231F01AAE652C00CE8F6C /* srs_core_autofree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_core_autofree.cpp; path = ../../../src/core/srs_core_autofree.cpp; sourceTree = "<group>"; }; | 128 | 3C1231F01AAE652C00CE8F6C /* srs_core_autofree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_core_autofree.cpp; path = ../../../src/core/srs_core_autofree.cpp; sourceTree = "<group>"; }; |
| 127 | 3C1231F11AAE652C00CE8F6C /* srs_core_autofree.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_core_autofree.hpp; path = ../../../src/core/srs_core_autofree.hpp; sourceTree = "<group>"; }; | 129 | 3C1231F11AAE652C00CE8F6C /* srs_core_autofree.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_core_autofree.hpp; path = ../../../src/core/srs_core_autofree.hpp; sourceTree = "<group>"; }; |
| @@ -205,8 +207,6 @@ | @@ -205,8 +207,6 @@ | ||
| 205 | 3C1232671AAE81D900CE8F6C /* srs_app_http_conn.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_http_conn.hpp; path = ../../../src/app/srs_app_http_conn.hpp; sourceTree = "<group>"; }; | 207 | 3C1232671AAE81D900CE8F6C /* srs_app_http_conn.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_http_conn.hpp; path = ../../../src/app/srs_app_http_conn.hpp; sourceTree = "<group>"; }; |
| 206 | 3C1232681AAE81D900CE8F6C /* srs_app_http_hooks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_http_hooks.cpp; path = ../../../src/app/srs_app_http_hooks.cpp; sourceTree = "<group>"; }; | 208 | 3C1232681AAE81D900CE8F6C /* srs_app_http_hooks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_http_hooks.cpp; path = ../../../src/app/srs_app_http_hooks.cpp; sourceTree = "<group>"; }; |
| 207 | 3C1232691AAE81D900CE8F6C /* srs_app_http_hooks.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_http_hooks.hpp; path = ../../../src/app/srs_app_http_hooks.hpp; sourceTree = "<group>"; }; | 209 | 3C1232691AAE81D900CE8F6C /* srs_app_http_hooks.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_http_hooks.hpp; path = ../../../src/app/srs_app_http_hooks.hpp; sourceTree = "<group>"; }; |
| 208 | - 3C12326A1AAE81D900CE8F6C /* srs_app_http.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_http.cpp; path = ../../../src/app/srs_app_http.cpp; sourceTree = "<group>"; }; | ||
| 209 | - 3C12326B1AAE81D900CE8F6C /* srs_app_http.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_http.hpp; path = ../../../src/app/srs_app_http.hpp; sourceTree = "<group>"; }; | ||
| 210 | 3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_ingest.cpp; path = ../../../src/app/srs_app_ingest.cpp; sourceTree = "<group>"; }; | 210 | 3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_ingest.cpp; path = ../../../src/app/srs_app_ingest.cpp; sourceTree = "<group>"; }; |
| 211 | 3C12326D1AAE81D900CE8F6C /* srs_app_ingest.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_ingest.hpp; path = ../../../src/app/srs_app_ingest.hpp; sourceTree = "<group>"; }; | 211 | 3C12326D1AAE81D900CE8F6C /* srs_app_ingest.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_ingest.hpp; path = ../../../src/app/srs_app_ingest.hpp; sourceTree = "<group>"; }; |
| 212 | 3C12326E1AAE81D900CE8F6C /* srs_app_json.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_json.cpp; path = ../../../src/app/srs_app_json.cpp; sourceTree = "<group>"; }; | 212 | 3C12326E1AAE81D900CE8F6C /* srs_app_json.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_json.cpp; path = ../../../src/app/srs_app_json.cpp; sourceTree = "<group>"; }; |
| @@ -487,6 +487,8 @@ | @@ -487,6 +487,8 @@ | ||
| 487 | 3C12322C1AAE819900CE8F6C /* protocol */ = { | 487 | 3C12322C1AAE819900CE8F6C /* protocol */ = { |
| 488 | isa = PBXGroup; | 488 | isa = PBXGroup; |
| 489 | children = ( | 489 | children = ( |
| 490 | + 3C0E1B8B1B0F5ADF003ADEF7 /* srs_http_stack.cpp */, | ||
| 491 | + 3C0E1B8C1B0F5ADF003ADEF7 /* srs_http_stack.hpp */, | ||
| 490 | 3C12322D1AAE81A400CE8F6C /* srs_raw_avc.cpp */, | 492 | 3C12322D1AAE81A400CE8F6C /* srs_raw_avc.cpp */, |
| 491 | 3C12322E1AAE81A400CE8F6C /* srs_raw_avc.hpp */, | 493 | 3C12322E1AAE81A400CE8F6C /* srs_raw_avc.hpp */, |
| 492 | 3C12322F1AAE81A400CE8F6C /* srs_rtmp_amf0.cpp */, | 494 | 3C12322F1AAE81A400CE8F6C /* srs_rtmp_amf0.cpp */, |
| @@ -550,8 +552,6 @@ | @@ -550,8 +552,6 @@ | ||
| 550 | 3C1232671AAE81D900CE8F6C /* srs_app_http_conn.hpp */, | 552 | 3C1232671AAE81D900CE8F6C /* srs_app_http_conn.hpp */, |
| 551 | 3C1232681AAE81D900CE8F6C /* srs_app_http_hooks.cpp */, | 553 | 3C1232681AAE81D900CE8F6C /* srs_app_http_hooks.cpp */, |
| 552 | 3C1232691AAE81D900CE8F6C /* srs_app_http_hooks.hpp */, | 554 | 3C1232691AAE81D900CE8F6C /* srs_app_http_hooks.hpp */, |
| 553 | - 3C12326A1AAE81D900CE8F6C /* srs_app_http.cpp */, | ||
| 554 | - 3C12326B1AAE81D900CE8F6C /* srs_app_http.hpp */, | ||
| 555 | 3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */, | 555 | 3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */, |
| 556 | 3C12326D1AAE81D900CE8F6C /* srs_app_ingest.hpp */, | 556 | 3C12326D1AAE81D900CE8F6C /* srs_app_ingest.hpp */, |
| 557 | 3C12326E1AAE81D900CE8F6C /* srs_app_json.cpp */, | 557 | 3C12326E1AAE81D900CE8F6C /* srs_app_json.cpp */, |
| @@ -886,6 +886,7 @@ | @@ -886,6 +886,7 @@ | ||
| 886 | 3C1232411AAE81A400CE8F6C /* srs_raw_avc.cpp in Sources */, | 886 | 3C1232411AAE81A400CE8F6C /* srs_raw_avc.cpp in Sources */, |
| 887 | 3C1232491AAE81A400CE8F6C /* srs_rtmp_utility.cpp in Sources */, | 887 | 3C1232491AAE81A400CE8F6C /* srs_rtmp_utility.cpp in Sources */, |
| 888 | 3C663F191AB0155100286D8B /* srs_publish.c in Sources */, | 888 | 3C663F191AB0155100286D8B /* srs_publish.c in Sources */, |
| 889 | + 3C0E1B8D1B0F5ADF003ADEF7 /* srs_http_stack.cpp in Sources */, | ||
| 889 | 3C1232A01AAE81D900CE8F6C /* srs_app_http_client.cpp in Sources */, | 890 | 3C1232A01AAE81D900CE8F6C /* srs_app_http_client.cpp in Sources */, |
| 890 | 3C689F981AB6AAAC00C9CEEE /* key.c in Sources */, | 891 | 3C689F981AB6AAAC00C9CEEE /* key.c in Sources */, |
| 891 | 3C12329B1AAE81D900CE8F6C /* srs_app_ffmpeg.cpp in Sources */, | 892 | 3C12329B1AAE81D900CE8F6C /* srs_app_ffmpeg.cpp in Sources */, |
| @@ -936,7 +937,6 @@ | @@ -936,7 +937,6 @@ | ||
| 936 | 3C1232AF1AAE81D900CE8F6C /* srs_app_rtsp.cpp in Sources */, | 937 | 3C1232AF1AAE81D900CE8F6C /* srs_app_rtsp.cpp in Sources */, |
| 937 | 3CC52DDD1ACE4023006FEB01 /* srs_utest_reload.cpp in Sources */, | 938 | 3CC52DDD1ACE4023006FEB01 /* srs_utest_reload.cpp in Sources */, |
| 938 | 3C689FA11AB6AAC800C9CEEE /* sync.c in Sources */, | 939 | 3C689FA11AB6AAC800C9CEEE /* sync.c in Sources */, |
| 939 | - 3C1232A31AAE81D900CE8F6C /* srs_app_http.cpp in Sources */, | ||
| 940 | 3C12329A1AAE81D900CE8F6C /* srs_app_encoder.cpp in Sources */, | 940 | 3C12329A1AAE81D900CE8F6C /* srs_app_encoder.cpp in Sources */, |
| 941 | ); | 941 | ); |
| 942 | runOnlyForDeploymentPostprocessing = 0; | 942 | runOnlyForDeploymentPostprocessing = 0; |
| @@ -31,65 +31,64 @@ using namespace std; | @@ -31,65 +31,64 @@ using namespace std; | ||
| 31 | // the sleep interval for http async callback. | 31 | // the sleep interval for http async callback. |
| 32 | #define SRS_AUTO_ASYNC_CALLBACL_SLEEP_US 300000 | 32 | #define SRS_AUTO_ASYNC_CALLBACL_SLEEP_US 300000 |
| 33 | 33 | ||
| 34 | -ISrsDvrAsyncCall::ISrsDvrAsyncCall() | 34 | +ISrsAsyncCallTask::ISrsAsyncCallTask() |
| 35 | { | 35 | { |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | -ISrsDvrAsyncCall::~ISrsDvrAsyncCall() | 38 | +ISrsAsyncCallTask::~ISrsAsyncCallTask() |
| 39 | { | 39 | { |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | -SrsDvrAsyncCallThread::SrsDvrAsyncCallThread() | 42 | +SrsAsyncCallWorker::SrsAsyncCallWorker() |
| 43 | { | 43 | { |
| 44 | - pthread = new SrsThread("async", this, SRS_AUTO_ASYNC_CALLBACL_SLEEP_US, true); | 44 | + pthread = new SrsReusableThread("async", this, SRS_AUTO_ASYNC_CALLBACL_SLEEP_US); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | -SrsDvrAsyncCallThread::~SrsDvrAsyncCallThread() | 47 | +SrsAsyncCallWorker::~SrsAsyncCallWorker() |
| 48 | { | 48 | { |
| 49 | - stop(); | ||
| 50 | srs_freep(pthread); | 49 | srs_freep(pthread); |
| 51 | 50 | ||
| 52 | - std::vector<ISrsDvrAsyncCall*>::iterator it; | ||
| 53 | - for (it = callbacks.begin(); it != callbacks.end(); ++it) { | ||
| 54 | - ISrsDvrAsyncCall* call = *it; | ||
| 55 | - srs_freep(call); | 51 | + std::vector<ISrsAsyncCallTask*>::iterator it; |
| 52 | + for (it = tasks.begin(); it != tasks.end(); ++it) { | ||
| 53 | + ISrsAsyncCallTask* task = *it; | ||
| 54 | + srs_freep(task); | ||
| 56 | } | 55 | } |
| 57 | - callbacks.clear(); | 56 | + tasks.clear(); |
| 58 | } | 57 | } |
| 59 | 58 | ||
| 60 | -int SrsDvrAsyncCallThread::call(ISrsDvrAsyncCall* c) | 59 | +int SrsAsyncCallWorker::execute(ISrsAsyncCallTask* t) |
| 61 | { | 60 | { |
| 62 | int ret = ERROR_SUCCESS; | 61 | int ret = ERROR_SUCCESS; |
| 63 | 62 | ||
| 64 | - callbacks.push_back(c); | 63 | + tasks.push_back(t); |
| 65 | 64 | ||
| 66 | return ret; | 65 | return ret; |
| 67 | } | 66 | } |
| 68 | 67 | ||
| 69 | -int SrsDvrAsyncCallThread::start() | 68 | +int SrsAsyncCallWorker::start() |
| 70 | { | 69 | { |
| 71 | return pthread->start(); | 70 | return pthread->start(); |
| 72 | } | 71 | } |
| 73 | 72 | ||
| 74 | -void SrsDvrAsyncCallThread::stop() | 73 | +void SrsAsyncCallWorker::stop() |
| 75 | { | 74 | { |
| 76 | pthread->stop(); | 75 | pthread->stop(); |
| 77 | } | 76 | } |
| 78 | 77 | ||
| 79 | -int SrsDvrAsyncCallThread::cycle() | 78 | +int SrsAsyncCallWorker::cycle() |
| 80 | { | 79 | { |
| 81 | int ret = ERROR_SUCCESS; | 80 | int ret = ERROR_SUCCESS; |
| 82 | 81 | ||
| 83 | - std::vector<ISrsDvrAsyncCall*> copies = callbacks; | ||
| 84 | - callbacks.clear(); | 82 | + std::vector<ISrsAsyncCallTask*> copies = tasks; |
| 83 | + tasks.clear(); | ||
| 85 | 84 | ||
| 86 | - std::vector<ISrsDvrAsyncCall*>::iterator it; | 85 | + std::vector<ISrsAsyncCallTask*>::iterator it; |
| 87 | for (it = copies.begin(); it != copies.end(); ++it) { | 86 | for (it = copies.begin(); it != copies.end(); ++it) { |
| 88 | - ISrsDvrAsyncCall* call = *it; | ||
| 89 | - if ((ret = call->call()) != ERROR_SUCCESS) { | ||
| 90 | - srs_warn("ignore async callback %s, ret=%d", call->to_string().c_str(), ret); | 87 | + ISrsAsyncCallTask* task = *it; |
| 88 | + if ((ret = task->call()) != ERROR_SUCCESS) { | ||
| 89 | + srs_warn("ignore async callback %s, ret=%d", task->to_string().c_str(), ret); | ||
| 91 | } | 90 | } |
| 92 | - srs_freep(call); | 91 | + srs_freep(task); |
| 93 | } | 92 | } |
| 94 | 93 | ||
| 95 | return ret; | 94 | return ret; |
| @@ -42,32 +42,36 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -42,32 +42,36 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 42 | * a video and pass it to the dvr again. | 42 | * a video and pass it to the dvr again. |
| 43 | * futhurmore, the aync call never block the main worker thread. | 43 | * futhurmore, the aync call never block the main worker thread. |
| 44 | */ | 44 | */ |
| 45 | -class ISrsDvrAsyncCall | 45 | +class ISrsAsyncCallTask |
| 46 | { | 46 | { |
| 47 | public: | 47 | public: |
| 48 | - ISrsDvrAsyncCall(); | ||
| 49 | - virtual ~ISrsDvrAsyncCall(); | 48 | + ISrsAsyncCallTask(); |
| 49 | + virtual ~ISrsAsyncCallTask(); | ||
| 50 | public: | 50 | public: |
| 51 | virtual int call() = 0; | 51 | virtual int call() = 0; |
| 52 | virtual std::string to_string() = 0; | 52 | virtual std::string to_string() = 0; |
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| 55 | /** | 55 | /** |
| 56 | -* the async callback for dvr. | ||
| 57 | -*/ | ||
| 58 | -class SrsDvrAsyncCallThread : public ISrsThreadHandler | 56 | + * the async callback for dvr. |
| 57 | + * when worker call with the task, the worker will do it in isolate thread. | ||
| 58 | + * that is, the task is execute/call in async mode. | ||
| 59 | + */ | ||
| 60 | +class SrsAsyncCallWorker : public ISrsReusableThreadHandler | ||
| 59 | { | 61 | { |
| 60 | private: | 62 | private: |
| 61 | - SrsThread* pthread; | ||
| 62 | - std::vector<ISrsDvrAsyncCall*> callbacks; | 63 | + SrsReusableThread* pthread; |
| 64 | + std::vector<ISrsAsyncCallTask*> tasks; | ||
| 63 | public: | 65 | public: |
| 64 | - SrsDvrAsyncCallThread(); | ||
| 65 | - virtual ~SrsDvrAsyncCallThread(); | 66 | + SrsAsyncCallWorker(); |
| 67 | + virtual ~SrsAsyncCallWorker(); | ||
| 66 | public: | 68 | public: |
| 67 | - virtual int call(ISrsDvrAsyncCall* c); | 69 | + virtual int execute(ISrsAsyncCallTask* t); |
| 68 | public: | 70 | public: |
| 69 | virtual int start(); | 71 | virtual int start(); |
| 70 | virtual void stop(); | 72 | virtual void stop(); |
| 73 | +// interface ISrsReusableThreadHandler | ||
| 74 | +public: | ||
| 71 | virtual int cycle(); | 75 | virtual int cycle(); |
| 72 | }; | 76 | }; |
| 73 | 77 |
| @@ -45,12 +45,17 @@ SrsConnection::SrsConnection(IConnectionManager* cm, st_netfd_t c) | @@ -45,12 +45,17 @@ SrsConnection::SrsConnection(IConnectionManager* cm, st_netfd_t c) | ||
| 45 | // so we never use joinable. | 45 | // so we never use joinable. |
| 46 | // TODO: FIXME: maybe other thread need to stop it. | 46 | // TODO: FIXME: maybe other thread need to stop it. |
| 47 | // @see: https://github.com/simple-rtmp-server/srs/issues/78 | 47 | // @see: https://github.com/simple-rtmp-server/srs/issues/78 |
| 48 | - pthread = new SrsThread("conn", this, 0, false); | 48 | + pthread = new SrsOneCycleThread("conn", this); |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | SrsConnection::~SrsConnection() | 51 | SrsConnection::~SrsConnection() |
| 52 | { | 52 | { |
| 53 | - stop(); | 53 | + /** |
| 54 | + * when delete the connection, stop the connection, | ||
| 55 | + * close the underlayer socket, delete the thread. | ||
| 56 | + */ | ||
| 57 | + srs_close_stfd(stfd); | ||
| 58 | + srs_freep(pthread); | ||
| 54 | } | 59 | } |
| 55 | 60 | ||
| 56 | int SrsConnection::start() | 61 | int SrsConnection::start() |
| @@ -83,9 +88,6 @@ int SrsConnection::cycle() | @@ -83,9 +88,6 @@ int SrsConnection::cycle() | ||
| 83 | if (ret == ERROR_SOCKET_CLOSED) { | 88 | if (ret == ERROR_SOCKET_CLOSED) { |
| 84 | srs_warn("client disconnect peer. ret=%d", ret); | 89 | srs_warn("client disconnect peer. ret=%d", ret); |
| 85 | } | 90 | } |
| 86 | - | ||
| 87 | - // set loop to stop to quit. | ||
| 88 | - pthread->stop_loop(); | ||
| 89 | 91 | ||
| 90 | return ERROR_SUCCESS; | 92 | return ERROR_SUCCESS; |
| 91 | } | 93 | } |
| @@ -101,10 +103,4 @@ int SrsConnection::srs_id() | @@ -101,10 +103,4 @@ int SrsConnection::srs_id() | ||
| 101 | return id; | 103 | return id; |
| 102 | } | 104 | } |
| 103 | 105 | ||
| 104 | -void SrsConnection::stop() | ||
| 105 | -{ | ||
| 106 | - srs_close_stfd(stfd); | ||
| 107 | - srs_freep(pthread); | ||
| 108 | -} | ||
| 109 | - | ||
| 110 | 106 |
| @@ -58,14 +58,14 @@ public: | @@ -58,14 +58,14 @@ public: | ||
| 58 | * all connections accept from listener must extends from this base class, | 58 | * all connections accept from listener must extends from this base class, |
| 59 | * server will add the connection to manager, and delete it when remove. | 59 | * server will add the connection to manager, and delete it when remove. |
| 60 | */ | 60 | */ |
| 61 | -class SrsConnection : public virtual ISrsThreadHandler, public virtual IKbpsDelta | 61 | +class SrsConnection : public virtual ISrsOneCycleThreadHandler, public virtual IKbpsDelta |
| 62 | { | 62 | { |
| 63 | private: | 63 | private: |
| 64 | /** | 64 | /** |
| 65 | * each connection start a green thread, | 65 | * each connection start a green thread, |
| 66 | * when thread stop, the connection will be delete by server. | 66 | * when thread stop, the connection will be delete by server. |
| 67 | */ | 67 | */ |
| 68 | - SrsThread* pthread; | 68 | + SrsOneCycleThread* pthread; |
| 69 | /** | 69 | /** |
| 70 | * the id of connection. | 70 | * the id of connection. |
| 71 | */ | 71 | */ |
| @@ -97,6 +97,8 @@ public: | @@ -97,6 +97,8 @@ public: | ||
| 97 | * to remove the client by server->remove(this). | 97 | * to remove the client by server->remove(this). |
| 98 | */ | 98 | */ |
| 99 | virtual int start(); | 99 | virtual int start(); |
| 100 | +// interface ISrsOneCycleThreadHandler | ||
| 101 | +public: | ||
| 100 | /** | 102 | /** |
| 101 | * the thread cycle function, | 103 | * the thread cycle function, |
| 102 | * when serve connection completed, terminate the loop which will terminate the thread, | 104 | * when serve connection completed, terminate the loop which will terminate the thread, |
| @@ -119,12 +121,6 @@ protected: | @@ -119,12 +121,6 @@ protected: | ||
| 119 | * for concrete connection to do the cycle. | 121 | * for concrete connection to do the cycle. |
| 120 | */ | 122 | */ |
| 121 | virtual int do_cycle() = 0; | 123 | virtual int do_cycle() = 0; |
| 122 | -private: | ||
| 123 | - /** | ||
| 124 | - * when delete the connection, stop the connection, | ||
| 125 | - * close the underlayer socket, delete the thread. | ||
| 126 | - */ | ||
| 127 | - virtual void stop(); | ||
| 128 | }; | 124 | }; |
| 129 | 125 | ||
| 130 | #endif | 126 | #endif |
| @@ -498,12 +498,13 @@ int SrsFlvSegment::on_reload_vhost_dvr(std::string /*vhost*/) | @@ -498,12 +498,13 @@ int SrsFlvSegment::on_reload_vhost_dvr(std::string /*vhost*/) | ||
| 498 | 498 | ||
| 499 | SrsDvrAsyncCallOnDvr::SrsDvrAsyncCallOnDvr(SrsRequest* r, string p) | 499 | SrsDvrAsyncCallOnDvr::SrsDvrAsyncCallOnDvr(SrsRequest* r, string p) |
| 500 | { | 500 | { |
| 501 | - req = r; | 501 | + req = r->copy(); |
| 502 | path = p; | 502 | path = p; |
| 503 | } | 503 | } |
| 504 | 504 | ||
| 505 | SrsDvrAsyncCallOnDvr::~SrsDvrAsyncCallOnDvr() | 505 | SrsDvrAsyncCallOnDvr::~SrsDvrAsyncCallOnDvr() |
| 506 | { | 506 | { |
| 507 | + srs_freep(req); | ||
| 507 | } | 508 | } |
| 508 | 509 | ||
| 509 | int SrsDvrAsyncCallOnDvr::call() | 510 | int SrsDvrAsyncCallOnDvr::call() |
| @@ -547,7 +548,7 @@ SrsDvrPlan::SrsDvrPlan() | @@ -547,7 +548,7 @@ SrsDvrPlan::SrsDvrPlan() | ||
| 547 | 548 | ||
| 548 | dvr_enabled = false; | 549 | dvr_enabled = false; |
| 549 | segment = new SrsFlvSegment(this); | 550 | segment = new SrsFlvSegment(this); |
| 550 | - async = new SrsDvrAsyncCallThread(); | 551 | + async = new SrsAsyncCallWorker(); |
| 551 | } | 552 | } |
| 552 | 553 | ||
| 553 | SrsDvrPlan::~SrsDvrPlan() | 554 | SrsDvrPlan::~SrsDvrPlan() |
| @@ -628,7 +629,7 @@ int SrsDvrPlan::on_reap_segment() | @@ -628,7 +629,7 @@ int SrsDvrPlan::on_reap_segment() | ||
| 628 | { | 629 | { |
| 629 | int ret = ERROR_SUCCESS; | 630 | int ret = ERROR_SUCCESS; |
| 630 | 631 | ||
| 631 | - if ((ret = async->call(new SrsDvrAsyncCallOnDvr(req, segment->get_path()))) != ERROR_SUCCESS) { | 632 | + if ((ret = async->execute(new SrsDvrAsyncCallOnDvr(req, segment->get_path()))) != ERROR_SUCCESS) { |
| 632 | return ret; | 633 | return ret; |
| 633 | } | 634 | } |
| 634 | 635 |
| @@ -178,7 +178,7 @@ public: | @@ -178,7 +178,7 @@ public: | ||
| 178 | /** | 178 | /** |
| 179 | * the dvr async call. | 179 | * the dvr async call. |
| 180 | */ | 180 | */ |
| 181 | -class SrsDvrAsyncCallOnDvr : public ISrsDvrAsyncCall | 181 | +class SrsDvrAsyncCallOnDvr : public ISrsAsyncCallTask |
| 182 | { | 182 | { |
| 183 | private: | 183 | private: |
| 184 | std::string path; | 184 | std::string path; |
| @@ -206,7 +206,7 @@ public: | @@ -206,7 +206,7 @@ public: | ||
| 206 | SrsRequest* req; | 206 | SrsRequest* req; |
| 207 | protected: | 207 | protected: |
| 208 | SrsFlvSegment* segment; | 208 | SrsFlvSegment* segment; |
| 209 | - SrsDvrAsyncCallThread* async; | 209 | + SrsAsyncCallWorker* async; |
| 210 | bool dvr_enabled; | 210 | bool dvr_enabled; |
| 211 | public: | 211 | public: |
| 212 | SrsDvrPlan(); | 212 | SrsDvrPlan(); |
| @@ -70,7 +70,7 @@ SrsEdgeIngester::SrsEdgeIngester() | @@ -70,7 +70,7 @@ SrsEdgeIngester::SrsEdgeIngester() | ||
| 70 | origin_index = 0; | 70 | origin_index = 0; |
| 71 | stream_id = 0; | 71 | stream_id = 0; |
| 72 | stfd = NULL; | 72 | stfd = NULL; |
| 73 | - pthread = new SrsThread("edge-igs", this, SRS_EDGE_INGESTER_SLEEP_US, true); | 73 | + pthread = new SrsReusableThread2("edge-igs", this, SRS_EDGE_INGESTER_SLEEP_US); |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | SrsEdgeIngester::~SrsEdgeIngester() | 76 | SrsEdgeIngester::~SrsEdgeIngester() |
| @@ -171,7 +171,7 @@ int SrsEdgeIngester::ingest() | @@ -171,7 +171,7 @@ int SrsEdgeIngester::ingest() | ||
| 171 | SrsPithyPrint* pprint = SrsPithyPrint::create_edge(); | 171 | SrsPithyPrint* pprint = SrsPithyPrint::create_edge(); |
| 172 | SrsAutoFree(SrsPithyPrint, pprint); | 172 | SrsAutoFree(SrsPithyPrint, pprint); |
| 173 | 173 | ||
| 174 | - while (pthread->can_loop()) { | 174 | + while (!pthread->interrupted()) { |
| 175 | pprint->elapse(); | 175 | pprint->elapse(); |
| 176 | 176 | ||
| 177 | // pithy print | 177 | // pithy print |
| @@ -397,7 +397,7 @@ SrsEdgeForwarder::SrsEdgeForwarder() | @@ -397,7 +397,7 @@ SrsEdgeForwarder::SrsEdgeForwarder() | ||
| 397 | origin_index = 0; | 397 | origin_index = 0; |
| 398 | stream_id = 0; | 398 | stream_id = 0; |
| 399 | stfd = NULL; | 399 | stfd = NULL; |
| 400 | - pthread = new SrsThread("edge-fwr", this, SRS_EDGE_FORWARDER_SLEEP_US, true); | 400 | + pthread = new SrsReusableThread2("edge-fwr", this, SRS_EDGE_FORWARDER_SLEEP_US); |
| 401 | queue = new SrsMessageQueue(); | 401 | queue = new SrsMessageQueue(); |
| 402 | send_error_code = ERROR_SUCCESS; | 402 | send_error_code = ERROR_SUCCESS; |
| 403 | } | 403 | } |
| @@ -489,7 +489,7 @@ int SrsEdgeForwarder::cycle() | @@ -489,7 +489,7 @@ int SrsEdgeForwarder::cycle() | ||
| 489 | 489 | ||
| 490 | SrsMessageArray msgs(SYS_MAX_EDGE_SEND_MSGS); | 490 | SrsMessageArray msgs(SYS_MAX_EDGE_SEND_MSGS); |
| 491 | 491 | ||
| 492 | - while (pthread->can_loop()) { | 492 | + while (!pthread->interrupted()) { |
| 493 | if (send_error_code != ERROR_SUCCESS) { | 493 | if (send_error_code != ERROR_SUCCESS) { |
| 494 | st_usleep(SRS_EDGE_FORWARDER_ERROR_US); | 494 | st_usleep(SRS_EDGE_FORWARDER_ERROR_US); |
| 495 | continue; | 495 | continue; |
| @@ -75,7 +75,7 @@ enum SrsEdgeUserState | @@ -75,7 +75,7 @@ enum SrsEdgeUserState | ||
| 75 | /** | 75 | /** |
| 76 | * edge used to ingest stream from origin. | 76 | * edge used to ingest stream from origin. |
| 77 | */ | 77 | */ |
| 78 | -class SrsEdgeIngester : public ISrsThreadHandler | 78 | +class SrsEdgeIngester : public ISrsReusableThread2Handler |
| 79 | { | 79 | { |
| 80 | private: | 80 | private: |
| 81 | int stream_id; | 81 | int stream_id; |
| @@ -83,7 +83,7 @@ private: | @@ -83,7 +83,7 @@ private: | ||
| 83 | SrsSource* _source; | 83 | SrsSource* _source; |
| 84 | SrsPlayEdge* _edge; | 84 | SrsPlayEdge* _edge; |
| 85 | SrsRequest* _req; | 85 | SrsRequest* _req; |
| 86 | - SrsThread* pthread; | 86 | + SrsReusableThread2* pthread; |
| 87 | st_netfd_t stfd; | 87 | st_netfd_t stfd; |
| 88 | ISrsProtocolReaderWriter* io; | 88 | ISrsProtocolReaderWriter* io; |
| 89 | SrsKbps* kbps; | 89 | SrsKbps* kbps; |
| @@ -96,7 +96,7 @@ public: | @@ -96,7 +96,7 @@ public: | ||
| 96 | virtual int initialize(SrsSource* source, SrsPlayEdge* edge, SrsRequest* req); | 96 | virtual int initialize(SrsSource* source, SrsPlayEdge* edge, SrsRequest* req); |
| 97 | virtual int start(); | 97 | virtual int start(); |
| 98 | virtual void stop(); | 98 | virtual void stop(); |
| 99 | -// interface ISrsThreadHandler | 99 | +// interface ISrsReusableThread2Handler |
| 100 | public: | 100 | public: |
| 101 | virtual int cycle(); | 101 | virtual int cycle(); |
| 102 | private: | 102 | private: |
| @@ -110,7 +110,7 @@ private: | @@ -110,7 +110,7 @@ private: | ||
| 110 | /** | 110 | /** |
| 111 | * edge used to forward stream to origin. | 111 | * edge used to forward stream to origin. |
| 112 | */ | 112 | */ |
| 113 | -class SrsEdgeForwarder : public ISrsThreadHandler | 113 | +class SrsEdgeForwarder : public ISrsReusableThread2Handler |
| 114 | { | 114 | { |
| 115 | private: | 115 | private: |
| 116 | int stream_id; | 116 | int stream_id; |
| @@ -118,7 +118,7 @@ private: | @@ -118,7 +118,7 @@ private: | ||
| 118 | SrsSource* _source; | 118 | SrsSource* _source; |
| 119 | SrsPublishEdge* _edge; | 119 | SrsPublishEdge* _edge; |
| 120 | SrsRequest* _req; | 120 | SrsRequest* _req; |
| 121 | - SrsThread* pthread; | 121 | + SrsReusableThread2* pthread; |
| 122 | st_netfd_t stfd; | 122 | st_netfd_t stfd; |
| 123 | ISrsProtocolReaderWriter* io; | 123 | ISrsProtocolReaderWriter* io; |
| 124 | SrsKbps* kbps; | 124 | SrsKbps* kbps; |
| @@ -144,7 +144,7 @@ public: | @@ -144,7 +144,7 @@ public: | ||
| 144 | virtual int initialize(SrsSource* source, SrsPublishEdge* edge, SrsRequest* req); | 144 | virtual int initialize(SrsSource* source, SrsPublishEdge* edge, SrsRequest* req); |
| 145 | virtual int start(); | 145 | virtual int start(); |
| 146 | virtual void stop(); | 146 | virtual void stop(); |
| 147 | -// interface ISrsThreadHandler | 147 | +// interface ISrsReusableThread2Handler |
| 148 | public: | 148 | public: |
| 149 | virtual int cycle(); | 149 | virtual int cycle(); |
| 150 | public: | 150 | public: |
| @@ -44,7 +44,7 @@ static std::vector<std::string> _transcoded_url; | @@ -44,7 +44,7 @@ static std::vector<std::string> _transcoded_url; | ||
| 44 | 44 | ||
| 45 | SrsEncoder::SrsEncoder() | 45 | SrsEncoder::SrsEncoder() |
| 46 | { | 46 | { |
| 47 | - pthread = new SrsThread("encoder", this, SRS_RTMP_ENCODER_SLEEP_US, true); | 47 | + pthread = new SrsReusableThread("encoder", this, SRS_RTMP_ENCODER_SLEEP_US); |
| 48 | pprint = SrsPithyPrint::create_encoder(); | 48 | pprint = SrsPithyPrint::create_encoder(); |
| 49 | } | 49 | } |
| 50 | 50 |
| @@ -45,13 +45,13 @@ class SrsFFMPEG; | @@ -45,13 +45,13 @@ class SrsFFMPEG; | ||
| 45 | * the encoder for a stream, | 45 | * the encoder for a stream, |
| 46 | * may use multiple ffmpegs to transcode the specified stream. | 46 | * may use multiple ffmpegs to transcode the specified stream. |
| 47 | */ | 47 | */ |
| 48 | -class SrsEncoder : public ISrsThreadHandler | 48 | +class SrsEncoder : public ISrsReusableThreadHandler |
| 49 | { | 49 | { |
| 50 | private: | 50 | private: |
| 51 | std::string input_stream_name; | 51 | std::string input_stream_name; |
| 52 | std::vector<SrsFFMPEG*> ffmpegs; | 52 | std::vector<SrsFFMPEG*> ffmpegs; |
| 53 | private: | 53 | private: |
| 54 | - SrsThread* pthread; | 54 | + SrsReusableThread* pthread; |
| 55 | SrsPithyPrint* pprint; | 55 | SrsPithyPrint* pprint; |
| 56 | public: | 56 | public: |
| 57 | SrsEncoder(); | 57 | SrsEncoder(); |
| @@ -59,7 +59,7 @@ public: | @@ -59,7 +59,7 @@ public: | ||
| 59 | public: | 59 | public: |
| 60 | virtual int on_publish(SrsRequest* req); | 60 | virtual int on_publish(SrsRequest* req); |
| 61 | virtual void on_unpublish(); | 61 | virtual void on_unpublish(); |
| 62 | -// interface ISrsThreadHandler. | 62 | +// interface ISrsReusableThreadHandler. |
| 63 | public: | 63 | public: |
| 64 | virtual int cycle(); | 64 | virtual int cycle(); |
| 65 | virtual void on_thread_stop(); | 65 | virtual void on_thread_stop(); |
| @@ -59,7 +59,7 @@ SrsForwarder::SrsForwarder(SrsSource* _source) | @@ -59,7 +59,7 @@ SrsForwarder::SrsForwarder(SrsSource* _source) | ||
| 59 | kbps = new SrsKbps(); | 59 | kbps = new SrsKbps(); |
| 60 | stream_id = 0; | 60 | stream_id = 0; |
| 61 | 61 | ||
| 62 | - pthread = new SrsThread("forward", this, SRS_FORWARDER_SLEEP_US, true); | 62 | + pthread = new SrsReusableThread2("forward", this, SRS_FORWARDER_SLEEP_US); |
| 63 | queue = new SrsMessageQueue(); | 63 | queue = new SrsMessageQueue(); |
| 64 | jitter = new SrsRtmpJitter(); | 64 | jitter = new SrsRtmpJitter(); |
| 65 | 65 | ||
| @@ -407,7 +407,7 @@ int SrsForwarder::forward() | @@ -407,7 +407,7 @@ int SrsForwarder::forward() | ||
| 407 | } | 407 | } |
| 408 | } | 408 | } |
| 409 | 409 | ||
| 410 | - while (pthread->can_loop()) { | 410 | + while (!pthread->interrupted()) { |
| 411 | pprint->elapse(); | 411 | pprint->elapse(); |
| 412 | 412 | ||
| 413 | // read from client. | 413 | // read from client. |
| @@ -48,7 +48,7 @@ class SrsKbps; | @@ -48,7 +48,7 @@ class SrsKbps; | ||
| 48 | * forward the stream to other servers. | 48 | * forward the stream to other servers. |
| 49 | */ | 49 | */ |
| 50 | // TODO: FIXME: refine the error log, comments it. | 50 | // TODO: FIXME: refine the error log, comments it. |
| 51 | -class SrsForwarder : public ISrsThreadHandler | 51 | +class SrsForwarder : public ISrsReusableThread2Handler |
| 52 | { | 52 | { |
| 53 | private: | 53 | private: |
| 54 | // the ep to forward, server[:port]. | 54 | // the ep to forward, server[:port]. |
| @@ -57,7 +57,7 @@ private: | @@ -57,7 +57,7 @@ private: | ||
| 57 | int stream_id; | 57 | int stream_id; |
| 58 | private: | 58 | private: |
| 59 | st_netfd_t stfd; | 59 | st_netfd_t stfd; |
| 60 | - SrsThread* pthread; | 60 | + SrsReusableThread2* pthread; |
| 61 | private: | 61 | private: |
| 62 | SrsSource* source; | 62 | SrsSource* source; |
| 63 | ISrsProtocolReaderWriter* io; | 63 | ISrsProtocolReaderWriter* io; |
| @@ -95,7 +95,7 @@ public: | @@ -95,7 +95,7 @@ public: | ||
| 95 | * @param shared_video, directly ptr, copy it if need to save it. | 95 | * @param shared_video, directly ptr, copy it if need to save it. |
| 96 | */ | 96 | */ |
| 97 | virtual int on_video(SrsSharedPtrMessage* shared_video); | 97 | virtual int on_video(SrsSharedPtrMessage* shared_video); |
| 98 | -// interface ISrsThreadHandler. | 98 | +// interface ISrsReusableThread2Handler. |
| 99 | public: | 99 | public: |
| 100 | virtual int cycle(); | 100 | virtual int cycle(); |
| 101 | private: | 101 | private: |
| @@ -33,9 +33,9 @@ using namespace std; | @@ -33,9 +33,9 @@ using namespace std; | ||
| 33 | #include <srs_app_config.hpp> | 33 | #include <srs_app_config.hpp> |
| 34 | #include <srs_app_http_client.hpp> | 34 | #include <srs_app_http_client.hpp> |
| 35 | #include <srs_app_json.hpp> | 35 | #include <srs_app_json.hpp> |
| 36 | -#include <srs_app_http.hpp> | ||
| 37 | #include <srs_app_utility.hpp> | 36 | #include <srs_app_utility.hpp> |
| 38 | #include <srs_core_autofree.hpp> | 37 | #include <srs_core_autofree.hpp> |
| 38 | +#include <srs_app_http_conn.hpp> | ||
| 39 | 39 | ||
| 40 | SrsHttpHeartbeat::SrsHttpHeartbeat() | 40 | SrsHttpHeartbeat::SrsHttpHeartbeat() |
| 41 | { | 41 | { |
| @@ -82,14 +82,14 @@ void SrsHttpHeartbeat::heartbeat() | @@ -82,14 +82,14 @@ void SrsHttpHeartbeat::heartbeat() | ||
| 82 | return; | 82 | return; |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | - SrsHttpMessage* msg = NULL; | 85 | + ISrsHttpMessage* msg = NULL; |
| 86 | if ((ret = http.post(uri.get_path(), req, &msg)) != ERROR_SUCCESS) { | 86 | if ((ret = http.post(uri.get_path(), req, &msg)) != ERROR_SUCCESS) { |
| 87 | srs_info("http post hartbeart uri failed. " | 87 | srs_info("http post hartbeart uri failed. " |
| 88 | "url=%s, request=%s, response=%s, ret=%d", | 88 | "url=%s, request=%s, response=%s, ret=%d", |
| 89 | url.c_str(), req.c_str(), res.c_str(), ret); | 89 | url.c_str(), req.c_str(), res.c_str(), ret); |
| 90 | return; | 90 | return; |
| 91 | } | 91 | } |
| 92 | - SrsAutoFree(SrsHttpMessage, msg); | 92 | + SrsAutoFree(ISrsHttpMessage, msg); |
| 93 | 93 | ||
| 94 | std::string res; | 94 | std::string res; |
| 95 | if ((ret = msg->body_read_all(res)) != ERROR_SUCCESS) { | 95 | if ((ret = msg->body_read_all(res)) != ERROR_SUCCESS) { |
| @@ -172,7 +172,7 @@ void SrsHlsSegment::update_duration(int64_t current_frame_dts) | @@ -172,7 +172,7 @@ void SrsHlsSegment::update_duration(int64_t current_frame_dts) | ||
| 172 | 172 | ||
| 173 | SrsDvrAsyncCallOnHls::SrsDvrAsyncCallOnHls(SrsRequest* r, string p, string t, string m, string mu, int s, double d) | 173 | SrsDvrAsyncCallOnHls::SrsDvrAsyncCallOnHls(SrsRequest* r, string p, string t, string m, string mu, int s, double d) |
| 174 | { | 174 | { |
| 175 | - req = r; | 175 | + req = r->copy(); |
| 176 | path = p; | 176 | path = p; |
| 177 | ts_url = t; | 177 | ts_url = t; |
| 178 | m3u8 = m; | 178 | m3u8 = m; |
| @@ -183,6 +183,7 @@ SrsDvrAsyncCallOnHls::SrsDvrAsyncCallOnHls(SrsRequest* r, string p, string t, st | @@ -183,6 +183,7 @@ SrsDvrAsyncCallOnHls::SrsDvrAsyncCallOnHls(SrsRequest* r, string p, string t, st | ||
| 183 | 183 | ||
| 184 | SrsDvrAsyncCallOnHls::~SrsDvrAsyncCallOnHls() | 184 | SrsDvrAsyncCallOnHls::~SrsDvrAsyncCallOnHls() |
| 185 | { | 185 | { |
| 186 | + srs_freep(req); | ||
| 186 | } | 187 | } |
| 187 | 188 | ||
| 188 | int SrsDvrAsyncCallOnHls::call() | 189 | int SrsDvrAsyncCallOnHls::call() |
| @@ -221,12 +222,13 @@ string SrsDvrAsyncCallOnHls::to_string() | @@ -221,12 +222,13 @@ string SrsDvrAsyncCallOnHls::to_string() | ||
| 221 | 222 | ||
| 222 | SrsDvrAsyncCallOnHlsNotify::SrsDvrAsyncCallOnHlsNotify(SrsRequest* r, string u) | 223 | SrsDvrAsyncCallOnHlsNotify::SrsDvrAsyncCallOnHlsNotify(SrsRequest* r, string u) |
| 223 | { | 224 | { |
| 224 | - req = r; | 225 | + req = r->copy(); |
| 225 | ts_url = u; | 226 | ts_url = u; |
| 226 | } | 227 | } |
| 227 | 228 | ||
| 228 | SrsDvrAsyncCallOnHlsNotify::~SrsDvrAsyncCallOnHlsNotify() | 229 | SrsDvrAsyncCallOnHlsNotify::~SrsDvrAsyncCallOnHlsNotify() |
| 229 | { | 230 | { |
| 231 | + srs_freep(req); | ||
| 230 | } | 232 | } |
| 231 | 233 | ||
| 232 | int SrsDvrAsyncCallOnHlsNotify::call() | 234 | int SrsDvrAsyncCallOnHlsNotify::call() |
| @@ -284,7 +286,7 @@ SrsHlsMuxer::SrsHlsMuxer() | @@ -284,7 +286,7 @@ SrsHlsMuxer::SrsHlsMuxer() | ||
| 284 | acodec = SrsCodecAudioReserved1; | 286 | acodec = SrsCodecAudioReserved1; |
| 285 | should_write_cache = false; | 287 | should_write_cache = false; |
| 286 | should_write_file = true; | 288 | should_write_file = true; |
| 287 | - async = new SrsDvrAsyncCallThread(); | 289 | + async = new SrsAsyncCallWorker(); |
| 288 | context = new SrsTsContext(); | 290 | context = new SrsTsContext(); |
| 289 | } | 291 | } |
| 290 | 292 | ||
| @@ -667,7 +669,7 @@ int SrsHlsMuxer::segment_close(string log_desc) | @@ -667,7 +669,7 @@ int SrsHlsMuxer::segment_close(string log_desc) | ||
| 667 | segments.push_back(current); | 669 | segments.push_back(current); |
| 668 | 670 | ||
| 669 | // use async to call the http hooks, for it will cause thread switch. | 671 | // use async to call the http hooks, for it will cause thread switch. |
| 670 | - if ((ret = async->call(new SrsDvrAsyncCallOnHls(req, | 672 | + if ((ret = async->execute(new SrsDvrAsyncCallOnHls(req, |
| 671 | current->full_path, current->uri, m3u8, m3u8_url, | 673 | current->full_path, current->uri, m3u8, m3u8_url, |
| 672 | current->sequence_no, current->duration))) != ERROR_SUCCESS) | 674 | current->sequence_no, current->duration))) != ERROR_SUCCESS) |
| 673 | { | 675 | { |
| @@ -675,7 +677,7 @@ int SrsHlsMuxer::segment_close(string log_desc) | @@ -675,7 +677,7 @@ int SrsHlsMuxer::segment_close(string log_desc) | ||
| 675 | } | 677 | } |
| 676 | 678 | ||
| 677 | // use async to call the http hooks, for it will cause thread switch. | 679 | // use async to call the http hooks, for it will cause thread switch. |
| 678 | - if ((ret = async->call(new SrsDvrAsyncCallOnHlsNotify(req, current->uri))) != ERROR_SUCCESS) { | 680 | + if ((ret = async->execute(new SrsDvrAsyncCallOnHlsNotify(req, current->uri))) != ERROR_SUCCESS) { |
| 679 | return ret; | 681 | return ret; |
| 680 | } | 682 | } |
| 681 | 683 |
| @@ -159,7 +159,7 @@ public: | @@ -159,7 +159,7 @@ public: | ||
| 159 | /** | 159 | /** |
| 160 | * the hls async call: on_hls | 160 | * the hls async call: on_hls |
| 161 | */ | 161 | */ |
| 162 | -class SrsDvrAsyncCallOnHls : public ISrsDvrAsyncCall | 162 | +class SrsDvrAsyncCallOnHls : public ISrsAsyncCallTask |
| 163 | { | 163 | { |
| 164 | private: | 164 | private: |
| 165 | std::string path; | 165 | std::string path; |
| @@ -180,7 +180,7 @@ public: | @@ -180,7 +180,7 @@ public: | ||
| 180 | /** | 180 | /** |
| 181 | * the hls async call: on_hls_notify | 181 | * the hls async call: on_hls_notify |
| 182 | */ | 182 | */ |
| 183 | -class SrsDvrAsyncCallOnHlsNotify : public ISrsDvrAsyncCall | 183 | +class SrsDvrAsyncCallOnHlsNotify : public ISrsAsyncCallTask |
| 184 | { | 184 | { |
| 185 | private: | 185 | private: |
| 186 | std::string ts_url; | 186 | std::string ts_url; |
| @@ -215,7 +215,7 @@ private: | @@ -215,7 +215,7 @@ private: | ||
| 215 | double hls_aof_ratio; | 215 | double hls_aof_ratio; |
| 216 | double hls_fragment; | 216 | double hls_fragment; |
| 217 | double hls_window; | 217 | double hls_window; |
| 218 | - SrsDvrAsyncCallThread* async; | 218 | + SrsAsyncCallWorker* async; |
| 219 | private: | 219 | private: |
| 220 | // whether use floor algorithm for timestamp. | 220 | // whether use floor algorithm for timestamp. |
| 221 | bool hls_ts_floor; | 221 | bool hls_ts_floor; |
trunk/src/app/srs_app_http.cpp
已删除
100644 → 0
| 1 | -/* | ||
| 2 | -The MIT License (MIT) | ||
| 3 | - | ||
| 4 | -Copyright (c) 2013-2015 SRS(simple-rtmp-server) | ||
| 5 | - | ||
| 6 | -Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
| 7 | -this software and associated documentation files (the "Software"), to deal in | ||
| 8 | -the Software without restriction, including without limitation the rights to | ||
| 9 | -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
| 10 | -the Software, and to permit persons to whom the Software is furnished to do so, | ||
| 11 | -subject to the following conditions: | ||
| 12 | - | ||
| 13 | -The above copyright notice and this permission notice shall be included in all | ||
| 14 | -copies or substantial portions of the Software. | ||
| 15 | - | ||
| 16 | -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
| 18 | -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
| 19 | -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
| 20 | -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 21 | -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 22 | -*/ | ||
| 23 | - | ||
| 24 | -#include <srs_app_http.hpp> | ||
| 25 | - | ||
| 26 | -#ifdef SRS_AUTO_HTTP_PARSER | ||
| 27 | - | ||
| 28 | -#include <stdlib.h> | ||
| 29 | -#include <sys/stat.h> | ||
| 30 | -#include <algorithm> | ||
| 31 | -using namespace std; | ||
| 32 | - | ||
| 33 | -#include <srs_kernel_error.hpp> | ||
| 34 | -#include <srs_kernel_log.hpp> | ||
| 35 | -#include <srs_app_st_socket.hpp> | ||
| 36 | -#include <srs_app_http_api.hpp> | ||
| 37 | -#include <srs_app_http_conn.hpp> | ||
| 38 | -#include <srs_app_json.hpp> | ||
| 39 | -#include <srs_kernel_utility.hpp> | ||
| 40 | -#include <srs_rtmp_buffer.hpp> | ||
| 41 | -#include <srs_kernel_file.hpp> | ||
| 42 | -#include <srs_core_autofree.hpp> | ||
| 43 | -#include <srs_rtmp_buffer.hpp> | ||
| 44 | -#include <srs_rtmp_sdk.hpp> | ||
| 45 | -#include <srs_rtmp_utility.hpp> | ||
| 46 | - | ||
| 47 | -#define SRS_DEFAULT_HTTP_PORT 80 | ||
| 48 | - | ||
| 49 | -// for http parser macros | ||
| 50 | -#define SRS_CONSTS_HTTP_OPTIONS HTTP_OPTIONS | ||
| 51 | -#define SRS_CONSTS_HTTP_GET HTTP_GET | ||
| 52 | -#define SRS_CONSTS_HTTP_POST HTTP_POST | ||
| 53 | -#define SRS_CONSTS_HTTP_PUT HTTP_PUT | ||
| 54 | -#define SRS_CONSTS_HTTP_DELETE HTTP_DELETE | ||
| 55 | - | ||
| 56 | -// for ead all of http body, read each time. | ||
| 57 | -#define SRS_HTTP_READ_CACHE_BYTES 4096 | ||
| 58 | - | ||
| 59 | -#define SRS_HTTP_DEFAULT_PAGE "index.html" | ||
| 60 | - | ||
| 61 | -int srs_go_http_response_json(ISrsHttpResponseWriter* w, string data) | ||
| 62 | -{ | ||
| 63 | - w->header()->set_content_length(data.length()); | ||
| 64 | - w->header()->set_content_type("application/json"); | ||
| 65 | - | ||
| 66 | - return w->write((char*)data.data(), (int)data.length()); | ||
| 67 | -} | ||
| 68 | - | ||
| 69 | -// get the status text of code. | ||
| 70 | -string srs_generate_http_status_text(int status) | ||
| 71 | -{ | ||
| 72 | - static std::map<int, std::string> _status_map; | ||
| 73 | - if (_status_map.empty()) { | ||
| 74 | - _status_map[SRS_CONSTS_HTTP_Continue ] = SRS_CONSTS_HTTP_Continue_str ; | ||
| 75 | - _status_map[SRS_CONSTS_HTTP_SwitchingProtocols ] = SRS_CONSTS_HTTP_SwitchingProtocols_str ; | ||
| 76 | - _status_map[SRS_CONSTS_HTTP_OK ] = SRS_CONSTS_HTTP_OK_str ; | ||
| 77 | - _status_map[SRS_CONSTS_HTTP_Created ] = SRS_CONSTS_HTTP_Created_str ; | ||
| 78 | - _status_map[SRS_CONSTS_HTTP_Accepted ] = SRS_CONSTS_HTTP_Accepted_str ; | ||
| 79 | - _status_map[SRS_CONSTS_HTTP_NonAuthoritativeInformation ] = SRS_CONSTS_HTTP_NonAuthoritativeInformation_str ; | ||
| 80 | - _status_map[SRS_CONSTS_HTTP_NoContent ] = SRS_CONSTS_HTTP_NoContent_str ; | ||
| 81 | - _status_map[SRS_CONSTS_HTTP_ResetContent ] = SRS_CONSTS_HTTP_ResetContent_str ; | ||
| 82 | - _status_map[SRS_CONSTS_HTTP_PartialContent ] = SRS_CONSTS_HTTP_PartialContent_str ; | ||
| 83 | - _status_map[SRS_CONSTS_HTTP_MultipleChoices ] = SRS_CONSTS_HTTP_MultipleChoices_str ; | ||
| 84 | - _status_map[SRS_CONSTS_HTTP_MovedPermanently ] = SRS_CONSTS_HTTP_MovedPermanently_str ; | ||
| 85 | - _status_map[SRS_CONSTS_HTTP_Found ] = SRS_CONSTS_HTTP_Found_str ; | ||
| 86 | - _status_map[SRS_CONSTS_HTTP_SeeOther ] = SRS_CONSTS_HTTP_SeeOther_str ; | ||
| 87 | - _status_map[SRS_CONSTS_HTTP_NotModified ] = SRS_CONSTS_HTTP_NotModified_str ; | ||
| 88 | - _status_map[SRS_CONSTS_HTTP_UseProxy ] = SRS_CONSTS_HTTP_UseProxy_str ; | ||
| 89 | - _status_map[SRS_CONSTS_HTTP_TemporaryRedirect ] = SRS_CONSTS_HTTP_TemporaryRedirect_str ; | ||
| 90 | - _status_map[SRS_CONSTS_HTTP_BadRequest ] = SRS_CONSTS_HTTP_BadRequest_str ; | ||
| 91 | - _status_map[SRS_CONSTS_HTTP_Unauthorized ] = SRS_CONSTS_HTTP_Unauthorized_str ; | ||
| 92 | - _status_map[SRS_CONSTS_HTTP_PaymentRequired ] = SRS_CONSTS_HTTP_PaymentRequired_str ; | ||
| 93 | - _status_map[SRS_CONSTS_HTTP_Forbidden ] = SRS_CONSTS_HTTP_Forbidden_str ; | ||
| 94 | - _status_map[SRS_CONSTS_HTTP_NotFound ] = SRS_CONSTS_HTTP_NotFound_str ; | ||
| 95 | - _status_map[SRS_CONSTS_HTTP_MethodNotAllowed ] = SRS_CONSTS_HTTP_MethodNotAllowed_str ; | ||
| 96 | - _status_map[SRS_CONSTS_HTTP_NotAcceptable ] = SRS_CONSTS_HTTP_NotAcceptable_str ; | ||
| 97 | - _status_map[SRS_CONSTS_HTTP_ProxyAuthenticationRequired ] = SRS_CONSTS_HTTP_ProxyAuthenticationRequired_str ; | ||
| 98 | - _status_map[SRS_CONSTS_HTTP_RequestTimeout ] = SRS_CONSTS_HTTP_RequestTimeout_str ; | ||
| 99 | - _status_map[SRS_CONSTS_HTTP_Conflict ] = SRS_CONSTS_HTTP_Conflict_str ; | ||
| 100 | - _status_map[SRS_CONSTS_HTTP_Gone ] = SRS_CONSTS_HTTP_Gone_str ; | ||
| 101 | - _status_map[SRS_CONSTS_HTTP_LengthRequired ] = SRS_CONSTS_HTTP_LengthRequired_str ; | ||
| 102 | - _status_map[SRS_CONSTS_HTTP_PreconditionFailed ] = SRS_CONSTS_HTTP_PreconditionFailed_str ; | ||
| 103 | - _status_map[SRS_CONSTS_HTTP_RequestEntityTooLarge ] = SRS_CONSTS_HTTP_RequestEntityTooLarge_str ; | ||
| 104 | - _status_map[SRS_CONSTS_HTTP_RequestURITooLarge ] = SRS_CONSTS_HTTP_RequestURITooLarge_str ; | ||
| 105 | - _status_map[SRS_CONSTS_HTTP_UnsupportedMediaType ] = SRS_CONSTS_HTTP_UnsupportedMediaType_str ; | ||
| 106 | - _status_map[SRS_CONSTS_HTTP_RequestedRangeNotSatisfiable ] = SRS_CONSTS_HTTP_RequestedRangeNotSatisfiable_str ; | ||
| 107 | - _status_map[SRS_CONSTS_HTTP_ExpectationFailed ] = SRS_CONSTS_HTTP_ExpectationFailed_str ; | ||
| 108 | - _status_map[SRS_CONSTS_HTTP_InternalServerError ] = SRS_CONSTS_HTTP_InternalServerError_str ; | ||
| 109 | - _status_map[SRS_CONSTS_HTTP_NotImplemented ] = SRS_CONSTS_HTTP_NotImplemented_str ; | ||
| 110 | - _status_map[SRS_CONSTS_HTTP_BadGateway ] = SRS_CONSTS_HTTP_BadGateway_str ; | ||
| 111 | - _status_map[SRS_CONSTS_HTTP_ServiceUnavailable ] = SRS_CONSTS_HTTP_ServiceUnavailable_str ; | ||
| 112 | - _status_map[SRS_CONSTS_HTTP_GatewayTimeout ] = SRS_CONSTS_HTTP_GatewayTimeout_str ; | ||
| 113 | - _status_map[SRS_CONSTS_HTTP_HTTPVersionNotSupported ] = SRS_CONSTS_HTTP_HTTPVersionNotSupported_str ; | ||
| 114 | - } | ||
| 115 | - | ||
| 116 | - std::string status_text; | ||
| 117 | - if (_status_map.find(status) == _status_map.end()) { | ||
| 118 | - status_text = "Status Unknown"; | ||
| 119 | - } else { | ||
| 120 | - status_text = _status_map[status]; | ||
| 121 | - } | ||
| 122 | - | ||
| 123 | - return status_text; | ||
| 124 | -} | ||
| 125 | - | ||
| 126 | -// bodyAllowedForStatus reports whether a given response status code | ||
| 127 | -// permits a body. See RFC2616, section 4.4. | ||
| 128 | -bool srs_go_http_body_allowd(int status) | ||
| 129 | -{ | ||
| 130 | - if (status >= 100 && status <= 199) { | ||
| 131 | - return false; | ||
| 132 | - } else if (status == 204 || status == 304) { | ||
| 133 | - return false; | ||
| 134 | - } | ||
| 135 | - | ||
| 136 | - return true; | ||
| 137 | -} | ||
| 138 | - | ||
| 139 | -// DetectContentType implements the algorithm described | ||
| 140 | -// at http://mimesniff.spec.whatwg.org/ to determine the | ||
| 141 | -// Content-Type of the given data. It considers at most the | ||
| 142 | -// first 512 bytes of data. DetectContentType always returns | ||
| 143 | -// a valid MIME type: if it cannot determine a more specific one, it | ||
| 144 | -// returns "application/octet-stream". | ||
| 145 | -string srs_go_http_detect(char* data, int size) | ||
| 146 | -{ | ||
| 147 | - // detect only when data specified. | ||
| 148 | - if (data) { | ||
| 149 | - } | ||
| 150 | - return "application/octet-stream"; // fallback | ||
| 151 | -} | ||
| 152 | - | ||
| 153 | -// Error replies to the request with the specified error message and HTTP code. | ||
| 154 | -// The error message should be plain text. | ||
| 155 | -int srs_go_http_error(ISrsHttpResponseWriter* w, int code, string error) | ||
| 156 | -{ | ||
| 157 | - int ret = ERROR_SUCCESS; | ||
| 158 | - | ||
| 159 | - w->header()->set_content_type("text/plain; charset=utf-8"); | ||
| 160 | - w->header()->set_content_length(error.length()); | ||
| 161 | - w->write_header(code); | ||
| 162 | - w->write((char*)error.data(), (int)error.length()); | ||
| 163 | - | ||
| 164 | - return ret; | ||
| 165 | -} | ||
| 166 | - | ||
| 167 | -SrsHttpHeader::SrsHttpHeader() | ||
| 168 | -{ | ||
| 169 | -} | ||
| 170 | - | ||
| 171 | -SrsHttpHeader::~SrsHttpHeader() | ||
| 172 | -{ | ||
| 173 | -} | ||
| 174 | - | ||
| 175 | -void SrsHttpHeader::set(string key, string value) | ||
| 176 | -{ | ||
| 177 | - headers[key] = value; | ||
| 178 | -} | ||
| 179 | - | ||
| 180 | -string SrsHttpHeader::get(string key) | ||
| 181 | -{ | ||
| 182 | - std::string v; | ||
| 183 | - | ||
| 184 | - if (headers.find(key) != headers.end()) { | ||
| 185 | - v = headers[key]; | ||
| 186 | - } | ||
| 187 | - | ||
| 188 | - return v; | ||
| 189 | -} | ||
| 190 | - | ||
| 191 | -int64_t SrsHttpHeader::content_length() | ||
| 192 | -{ | ||
| 193 | - std::string cl = get("Content-Length"); | ||
| 194 | - | ||
| 195 | - if (cl.empty()) { | ||
| 196 | - return -1; | ||
| 197 | - } | ||
| 198 | - | ||
| 199 | - return (int64_t)::atof(cl.c_str()); | ||
| 200 | -} | ||
| 201 | - | ||
| 202 | -void SrsHttpHeader::set_content_length(int64_t size) | ||
| 203 | -{ | ||
| 204 | - char buf[64]; | ||
| 205 | - snprintf(buf, sizeof(buf), "%"PRId64, size); | ||
| 206 | - set("Content-Length", buf); | ||
| 207 | -} | ||
| 208 | - | ||
| 209 | -string SrsHttpHeader::content_type() | ||
| 210 | -{ | ||
| 211 | - return get("Content-Type"); | ||
| 212 | -} | ||
| 213 | - | ||
| 214 | -void SrsHttpHeader::set_content_type(string ct) | ||
| 215 | -{ | ||
| 216 | - set("Content-Type", ct); | ||
| 217 | -} | ||
| 218 | - | ||
| 219 | -void SrsHttpHeader::write(stringstream& ss) | ||
| 220 | -{ | ||
| 221 | - std::map<std::string, std::string>::iterator it; | ||
| 222 | - for (it = headers.begin(); it != headers.end(); ++it) { | ||
| 223 | - ss << it->first << ": " << it->second << SRS_HTTP_CRLF; | ||
| 224 | - } | ||
| 225 | -} | ||
| 226 | - | ||
| 227 | -ISrsHttpResponseWriter::ISrsHttpResponseWriter() | ||
| 228 | -{ | ||
| 229 | -} | ||
| 230 | - | ||
| 231 | -ISrsHttpResponseWriter::~ISrsHttpResponseWriter() | ||
| 232 | -{ | ||
| 233 | -} | ||
| 234 | - | ||
| 235 | -ISrsHttpResponseReader::ISrsHttpResponseReader() | ||
| 236 | -{ | ||
| 237 | -} | ||
| 238 | - | ||
| 239 | -ISrsHttpResponseReader::~ISrsHttpResponseReader() | ||
| 240 | -{ | ||
| 241 | -} | ||
| 242 | - | ||
| 243 | -ISrsHttpHandler::ISrsHttpHandler() | ||
| 244 | -{ | ||
| 245 | - entry = NULL; | ||
| 246 | -} | ||
| 247 | - | ||
| 248 | -ISrsHttpHandler::~ISrsHttpHandler() | ||
| 249 | -{ | ||
| 250 | -} | ||
| 251 | - | ||
| 252 | -SrsHttpRedirectHandler::SrsHttpRedirectHandler(string u, int c) | ||
| 253 | -{ | ||
| 254 | - url = u; | ||
| 255 | - code = c; | ||
| 256 | -} | ||
| 257 | - | ||
| 258 | -SrsHttpRedirectHandler::~SrsHttpRedirectHandler() | ||
| 259 | -{ | ||
| 260 | -} | ||
| 261 | - | ||
| 262 | -int SrsHttpRedirectHandler::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | ||
| 263 | -{ | ||
| 264 | - int ret = ERROR_SUCCESS; | ||
| 265 | - // TODO: FIXME: implements it. | ||
| 266 | - return ret; | ||
| 267 | -} | ||
| 268 | - | ||
| 269 | -SrsHttpNotFoundHandler::SrsHttpNotFoundHandler() | ||
| 270 | -{ | ||
| 271 | -} | ||
| 272 | - | ||
| 273 | -SrsHttpNotFoundHandler::~SrsHttpNotFoundHandler() | ||
| 274 | -{ | ||
| 275 | -} | ||
| 276 | - | ||
| 277 | -int SrsHttpNotFoundHandler::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | ||
| 278 | -{ | ||
| 279 | - return srs_go_http_error(w, | ||
| 280 | - SRS_CONSTS_HTTP_NotFound, SRS_CONSTS_HTTP_NotFound_str); | ||
| 281 | -} | ||
| 282 | - | ||
| 283 | -SrsHttpFileServer::SrsHttpFileServer(string root_dir) | ||
| 284 | -{ | ||
| 285 | - dir = root_dir; | ||
| 286 | -} | ||
| 287 | - | ||
| 288 | -SrsHttpFileServer::~SrsHttpFileServer() | ||
| 289 | -{ | ||
| 290 | -} | ||
| 291 | - | ||
| 292 | -int SrsHttpFileServer::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | ||
| 293 | -{ | ||
| 294 | - string upath = r->path(); | ||
| 295 | - | ||
| 296 | - // add default pages. | ||
| 297 | - if (srs_string_ends_with(upath, "/")) { | ||
| 298 | - upath += SRS_HTTP_DEFAULT_PAGE; | ||
| 299 | - } | ||
| 300 | - | ||
| 301 | - string fullpath = dir + "/"; | ||
| 302 | - | ||
| 303 | - // remove the virtual directory. | ||
| 304 | - srs_assert(entry); | ||
| 305 | - size_t pos = entry->pattern.find("/"); | ||
| 306 | - if (upath.length() > entry->pattern.length() && pos != string::npos) { | ||
| 307 | - fullpath += upath.substr(entry->pattern.length() - pos); | ||
| 308 | - } else { | ||
| 309 | - fullpath += upath; | ||
| 310 | - } | ||
| 311 | - | ||
| 312 | - // stat current dir, if exists, return error. | ||
| 313 | - if (!srs_path_exists(fullpath)) { | ||
| 314 | - srs_warn("http miss file=%s, pattern=%s, upath=%s", | ||
| 315 | - fullpath.c_str(), entry->pattern.c_str(), upath.c_str()); | ||
| 316 | - return SrsHttpNotFoundHandler().serve_http(w, r); | ||
| 317 | - } | ||
| 318 | - srs_trace("http match file=%s, pattern=%s, upath=%s", | ||
| 319 | - fullpath.c_str(), entry->pattern.c_str(), upath.c_str()); | ||
| 320 | - | ||
| 321 | - // handle file according to its extension. | ||
| 322 | - // use vod stream for .flv/.fhv | ||
| 323 | - if (srs_string_ends_with(fullpath, ".flv") || srs_string_ends_with(fullpath, ".fhv")) { | ||
| 324 | - return serve_flv_file(w, r, fullpath); | ||
| 325 | - } else if (srs_string_ends_with(fullpath, ".mp4")) { | ||
| 326 | - return serve_mp4_file(w, r, fullpath); | ||
| 327 | - } | ||
| 328 | - | ||
| 329 | - // serve common static file. | ||
| 330 | - return serve_file(w, r, fullpath); | ||
| 331 | -} | ||
| 332 | - | ||
| 333 | -int SrsHttpFileServer::serve_file(ISrsHttpResponseWriter* w, SrsHttpMessage* r, string fullpath) | ||
| 334 | -{ | ||
| 335 | - int ret = ERROR_SUCCESS; | ||
| 336 | - | ||
| 337 | - // open the target file. | ||
| 338 | - SrsFileReader fs; | ||
| 339 | - | ||
| 340 | - if ((ret = fs.open(fullpath)) != ERROR_SUCCESS) { | ||
| 341 | - srs_warn("open file %s failed, ret=%d", fullpath.c_str(), ret); | ||
| 342 | - return ret; | ||
| 343 | - } | ||
| 344 | - | ||
| 345 | - int64_t length = fs.filesize(); | ||
| 346 | - | ||
| 347 | - // unset the content length to encode in chunked encoding. | ||
| 348 | - w->header()->set_content_length(length); | ||
| 349 | - | ||
| 350 | - static std::map<std::string, std::string> _mime; | ||
| 351 | - if (_mime.empty()) { | ||
| 352 | - _mime[".ts"] = "video/MP2T"; | ||
| 353 | - _mime[".flv"] = "video/x-flv"; | ||
| 354 | - _mime[".m4v"] = "video/x-m4v"; | ||
| 355 | - _mime[".3gpp"] = "video/3gpp"; | ||
| 356 | - _mime[".3gp"] = "video/3gpp"; | ||
| 357 | - _mime[".mp4"] = "video/mp4"; | ||
| 358 | - _mime[".aac"] = "audio/x-aac"; | ||
| 359 | - _mime[".mp3"] = "audio/mpeg"; | ||
| 360 | - _mime[".m4a"] = "audio/x-m4a"; | ||
| 361 | - _mime[".ogg"] = "audio/ogg"; | ||
| 362 | - // @see hls-m3u8-draft-pantos-http-live-streaming-12.pdf, page 5. | ||
| 363 | - _mime[".m3u8"] = "application/vnd.apple.mpegurl"; // application/x-mpegURL | ||
| 364 | - _mime[".rss"] = "application/rss+xml"; | ||
| 365 | - _mime[".json"] = "application/json"; | ||
| 366 | - _mime[".swf"] = "application/x-shockwave-flash"; | ||
| 367 | - _mime[".doc"] = "application/msword"; | ||
| 368 | - _mime[".zip"] = "application/zip"; | ||
| 369 | - _mime[".rar"] = "application/x-rar-compressed"; | ||
| 370 | - _mime[".xml"] = "text/xml"; | ||
| 371 | - _mime[".html"] = "text/html"; | ||
| 372 | - _mime[".js"] = "text/javascript"; | ||
| 373 | - _mime[".css"] = "text/css"; | ||
| 374 | - _mime[".ico"] = "image/x-icon"; | ||
| 375 | - _mime[".png"] = "image/png"; | ||
| 376 | - _mime[".jpeg"] = "image/jpeg"; | ||
| 377 | - _mime[".jpg"] = "image/jpeg"; | ||
| 378 | - _mime[".gif"] = "image/gif"; | ||
| 379 | - } | ||
| 380 | - | ||
| 381 | - if (true) { | ||
| 382 | - size_t pos; | ||
| 383 | - std::string ext = fullpath; | ||
| 384 | - if ((pos = ext.rfind(".")) != string::npos) { | ||
| 385 | - ext = ext.substr(pos); | ||
| 386 | - } | ||
| 387 | - | ||
| 388 | - if (_mime.find(ext) == _mime.end()) { | ||
| 389 | - w->header()->set_content_type("application/octet-stream"); | ||
| 390 | - } else { | ||
| 391 | - w->header()->set_content_type(_mime[ext]); | ||
| 392 | - } | ||
| 393 | - } | ||
| 394 | - | ||
| 395 | - // write body. | ||
| 396 | - int64_t left = length; | ||
| 397 | - if ((ret = copy(w, &fs, r, (int)left)) != ERROR_SUCCESS) { | ||
| 398 | - if (!srs_is_client_gracefully_close(ret)) { | ||
| 399 | - srs_error("read file=%s size=%d failed, ret=%d", fullpath.c_str(), left, ret); | ||
| 400 | - } | ||
| 401 | - return ret; | ||
| 402 | - } | ||
| 403 | - | ||
| 404 | - return w->final_request(); | ||
| 405 | -} | ||
| 406 | - | ||
| 407 | -int SrsHttpFileServer::serve_flv_file(ISrsHttpResponseWriter* w, SrsHttpMessage* r, string fullpath) | ||
| 408 | -{ | ||
| 409 | - std::string start = r->query_get("start"); | ||
| 410 | - if (start.empty()) { | ||
| 411 | - return serve_file(w, r, fullpath); | ||
| 412 | - } | ||
| 413 | - | ||
| 414 | - int offset = ::atoi(start.c_str()); | ||
| 415 | - if (offset <= 0) { | ||
| 416 | - return serve_file(w, r, fullpath); | ||
| 417 | - } | ||
| 418 | - | ||
| 419 | - return serve_flv_stream(w, r, fullpath, offset); | ||
| 420 | -} | ||
| 421 | - | ||
| 422 | -int SrsHttpFileServer::serve_mp4_file(ISrsHttpResponseWriter* w, SrsHttpMessage* r, string fullpath) | ||
| 423 | -{ | ||
| 424 | - // for flash to request mp4 range in query string. | ||
| 425 | - // for example, http://digitalprimates.net/dash/DashTest.html?url=http://dashdemo.edgesuite.net/digitalprimates/nexus/oops-20120802-manifest.mpd | ||
| 426 | - std::string range = r->query_get("range"); | ||
| 427 | - // or, use bytes to request range, | ||
| 428 | - // for example, http://dashas.castlabs.com/demo/try.html | ||
| 429 | - if (range.empty()) { | ||
| 430 | - range = r->query_get("bytes"); | ||
| 431 | - } | ||
| 432 | - | ||
| 433 | - // rollback to serve whole file. | ||
| 434 | - size_t pos = string::npos; | ||
| 435 | - if (range.empty() || (pos = range.find("-")) == string::npos) { | ||
| 436 | - return serve_file(w, r, fullpath); | ||
| 437 | - } | ||
| 438 | - | ||
| 439 | - // parse the start in query string | ||
| 440 | - int start = 0; | ||
| 441 | - if (pos > 0) { | ||
| 442 | - start = ::atoi(range.substr(0, pos).c_str()); | ||
| 443 | - } | ||
| 444 | - | ||
| 445 | - // parse end in query string. | ||
| 446 | - int end = -1; | ||
| 447 | - if (pos < range.length() - 1) { | ||
| 448 | - end = ::atoi(range.substr(pos + 1).c_str()); | ||
| 449 | - } | ||
| 450 | - | ||
| 451 | - // invalid param, serve as whole mp4 file. | ||
| 452 | - if (start < 0 || (end != -1 && start > end)) { | ||
| 453 | - return serve_file(w, r, fullpath); | ||
| 454 | - } | ||
| 455 | - | ||
| 456 | - return serve_mp4_stream(w, r, fullpath, start, end); | ||
| 457 | -} | ||
| 458 | - | ||
| 459 | -int SrsHttpFileServer::serve_flv_stream(ISrsHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int offset) | ||
| 460 | -{ | ||
| 461 | - return serve_file(w, r, fullpath); | ||
| 462 | -} | ||
| 463 | - | ||
| 464 | -int SrsHttpFileServer::serve_mp4_stream(ISrsHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int start, int end) | ||
| 465 | -{ | ||
| 466 | - return serve_file(w, r, fullpath); | ||
| 467 | -} | ||
| 468 | - | ||
| 469 | -int SrsHttpFileServer::copy(ISrsHttpResponseWriter* w, SrsFileReader* fs, SrsHttpMessage* r, int size) | ||
| 470 | -{ | ||
| 471 | - int ret = ERROR_SUCCESS; | ||
| 472 | - | ||
| 473 | - int left = size; | ||
| 474 | - char* buf = r->http_ts_send_buffer(); | ||
| 475 | - | ||
| 476 | - while (left > 0) { | ||
| 477 | - ssize_t nread = -1; | ||
| 478 | - int max_read = srs_min(left, SRS_HTTP_TS_SEND_BUFFER_SIZE); | ||
| 479 | - if ((ret = fs->read(buf, max_read, &nread)) != ERROR_SUCCESS) { | ||
| 480 | - break; | ||
| 481 | - } | ||
| 482 | - | ||
| 483 | - left -= nread; | ||
| 484 | - if ((ret = w->write(buf, (int)nread)) != ERROR_SUCCESS) { | ||
| 485 | - break; | ||
| 486 | - } | ||
| 487 | - } | ||
| 488 | - | ||
| 489 | - return ret; | ||
| 490 | -} | ||
| 491 | - | ||
| 492 | -SrsHttpMuxEntry::SrsHttpMuxEntry() | ||
| 493 | -{ | ||
| 494 | - enabled = true; | ||
| 495 | - explicit_match = false; | ||
| 496 | - handler = NULL; | ||
| 497 | -} | ||
| 498 | - | ||
| 499 | -SrsHttpMuxEntry::~SrsHttpMuxEntry() | ||
| 500 | -{ | ||
| 501 | - srs_freep(handler); | ||
| 502 | -} | ||
| 503 | - | ||
| 504 | -ISrsHttpMatchHijacker::ISrsHttpMatchHijacker() | ||
| 505 | -{ | ||
| 506 | -} | ||
| 507 | - | ||
| 508 | -ISrsHttpMatchHijacker::~ISrsHttpMatchHijacker() | ||
| 509 | -{ | ||
| 510 | -} | ||
| 511 | - | ||
| 512 | -SrsHttpServeMux::SrsHttpServeMux() | ||
| 513 | -{ | ||
| 514 | -} | ||
| 515 | - | ||
| 516 | -SrsHttpServeMux::~SrsHttpServeMux() | ||
| 517 | -{ | ||
| 518 | - std::map<std::string, SrsHttpMuxEntry*>::iterator it; | ||
| 519 | - for (it = entries.begin(); it != entries.end(); ++it) { | ||
| 520 | - SrsHttpMuxEntry* entry = it->second; | ||
| 521 | - srs_freep(entry); | ||
| 522 | - } | ||
| 523 | - entries.clear(); | ||
| 524 | - | ||
| 525 | - vhosts.clear(); | ||
| 526 | - hijackers.clear(); | ||
| 527 | -} | ||
| 528 | - | ||
| 529 | -int SrsHttpServeMux::initialize() | ||
| 530 | -{ | ||
| 531 | - int ret = ERROR_SUCCESS; | ||
| 532 | - // TODO: FIXME: implements it. | ||
| 533 | - return ret; | ||
| 534 | -} | ||
| 535 | - | ||
| 536 | -void SrsHttpServeMux::hijack(ISrsHttpMatchHijacker* h) | ||
| 537 | -{ | ||
| 538 | - std::vector<ISrsHttpMatchHijacker*>::iterator it = ::find(hijackers.begin(), hijackers.end(), h); | ||
| 539 | - if (it != hijackers.end()) { | ||
| 540 | - return; | ||
| 541 | - } | ||
| 542 | - hijackers.push_back(h); | ||
| 543 | -} | ||
| 544 | - | ||
| 545 | -void SrsHttpServeMux::unhijack(ISrsHttpMatchHijacker* h) | ||
| 546 | -{ | ||
| 547 | - std::vector<ISrsHttpMatchHijacker*>::iterator it = ::find(hijackers.begin(), hijackers.end(), h); | ||
| 548 | - if (it == hijackers.end()) { | ||
| 549 | - return; | ||
| 550 | - } | ||
| 551 | - hijackers.erase(it); | ||
| 552 | -} | ||
| 553 | - | ||
| 554 | -int SrsHttpServeMux::handle(std::string pattern, ISrsHttpHandler* handler) | ||
| 555 | -{ | ||
| 556 | - int ret = ERROR_SUCCESS; | ||
| 557 | - | ||
| 558 | - srs_assert(handler); | ||
| 559 | - | ||
| 560 | - if (pattern.empty()) { | ||
| 561 | - ret = ERROR_HTTP_PATTERN_EMPTY; | ||
| 562 | - srs_error("http: empty pattern. ret=%d", ret); | ||
| 563 | - return ret; | ||
| 564 | - } | ||
| 565 | - | ||
| 566 | - if (entries.find(pattern) != entries.end()) { | ||
| 567 | - SrsHttpMuxEntry* exists = entries[pattern]; | ||
| 568 | - if (exists->explicit_match) { | ||
| 569 | - ret = ERROR_HTTP_PATTERN_DUPLICATED; | ||
| 570 | - srs_error("http: multiple registrations for %s. ret=%d", pattern.c_str(), ret); | ||
| 571 | - return ret; | ||
| 572 | - } | ||
| 573 | - } | ||
| 574 | - | ||
| 575 | - std::string vhost = pattern; | ||
| 576 | - if (pattern.at(0) != '/') { | ||
| 577 | - if (pattern.find("/") != string::npos) { | ||
| 578 | - vhost = pattern.substr(0, pattern.find("/")); | ||
| 579 | - } | ||
| 580 | - vhosts[vhost] = handler; | ||
| 581 | - } | ||
| 582 | - | ||
| 583 | - if (true) { | ||
| 584 | - SrsHttpMuxEntry* entry = new SrsHttpMuxEntry(); | ||
| 585 | - entry->explicit_match = true; | ||
| 586 | - entry->handler = handler; | ||
| 587 | - entry->pattern = pattern; | ||
| 588 | - entry->handler->entry = entry; | ||
| 589 | - | ||
| 590 | - if (entries.find(pattern) != entries.end()) { | ||
| 591 | - SrsHttpMuxEntry* exists = entries[pattern]; | ||
| 592 | - srs_freep(exists); | ||
| 593 | - } | ||
| 594 | - entries[pattern] = entry; | ||
| 595 | - } | ||
| 596 | - | ||
| 597 | - // Helpful behavior: | ||
| 598 | - // If pattern is /tree/, insert an implicit permanent redirect for /tree. | ||
| 599 | - // It can be overridden by an explicit registration. | ||
| 600 | - if (pattern != "/" && !pattern.empty() && pattern.at(pattern.length() - 1) == '/') { | ||
| 601 | - std::string rpattern = pattern.substr(0, pattern.length() - 1); | ||
| 602 | - SrsHttpMuxEntry* entry = NULL; | ||
| 603 | - | ||
| 604 | - // free the exists not explicit entry | ||
| 605 | - if (entries.find(rpattern) != entries.end()) { | ||
| 606 | - SrsHttpMuxEntry* exists = entries[rpattern]; | ||
| 607 | - if (!exists->explicit_match) { | ||
| 608 | - entry = exists; | ||
| 609 | - } | ||
| 610 | - } | ||
| 611 | - | ||
| 612 | - // create implicit redirect. | ||
| 613 | - if (!entry || entry->explicit_match) { | ||
| 614 | - srs_freep(entry); | ||
| 615 | - | ||
| 616 | - entry = new SrsHttpMuxEntry(); | ||
| 617 | - entry->explicit_match = false; | ||
| 618 | - entry->handler = new SrsHttpRedirectHandler(pattern, SRS_CONSTS_HTTP_MovedPermanently); | ||
| 619 | - entry->pattern = pattern; | ||
| 620 | - entry->handler->entry = entry; | ||
| 621 | - | ||
| 622 | - entries[rpattern] = entry; | ||
| 623 | - } | ||
| 624 | - } | ||
| 625 | - | ||
| 626 | - return ret; | ||
| 627 | -} | ||
| 628 | - | ||
| 629 | -int SrsHttpServeMux::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | ||
| 630 | -{ | ||
| 631 | - int ret = ERROR_SUCCESS; | ||
| 632 | - | ||
| 633 | - ISrsHttpHandler* h = NULL; | ||
| 634 | - if ((ret = find_handler(r, &h)) != ERROR_SUCCESS) { | ||
| 635 | - srs_error("find handler failed. ret=%d", ret); | ||
| 636 | - return ret; | ||
| 637 | - } | ||
| 638 | - | ||
| 639 | - srs_assert(h); | ||
| 640 | - if ((ret = h->serve_http(w, r)) != ERROR_SUCCESS) { | ||
| 641 | - if (!srs_is_client_gracefully_close(ret)) { | ||
| 642 | - srs_error("handler serve http failed. ret=%d", ret); | ||
| 643 | - } | ||
| 644 | - return ret; | ||
| 645 | - } | ||
| 646 | - | ||
| 647 | - return ret; | ||
| 648 | -} | ||
| 649 | - | ||
| 650 | -int SrsHttpServeMux::find_handler(SrsHttpMessage* r, ISrsHttpHandler** ph) | ||
| 651 | -{ | ||
| 652 | - int ret = ERROR_SUCCESS; | ||
| 653 | - | ||
| 654 | - // TODO: FIXME: support the path . and .. | ||
| 655 | - if (r->url().find("..") != std::string::npos) { | ||
| 656 | - ret = ERROR_HTTP_URL_NOT_CLEAN; | ||
| 657 | - srs_error("htt url not canonical, url=%s. ret=%d", r->url().c_str(), ret); | ||
| 658 | - return ret; | ||
| 659 | - } | ||
| 660 | - | ||
| 661 | - if ((ret = match(r, ph)) != ERROR_SUCCESS) { | ||
| 662 | - srs_error("http match handler failed. ret=%d", ret); | ||
| 663 | - return ret; | ||
| 664 | - } | ||
| 665 | - | ||
| 666 | - // always hijack. | ||
| 667 | - if (!hijackers.empty()) { | ||
| 668 | - // notice all hijacker the match failed. | ||
| 669 | - std::vector<ISrsHttpMatchHijacker*>::iterator it; | ||
| 670 | - for (it = hijackers.begin(); it != hijackers.end(); ++it) { | ||
| 671 | - ISrsHttpMatchHijacker* hijacker = *it; | ||
| 672 | - if ((ret = hijacker->hijack(r, ph)) != ERROR_SUCCESS) { | ||
| 673 | - srs_error("hijacker match failed. ret=%d", ret); | ||
| 674 | - return ret; | ||
| 675 | - } | ||
| 676 | - } | ||
| 677 | - } | ||
| 678 | - | ||
| 679 | - if (*ph == NULL) { | ||
| 680 | - // TODO: FIXME: memory leak. | ||
| 681 | - *ph = new SrsHttpNotFoundHandler(); | ||
| 682 | - } | ||
| 683 | - | ||
| 684 | - return ret; | ||
| 685 | -} | ||
| 686 | - | ||
| 687 | -int SrsHttpServeMux::match(SrsHttpMessage* r, ISrsHttpHandler** ph) | ||
| 688 | -{ | ||
| 689 | - int ret = ERROR_SUCCESS; | ||
| 690 | - | ||
| 691 | - std::string path = r->path(); | ||
| 692 | - | ||
| 693 | - // Host-specific pattern takes precedence over generic ones | ||
| 694 | - if (!vhosts.empty() && vhosts.find(r->host()) != vhosts.end()) { | ||
| 695 | - path = r->host() + path; | ||
| 696 | - } | ||
| 697 | - | ||
| 698 | - int nb_matched = 0; | ||
| 699 | - ISrsHttpHandler* h = NULL; | ||
| 700 | - | ||
| 701 | - std::map<std::string, SrsHttpMuxEntry*>::iterator it; | ||
| 702 | - for (it = entries.begin(); it != entries.end(); ++it) { | ||
| 703 | - std::string pattern = it->first; | ||
| 704 | - SrsHttpMuxEntry* entry = it->second; | ||
| 705 | - | ||
| 706 | - if (!entry->enabled) { | ||
| 707 | - continue; | ||
| 708 | - } | ||
| 709 | - | ||
| 710 | - if (!path_match(pattern, path)) { | ||
| 711 | - continue; | ||
| 712 | - } | ||
| 713 | - | ||
| 714 | - if (!h || (int)pattern.length() > nb_matched) { | ||
| 715 | - nb_matched = (int)pattern.length(); | ||
| 716 | - h = entry->handler; | ||
| 717 | - } | ||
| 718 | - } | ||
| 719 | - | ||
| 720 | - *ph = h; | ||
| 721 | - | ||
| 722 | - return ret; | ||
| 723 | -} | ||
| 724 | - | ||
| 725 | -bool SrsHttpServeMux::path_match(string pattern, string path) | ||
| 726 | -{ | ||
| 727 | - if (pattern.empty()) { | ||
| 728 | - return false; | ||
| 729 | - } | ||
| 730 | - | ||
| 731 | - int n = (int)pattern.length(); | ||
| 732 | - | ||
| 733 | - // not endswith '/', exactly match. | ||
| 734 | - if (pattern.at(n - 1) != '/') { | ||
| 735 | - return pattern == path; | ||
| 736 | - } | ||
| 737 | - | ||
| 738 | - // endswith '/', match any, | ||
| 739 | - // for example, '/api/' match '/api/[N]' | ||
| 740 | - if ((int)path.length() >= n) { | ||
| 741 | - if (memcmp(pattern.data(), path.data(), n) == 0) { | ||
| 742 | - return true; | ||
| 743 | - } | ||
| 744 | - } | ||
| 745 | - | ||
| 746 | - return false; | ||
| 747 | -} | ||
| 748 | - | ||
| 749 | -SrsHttpResponseWriter::SrsHttpResponseWriter(SrsStSocket* io) | ||
| 750 | -{ | ||
| 751 | - skt = io; | ||
| 752 | - hdr = new SrsHttpHeader(); | ||
| 753 | - header_wrote = false; | ||
| 754 | - status = SRS_CONSTS_HTTP_OK; | ||
| 755 | - content_length = -1; | ||
| 756 | - written = 0; | ||
| 757 | - header_sent = false; | ||
| 758 | -} | ||
| 759 | - | ||
| 760 | -SrsHttpResponseWriter::~SrsHttpResponseWriter() | ||
| 761 | -{ | ||
| 762 | - srs_freep(hdr); | ||
| 763 | -} | ||
| 764 | - | ||
| 765 | -int SrsHttpResponseWriter::final_request() | ||
| 766 | -{ | ||
| 767 | - // complete the chunked encoding. | ||
| 768 | - if (content_length == -1) { | ||
| 769 | - std::stringstream ss; | ||
| 770 | - ss << 0 << SRS_HTTP_CRLF << SRS_HTTP_CRLF; | ||
| 771 | - std::string ch = ss.str(); | ||
| 772 | - return skt->write((void*)ch.data(), (int)ch.length(), NULL); | ||
| 773 | - } | ||
| 774 | - | ||
| 775 | - // flush when send with content length | ||
| 776 | - return write(NULL, 0); | ||
| 777 | -} | ||
| 778 | - | ||
| 779 | -SrsHttpHeader* SrsHttpResponseWriter::header() | ||
| 780 | -{ | ||
| 781 | - return hdr; | ||
| 782 | -} | ||
| 783 | - | ||
| 784 | -int SrsHttpResponseWriter::write(char* data, int size) | ||
| 785 | -{ | ||
| 786 | - int ret = ERROR_SUCCESS; | ||
| 787 | - | ||
| 788 | - if (!header_wrote) { | ||
| 789 | - write_header(SRS_CONSTS_HTTP_OK); | ||
| 790 | - } | ||
| 791 | - | ||
| 792 | - written += size; | ||
| 793 | - if (content_length != -1 && written > content_length) { | ||
| 794 | - ret = ERROR_HTTP_CONTENT_LENGTH; | ||
| 795 | - srs_error("http: exceed content length. ret=%d", ret); | ||
| 796 | - return ret; | ||
| 797 | - } | ||
| 798 | - | ||
| 799 | - if ((ret = send_header(data, size)) != ERROR_SUCCESS) { | ||
| 800 | - srs_error("http: send header failed. ret=%d", ret); | ||
| 801 | - return ret; | ||
| 802 | - } | ||
| 803 | - | ||
| 804 | - // ignore NULL content. | ||
| 805 | - if (!data) { | ||
| 806 | - return ret; | ||
| 807 | - } | ||
| 808 | - | ||
| 809 | - // directly send with content length | ||
| 810 | - if (content_length != -1) { | ||
| 811 | - return skt->write((void*)data, size, NULL); | ||
| 812 | - } | ||
| 813 | - | ||
| 814 | - // send in chunked encoding. | ||
| 815 | - std::stringstream ss; | ||
| 816 | - ss << hex << size << SRS_HTTP_CRLF; | ||
| 817 | - std::string ch = ss.str(); | ||
| 818 | - if ((ret = skt->write((void*)ch.data(), (int)ch.length(), NULL)) != ERROR_SUCCESS) { | ||
| 819 | - return ret; | ||
| 820 | - } | ||
| 821 | - if ((ret = skt->write((void*)data, size, NULL)) != ERROR_SUCCESS) { | ||
| 822 | - return ret; | ||
| 823 | - } | ||
| 824 | - if ((ret = skt->write((void*)SRS_HTTP_CRLF, 2, NULL)) != ERROR_SUCCESS) { | ||
| 825 | - return ret; | ||
| 826 | - } | ||
| 827 | - | ||
| 828 | - return ret; | ||
| 829 | -} | ||
| 830 | - | ||
| 831 | -void SrsHttpResponseWriter::write_header(int code) | ||
| 832 | -{ | ||
| 833 | - if (header_wrote) { | ||
| 834 | - srs_warn("http: multiple write_header calls, code=%d", code); | ||
| 835 | - return; | ||
| 836 | - } | ||
| 837 | - | ||
| 838 | - header_wrote = true; | ||
| 839 | - status = code; | ||
| 840 | - | ||
| 841 | - // parse the content length from header. | ||
| 842 | - content_length = hdr->content_length(); | ||
| 843 | -} | ||
| 844 | - | ||
| 845 | -int SrsHttpResponseWriter::send_header(char* data, int size) | ||
| 846 | -{ | ||
| 847 | - int ret = ERROR_SUCCESS; | ||
| 848 | - | ||
| 849 | - if (header_sent) { | ||
| 850 | - return ret; | ||
| 851 | - } | ||
| 852 | - header_sent = true; | ||
| 853 | - | ||
| 854 | - std::stringstream ss; | ||
| 855 | - | ||
| 856 | - // status_line | ||
| 857 | - ss << "HTTP/1.1 " << status << " " | ||
| 858 | - << srs_generate_http_status_text(status) << SRS_HTTP_CRLF; | ||
| 859 | - | ||
| 860 | - // detect content type | ||
| 861 | - if (srs_go_http_body_allowd(status)) { | ||
| 862 | - if (hdr->content_type().empty()) { | ||
| 863 | - hdr->set_content_type(srs_go_http_detect(data, size)); | ||
| 864 | - } | ||
| 865 | - } | ||
| 866 | - | ||
| 867 | - // set server if not set. | ||
| 868 | - if (hdr->get("Server").empty()) { | ||
| 869 | - hdr->set("Server", RTMP_SIG_SRS_KEY"/"RTMP_SIG_SRS_VERSION); | ||
| 870 | - } | ||
| 871 | - | ||
| 872 | - // chunked encoding | ||
| 873 | - if (content_length == -1) { | ||
| 874 | - hdr->set("Transfer-Encoding", "chunked"); | ||
| 875 | - } | ||
| 876 | - | ||
| 877 | - // keep alive to make vlc happy. | ||
| 878 | - hdr->set("Connection", "Keep-Alive"); | ||
| 879 | - | ||
| 880 | - // write headers | ||
| 881 | - hdr->write(ss); | ||
| 882 | - | ||
| 883 | - // header_eof | ||
| 884 | - ss << SRS_HTTP_CRLF; | ||
| 885 | - | ||
| 886 | - std::string buf = ss.str(); | ||
| 887 | - return skt->write((void*)buf.c_str(), buf.length(), NULL); | ||
| 888 | -} | ||
| 889 | - | ||
| 890 | -SrsHttpResponseReader::SrsHttpResponseReader(SrsHttpMessage* msg, SrsStSocket* io) | ||
| 891 | -{ | ||
| 892 | - skt = io; | ||
| 893 | - owner = msg; | ||
| 894 | - is_eof = false; | ||
| 895 | - nb_total_read = 0; | ||
| 896 | - nb_left_chunk = 0; | ||
| 897 | - buffer = NULL; | ||
| 898 | -} | ||
| 899 | - | ||
| 900 | -SrsHttpResponseReader::~SrsHttpResponseReader() | ||
| 901 | -{ | ||
| 902 | -} | ||
| 903 | - | ||
| 904 | -int SrsHttpResponseReader::initialize(SrsFastBuffer* body) | ||
| 905 | -{ | ||
| 906 | - int ret = ERROR_SUCCESS; | ||
| 907 | - | ||
| 908 | - nb_chunk = 0; | ||
| 909 | - nb_left_chunk = 0; | ||
| 910 | - nb_total_read = 0; | ||
| 911 | - buffer = body; | ||
| 912 | - | ||
| 913 | - return ret; | ||
| 914 | -} | ||
| 915 | - | ||
| 916 | -bool SrsHttpResponseReader::eof() | ||
| 917 | -{ | ||
| 918 | - return is_eof; | ||
| 919 | -} | ||
| 920 | - | ||
| 921 | -int SrsHttpResponseReader::read(char* data, int nb_data, int* nb_read) | ||
| 922 | -{ | ||
| 923 | - int ret = ERROR_SUCCESS; | ||
| 924 | - | ||
| 925 | - if (is_eof) { | ||
| 926 | - ret = ERROR_HTTP_RESPONSE_EOF; | ||
| 927 | - srs_error("http: response EOF. ret=%d", ret); | ||
| 928 | - return ret; | ||
| 929 | - } | ||
| 930 | - | ||
| 931 | - // chunked encoding. | ||
| 932 | - if (owner->is_chunked()) { | ||
| 933 | - return read_chunked(data, nb_data, nb_read); | ||
| 934 | - } | ||
| 935 | - | ||
| 936 | - // read by specified content-length | ||
| 937 | - int max = (int)owner->content_length() - (int)nb_total_read; | ||
| 938 | - if (max <= 0) { | ||
| 939 | - is_eof = true; | ||
| 940 | - return ret; | ||
| 941 | - } | ||
| 942 | - | ||
| 943 | - // change the max to read. | ||
| 944 | - nb_data = srs_min(nb_data, max); | ||
| 945 | - return read_specified(data, nb_data, nb_read); | ||
| 946 | -} | ||
| 947 | - | ||
| 948 | -int SrsHttpResponseReader::read_chunked(char* data, int nb_data, int* nb_read) | ||
| 949 | -{ | ||
| 950 | - int ret = ERROR_SUCCESS; | ||
| 951 | - | ||
| 952 | - // when no bytes left in chunk, | ||
| 953 | - // parse the chunk length first. | ||
| 954 | - if (nb_left_chunk <= 0) { | ||
| 955 | - char* at = NULL; | ||
| 956 | - int length = 0; | ||
| 957 | - while (!at) { | ||
| 958 | - // find the CRLF of chunk header end. | ||
| 959 | - char* start = buffer->bytes(); | ||
| 960 | - char* end = start + buffer->size(); | ||
| 961 | - for (char* p = start; p < end - 1; p++) { | ||
| 962 | - if (p[0] == SRS_HTTP_CR && p[1] == SRS_HTTP_LF) { | ||
| 963 | - // invalid chunk, ignore. | ||
| 964 | - if (p == start) { | ||
| 965 | - ret = ERROR_HTTP_INVALID_CHUNK_HEADER; | ||
| 966 | - srs_error("chunk header start with CRLF. ret=%d", ret); | ||
| 967 | - return ret; | ||
| 968 | - } | ||
| 969 | - length = (int)(p - start + 2); | ||
| 970 | - at = buffer->read_slice(length); | ||
| 971 | - break; | ||
| 972 | - } | ||
| 973 | - } | ||
| 974 | - | ||
| 975 | - // got at, ok. | ||
| 976 | - if (at) { | ||
| 977 | - break; | ||
| 978 | - } | ||
| 979 | - | ||
| 980 | - // when empty, only grow 1bytes, but the buffer will cache more. | ||
| 981 | - if ((ret = buffer->grow(skt, buffer->size() + 1)) != ERROR_SUCCESS) { | ||
| 982 | - if (!srs_is_client_gracefully_close(ret)) { | ||
| 983 | - srs_error("read body from server failed. ret=%d", ret); | ||
| 984 | - } | ||
| 985 | - return ret; | ||
| 986 | - } | ||
| 987 | - } | ||
| 988 | - srs_assert(length >= 3); | ||
| 989 | - | ||
| 990 | - // it's ok to set the pos and pos+1 to NULL. | ||
| 991 | - at[length - 1] = 0; | ||
| 992 | - at[length - 2] = 0; | ||
| 993 | - | ||
| 994 | - // size is the bytes size, excludes the chunk header and end CRLF. | ||
| 995 | - int ilength = (int)::strtol(at, NULL, 16); | ||
| 996 | - if (ilength < 0) { | ||
| 997 | - ret = ERROR_HTTP_INVALID_CHUNK_HEADER; | ||
| 998 | - srs_error("chunk header negative, length=%d. ret=%d", ilength, ret); | ||
| 999 | - return ret; | ||
| 1000 | - } | ||
| 1001 | - | ||
| 1002 | - // all bytes in chunk is left now. | ||
| 1003 | - nb_chunk = nb_left_chunk = ilength; | ||
| 1004 | - } | ||
| 1005 | - | ||
| 1006 | - if (nb_chunk <= 0) { | ||
| 1007 | - // for the last chunk, eof. | ||
| 1008 | - is_eof = true; | ||
| 1009 | - } else { | ||
| 1010 | - // for not the last chunk, there must always exists bytes. | ||
| 1011 | - // left bytes in chunk, read some. | ||
| 1012 | - srs_assert(nb_left_chunk); | ||
| 1013 | - | ||
| 1014 | - int nb_bytes = srs_min(nb_left_chunk, nb_data); | ||
| 1015 | - ret = read_specified(data, nb_bytes, &nb_bytes); | ||
| 1016 | - | ||
| 1017 | - // the nb_bytes used for output already read size of bytes. | ||
| 1018 | - if (nb_read) { | ||
| 1019 | - *nb_read = nb_bytes; | ||
| 1020 | - } | ||
| 1021 | - nb_left_chunk -= nb_bytes; | ||
| 1022 | - srs_info("http: read %d bytes of chunk", nb_bytes); | ||
| 1023 | - | ||
| 1024 | - // error or still left bytes in chunk, ignore and read in future. | ||
| 1025 | - if (nb_left_chunk > 0 || (ret != ERROR_SUCCESS)) { | ||
| 1026 | - return ret; | ||
| 1027 | - } | ||
| 1028 | - srs_info("http: read total chunk %dB", nb_chunk); | ||
| 1029 | - } | ||
| 1030 | - | ||
| 1031 | - // for both the last or not, the CRLF of chunk payload end. | ||
| 1032 | - if ((ret = buffer->grow(skt, 2)) != ERROR_SUCCESS) { | ||
| 1033 | - if (!srs_is_client_gracefully_close(ret)) { | ||
| 1034 | - srs_error("read EOF of chunk from server failed. ret=%d", ret); | ||
| 1035 | - } | ||
| 1036 | - return ret; | ||
| 1037 | - } | ||
| 1038 | - buffer->read_slice(2); | ||
| 1039 | - | ||
| 1040 | - return ret; | ||
| 1041 | -} | ||
| 1042 | - | ||
| 1043 | -int SrsHttpResponseReader::read_specified(char* data, int nb_data, int* nb_read) | ||
| 1044 | -{ | ||
| 1045 | - int ret = ERROR_SUCCESS; | ||
| 1046 | - | ||
| 1047 | - if (buffer->size() <= 0) { | ||
| 1048 | - // when empty, only grow 1bytes, but the buffer will cache more. | ||
| 1049 | - if ((ret = buffer->grow(skt, 1)) != ERROR_SUCCESS) { | ||
| 1050 | - if (!srs_is_client_gracefully_close(ret)) { | ||
| 1051 | - srs_error("read body from server failed. ret=%d", ret); | ||
| 1052 | - } | ||
| 1053 | - return ret; | ||
| 1054 | - } | ||
| 1055 | - } | ||
| 1056 | - | ||
| 1057 | - int nb_bytes = srs_min(nb_data, buffer->size()); | ||
| 1058 | - | ||
| 1059 | - // read data to buffer. | ||
| 1060 | - srs_assert(nb_bytes); | ||
| 1061 | - char* p = buffer->read_slice(nb_bytes); | ||
| 1062 | - memcpy(data, p, nb_bytes); | ||
| 1063 | - if (nb_read) { | ||
| 1064 | - *nb_read = nb_bytes; | ||
| 1065 | - } | ||
| 1066 | - | ||
| 1067 | - // increase the total read to determine whether EOF. | ||
| 1068 | - nb_total_read += nb_bytes; | ||
| 1069 | - | ||
| 1070 | - // for not chunked | ||
| 1071 | - if (!owner->is_chunked()) { | ||
| 1072 | - // when read completed, eof. | ||
| 1073 | - if (nb_total_read >= (int)owner->content_length()) { | ||
| 1074 | - is_eof = true; | ||
| 1075 | - } | ||
| 1076 | - } | ||
| 1077 | - | ||
| 1078 | - return ret; | ||
| 1079 | -} | ||
| 1080 | - | ||
| 1081 | -SrsHttpMessage::SrsHttpMessage(SrsStSocket* io, SrsConnection* c) | ||
| 1082 | -{ | ||
| 1083 | - conn = c; | ||
| 1084 | - chunked = false; | ||
| 1085 | - keep_alive = true; | ||
| 1086 | - _uri = new SrsHttpUri(); | ||
| 1087 | - _body = new SrsHttpResponseReader(this, io); | ||
| 1088 | - _http_ts_send_buffer = new char[SRS_HTTP_TS_SEND_BUFFER_SIZE]; | ||
| 1089 | -} | ||
| 1090 | - | ||
| 1091 | -SrsHttpMessage::~SrsHttpMessage() | ||
| 1092 | -{ | ||
| 1093 | - srs_freep(_body); | ||
| 1094 | - srs_freep(_uri); | ||
| 1095 | - srs_freep(_http_ts_send_buffer); | ||
| 1096 | -} | ||
| 1097 | - | ||
| 1098 | -int SrsHttpMessage::update(string url, http_parser* header, SrsFastBuffer* body, vector<SrsHttpHeaderField>& headers) | ||
| 1099 | -{ | ||
| 1100 | - int ret = ERROR_SUCCESS; | ||
| 1101 | - | ||
| 1102 | - _url = url; | ||
| 1103 | - _header = *header; | ||
| 1104 | - _headers = headers; | ||
| 1105 | - | ||
| 1106 | - // whether chunked. | ||
| 1107 | - std::string transfer_encoding = get_request_header("Transfer-Encoding"); | ||
| 1108 | - chunked = (transfer_encoding == "chunked"); | ||
| 1109 | - | ||
| 1110 | - // whether keep alive. | ||
| 1111 | - keep_alive = http_should_keep_alive(header); | ||
| 1112 | - | ||
| 1113 | - // set the buffer. | ||
| 1114 | - if ((ret = _body->initialize(body)) != ERROR_SUCCESS) { | ||
| 1115 | - return ret; | ||
| 1116 | - } | ||
| 1117 | - | ||
| 1118 | - // parse uri from url. | ||
| 1119 | - std::string host = get_request_header("Host"); | ||
| 1120 | - | ||
| 1121 | - // donot parse the empty host for uri, | ||
| 1122 | - // for example, the response contains no host, | ||
| 1123 | - // ignore it is ok. | ||
| 1124 | - if (host.empty()) { | ||
| 1125 | - return ret; | ||
| 1126 | - } | ||
| 1127 | - | ||
| 1128 | - // parse uri to schema/server:port/path?query | ||
| 1129 | - std::string uri = "http://" + host + _url; | ||
| 1130 | - if ((ret = _uri->initialize(uri)) != ERROR_SUCCESS) { | ||
| 1131 | - return ret; | ||
| 1132 | - } | ||
| 1133 | - | ||
| 1134 | - // must format as key=value&...&keyN=valueN | ||
| 1135 | - std::string q = _uri->get_query(); | ||
| 1136 | - size_t pos = string::npos; | ||
| 1137 | - while (!q.empty()) { | ||
| 1138 | - std::string k = q; | ||
| 1139 | - if ((pos = q.find("=")) != string::npos) { | ||
| 1140 | - k = q.substr(0, pos); | ||
| 1141 | - q = q.substr(pos + 1); | ||
| 1142 | - } else { | ||
| 1143 | - q = ""; | ||
| 1144 | - } | ||
| 1145 | - | ||
| 1146 | - std::string v = q; | ||
| 1147 | - if ((pos = q.find("&")) != string::npos) { | ||
| 1148 | - v = q.substr(0, pos); | ||
| 1149 | - q = q.substr(pos + 1); | ||
| 1150 | - } else { | ||
| 1151 | - q = ""; | ||
| 1152 | - } | ||
| 1153 | - | ||
| 1154 | - _query[k] = v; | ||
| 1155 | - } | ||
| 1156 | - | ||
| 1157 | - // parse ext. | ||
| 1158 | - _ext = _uri->get_path(); | ||
| 1159 | - if ((pos = _ext.rfind(".")) != string::npos) { | ||
| 1160 | - _ext = _ext.substr(pos); | ||
| 1161 | - } else { | ||
| 1162 | - _ext = ""; | ||
| 1163 | - } | ||
| 1164 | - | ||
| 1165 | - return ret; | ||
| 1166 | -} | ||
| 1167 | - | ||
| 1168 | -char* SrsHttpMessage::http_ts_send_buffer() | ||
| 1169 | -{ | ||
| 1170 | - return _http_ts_send_buffer; | ||
| 1171 | -} | ||
| 1172 | - | ||
| 1173 | -SrsConnection* SrsHttpMessage::connection() | ||
| 1174 | -{ | ||
| 1175 | - return conn; | ||
| 1176 | -} | ||
| 1177 | - | ||
| 1178 | -u_int8_t SrsHttpMessage::method() | ||
| 1179 | -{ | ||
| 1180 | - return (u_int8_t)_header.method; | ||
| 1181 | -} | ||
| 1182 | - | ||
| 1183 | -u_int16_t SrsHttpMessage::status_code() | ||
| 1184 | -{ | ||
| 1185 | - return (u_int16_t)_header.status_code; | ||
| 1186 | -} | ||
| 1187 | - | ||
| 1188 | -string SrsHttpMessage::method_str() | ||
| 1189 | -{ | ||
| 1190 | - if (is_http_get()) { | ||
| 1191 | - return "GET"; | ||
| 1192 | - } | ||
| 1193 | - if (is_http_put()) { | ||
| 1194 | - return "PUT"; | ||
| 1195 | - } | ||
| 1196 | - if (is_http_post()) { | ||
| 1197 | - return "POST"; | ||
| 1198 | - } | ||
| 1199 | - if (is_http_delete()) { | ||
| 1200 | - return "DELETE"; | ||
| 1201 | - } | ||
| 1202 | - if (is_http_options()) { | ||
| 1203 | - return "OPTIONS"; | ||
| 1204 | - } | ||
| 1205 | - | ||
| 1206 | - return "OTHER"; | ||
| 1207 | -} | ||
| 1208 | - | ||
| 1209 | -bool SrsHttpMessage::is_http_get() | ||
| 1210 | -{ | ||
| 1211 | - return _header.method == SRS_CONSTS_HTTP_GET; | ||
| 1212 | -} | ||
| 1213 | - | ||
| 1214 | -bool SrsHttpMessage::is_http_put() | ||
| 1215 | -{ | ||
| 1216 | - return _header.method == SRS_CONSTS_HTTP_PUT; | ||
| 1217 | -} | ||
| 1218 | - | ||
| 1219 | -bool SrsHttpMessage::is_http_post() | ||
| 1220 | -{ | ||
| 1221 | - return _header.method == SRS_CONSTS_HTTP_POST; | ||
| 1222 | -} | ||
| 1223 | - | ||
| 1224 | -bool SrsHttpMessage::is_http_delete() | ||
| 1225 | -{ | ||
| 1226 | - return _header.method == SRS_CONSTS_HTTP_DELETE; | ||
| 1227 | -} | ||
| 1228 | - | ||
| 1229 | -bool SrsHttpMessage::is_http_options() | ||
| 1230 | -{ | ||
| 1231 | - return _header.method == SRS_CONSTS_HTTP_OPTIONS; | ||
| 1232 | -} | ||
| 1233 | - | ||
| 1234 | -bool SrsHttpMessage::is_chunked() | ||
| 1235 | -{ | ||
| 1236 | - return chunked; | ||
| 1237 | -} | ||
| 1238 | - | ||
| 1239 | -bool SrsHttpMessage::is_keep_alive() | ||
| 1240 | -{ | ||
| 1241 | - return keep_alive; | ||
| 1242 | -} | ||
| 1243 | - | ||
| 1244 | -string SrsHttpMessage::uri() | ||
| 1245 | -{ | ||
| 1246 | - std::string uri = _uri->get_schema(); | ||
| 1247 | - if (uri.empty()) { | ||
| 1248 | - uri += "http"; | ||
| 1249 | - } | ||
| 1250 | - uri += "://"; | ||
| 1251 | - | ||
| 1252 | - uri += host(); | ||
| 1253 | - uri += path(); | ||
| 1254 | - return uri; | ||
| 1255 | -} | ||
| 1256 | - | ||
| 1257 | -string SrsHttpMessage::url() | ||
| 1258 | -{ | ||
| 1259 | - return _uri->get_url(); | ||
| 1260 | -} | ||
| 1261 | - | ||
| 1262 | -string SrsHttpMessage::host() | ||
| 1263 | -{ | ||
| 1264 | - return _uri->get_host(); | ||
| 1265 | -} | ||
| 1266 | - | ||
| 1267 | -string SrsHttpMessage::path() | ||
| 1268 | -{ | ||
| 1269 | - return _uri->get_path(); | ||
| 1270 | -} | ||
| 1271 | - | ||
| 1272 | -string SrsHttpMessage::ext() | ||
| 1273 | -{ | ||
| 1274 | - return _ext; | ||
| 1275 | -} | ||
| 1276 | - | ||
| 1277 | -int SrsHttpMessage::body_read_all(string& body) | ||
| 1278 | -{ | ||
| 1279 | - int ret = ERROR_SUCCESS; | ||
| 1280 | - | ||
| 1281 | - // cache to read. | ||
| 1282 | - char* buf = new char[SRS_HTTP_READ_CACHE_BYTES]; | ||
| 1283 | - SrsAutoFree(char, buf); | ||
| 1284 | - | ||
| 1285 | - // whatever, read util EOF. | ||
| 1286 | - while (!_body->eof()) { | ||
| 1287 | - int nb_read = 0; | ||
| 1288 | - if ((ret = _body->read(buf, SRS_HTTP_READ_CACHE_BYTES, &nb_read)) != ERROR_SUCCESS) { | ||
| 1289 | - return ret; | ||
| 1290 | - } | ||
| 1291 | - | ||
| 1292 | - if (nb_read > 0) { | ||
| 1293 | - body.append(buf, nb_read); | ||
| 1294 | - } | ||
| 1295 | - } | ||
| 1296 | - | ||
| 1297 | - return ret; | ||
| 1298 | -} | ||
| 1299 | - | ||
| 1300 | -ISrsHttpResponseReader* SrsHttpMessage::body_reader() | ||
| 1301 | -{ | ||
| 1302 | - return _body; | ||
| 1303 | -} | ||
| 1304 | - | ||
| 1305 | -int64_t SrsHttpMessage::content_length() | ||
| 1306 | -{ | ||
| 1307 | - return _header.content_length; | ||
| 1308 | -} | ||
| 1309 | - | ||
| 1310 | -string SrsHttpMessage::query_get(string key) | ||
| 1311 | -{ | ||
| 1312 | - std::string v; | ||
| 1313 | - | ||
| 1314 | - if (_query.find(key) != _query.end()) { | ||
| 1315 | - v = _query[key]; | ||
| 1316 | - } | ||
| 1317 | - | ||
| 1318 | - return v; | ||
| 1319 | -} | ||
| 1320 | - | ||
| 1321 | -int SrsHttpMessage::request_header_count() | ||
| 1322 | -{ | ||
| 1323 | - return (int)_headers.size(); | ||
| 1324 | -} | ||
| 1325 | - | ||
| 1326 | -string SrsHttpMessage::request_header_key_at(int index) | ||
| 1327 | -{ | ||
| 1328 | - srs_assert(index < request_header_count()); | ||
| 1329 | - SrsHttpHeaderField item = _headers[index]; | ||
| 1330 | - return item.first; | ||
| 1331 | -} | ||
| 1332 | - | ||
| 1333 | -string SrsHttpMessage::request_header_value_at(int index) | ||
| 1334 | -{ | ||
| 1335 | - srs_assert(index < request_header_count()); | ||
| 1336 | - SrsHttpHeaderField item = _headers[index]; | ||
| 1337 | - return item.second; | ||
| 1338 | -} | ||
| 1339 | - | ||
| 1340 | -string SrsHttpMessage::get_request_header(string name) | ||
| 1341 | -{ | ||
| 1342 | - std::vector<SrsHttpHeaderField>::iterator it; | ||
| 1343 | - | ||
| 1344 | - for (it = _headers.begin(); it != _headers.end(); ++it) { | ||
| 1345 | - SrsHttpHeaderField& elem = *it; | ||
| 1346 | - std::string key = elem.first; | ||
| 1347 | - std::string value = elem.second; | ||
| 1348 | - if (key == name) { | ||
| 1349 | - return value; | ||
| 1350 | - } | ||
| 1351 | - } | ||
| 1352 | - | ||
| 1353 | - return ""; | ||
| 1354 | -} | ||
| 1355 | - | ||
| 1356 | -SrsRequest* SrsHttpMessage::to_request(string vhost) | ||
| 1357 | -{ | ||
| 1358 | - SrsRequest* req = new SrsRequest(); | ||
| 1359 | - | ||
| 1360 | - req->app = _uri->get_path(); | ||
| 1361 | - size_t pos = string::npos; | ||
| 1362 | - if ((pos = req->app.rfind("/")) != string::npos) { | ||
| 1363 | - req->stream = req->app.substr(pos + 1); | ||
| 1364 | - req->app = req->app.substr(0, pos); | ||
| 1365 | - } | ||
| 1366 | - if ((pos = req->stream.rfind(".")) != string::npos) { | ||
| 1367 | - req->stream = req->stream.substr(0, pos); | ||
| 1368 | - } | ||
| 1369 | - | ||
| 1370 | - req->tcUrl = "rtmp://" + vhost + req->app; | ||
| 1371 | - req->pageUrl = get_request_header("Referer"); | ||
| 1372 | - req->objectEncoding = 0; | ||
| 1373 | - | ||
| 1374 | - srs_discovery_tc_url(req->tcUrl, | ||
| 1375 | - req->schema, req->host, req->vhost, req->app, req->port, | ||
| 1376 | - req->param); | ||
| 1377 | - req->strip(); | ||
| 1378 | - | ||
| 1379 | - return req; | ||
| 1380 | -} | ||
| 1381 | - | ||
| 1382 | -SrsHttpParser::SrsHttpParser() | ||
| 1383 | -{ | ||
| 1384 | - buffer = new SrsFastBuffer(); | ||
| 1385 | -} | ||
| 1386 | - | ||
| 1387 | -SrsHttpParser::~SrsHttpParser() | ||
| 1388 | -{ | ||
| 1389 | - srs_freep(buffer); | ||
| 1390 | -} | ||
| 1391 | - | ||
| 1392 | -int SrsHttpParser::initialize(enum http_parser_type type) | ||
| 1393 | -{ | ||
| 1394 | - int ret = ERROR_SUCCESS; | ||
| 1395 | - | ||
| 1396 | - memset(&settings, 0, sizeof(settings)); | ||
| 1397 | - settings.on_message_begin = on_message_begin; | ||
| 1398 | - settings.on_url = on_url; | ||
| 1399 | - settings.on_header_field = on_header_field; | ||
| 1400 | - settings.on_header_value = on_header_value; | ||
| 1401 | - settings.on_headers_complete = on_headers_complete; | ||
| 1402 | - settings.on_body = on_body; | ||
| 1403 | - settings.on_message_complete = on_message_complete; | ||
| 1404 | - | ||
| 1405 | - http_parser_init(&parser, type); | ||
| 1406 | - // callback object ptr. | ||
| 1407 | - parser.data = (void*)this; | ||
| 1408 | - | ||
| 1409 | - return ret; | ||
| 1410 | -} | ||
| 1411 | - | ||
| 1412 | -int SrsHttpParser::parse_message(SrsStSocket* skt, SrsConnection* conn, SrsHttpMessage** ppmsg) | ||
| 1413 | -{ | ||
| 1414 | - *ppmsg = NULL; | ||
| 1415 | - | ||
| 1416 | - int ret = ERROR_SUCCESS; | ||
| 1417 | - | ||
| 1418 | - // reset request data. | ||
| 1419 | - field_name = ""; | ||
| 1420 | - field_value = ""; | ||
| 1421 | - expect_field_name = true; | ||
| 1422 | - state = SrsHttpParseStateInit; | ||
| 1423 | - header = http_parser(); | ||
| 1424 | - url = ""; | ||
| 1425 | - headers.clear(); | ||
| 1426 | - header_parsed = 0; | ||
| 1427 | - | ||
| 1428 | - // do parse | ||
| 1429 | - if ((ret = parse_message_imp(skt)) != ERROR_SUCCESS) { | ||
| 1430 | - if (!srs_is_client_gracefully_close(ret)) { | ||
| 1431 | - srs_error("parse http msg failed. ret=%d", ret); | ||
| 1432 | - } | ||
| 1433 | - return ret; | ||
| 1434 | - } | ||
| 1435 | - | ||
| 1436 | - // create msg | ||
| 1437 | - SrsHttpMessage* msg = new SrsHttpMessage(skt, conn); | ||
| 1438 | - | ||
| 1439 | - // initalize http msg, parse url. | ||
| 1440 | - if ((ret = msg->update(url, &header, buffer, headers)) != ERROR_SUCCESS) { | ||
| 1441 | - srs_error("initialize http msg failed. ret=%d", ret); | ||
| 1442 | - srs_freep(msg); | ||
| 1443 | - return ret; | ||
| 1444 | - } | ||
| 1445 | - | ||
| 1446 | - // parse ok, return the msg. | ||
| 1447 | - *ppmsg = msg; | ||
| 1448 | - | ||
| 1449 | - return ret; | ||
| 1450 | -} | ||
| 1451 | - | ||
| 1452 | -int SrsHttpParser::parse_message_imp(SrsStSocket* skt) | ||
| 1453 | -{ | ||
| 1454 | - int ret = ERROR_SUCCESS; | ||
| 1455 | - | ||
| 1456 | - while (true) { | ||
| 1457 | - ssize_t nparsed = 0; | ||
| 1458 | - | ||
| 1459 | - // when got entire http header, parse it. | ||
| 1460 | - // @see https://github.com/simple-rtmp-server/srs/issues/400 | ||
| 1461 | - char* start = buffer->bytes(); | ||
| 1462 | - char* end = start + buffer->size(); | ||
| 1463 | - for (char* p = start; p <= end - 4; p++) { | ||
| 1464 | - // SRS_HTTP_CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A | ||
| 1465 | - if (p[0] == SRS_CONSTS_CR && p[1] == SRS_CONSTS_LF && p[2] == SRS_CONSTS_CR && p[3] == SRS_CONSTS_LF) { | ||
| 1466 | - nparsed = http_parser_execute(&parser, &settings, buffer->bytes(), buffer->size()); | ||
| 1467 | - srs_info("buffer=%d, nparsed=%d, header=%d", buffer->size(), (int)nparsed, header_parsed); | ||
| 1468 | - break; | ||
| 1469 | - } | ||
| 1470 | - } | ||
| 1471 | - | ||
| 1472 | - // consume the parsed bytes. | ||
| 1473 | - if (nparsed && header_parsed) { | ||
| 1474 | - buffer->read_slice(header_parsed); | ||
| 1475 | - } | ||
| 1476 | - | ||
| 1477 | - // ok atleast header completed, | ||
| 1478 | - // never wait for body completed, for maybe chunked. | ||
| 1479 | - if (state == SrsHttpParseStateHeaderComplete || state == SrsHttpParseStateMessageComplete) { | ||
| 1480 | - break; | ||
| 1481 | - } | ||
| 1482 | - | ||
| 1483 | - // when nothing parsed, read more to parse. | ||
| 1484 | - if (nparsed == 0) { | ||
| 1485 | - // when requires more, only grow 1bytes, but the buffer will cache more. | ||
| 1486 | - if ((ret = buffer->grow(skt, buffer->size() + 1)) != ERROR_SUCCESS) { | ||
| 1487 | - if (!srs_is_client_gracefully_close(ret)) { | ||
| 1488 | - srs_error("read body from server failed. ret=%d", ret); | ||
| 1489 | - } | ||
| 1490 | - return ret; | ||
| 1491 | - } | ||
| 1492 | - } | ||
| 1493 | - } | ||
| 1494 | - | ||
| 1495 | - // parse last header. | ||
| 1496 | - if (!field_name.empty() && !field_value.empty()) { | ||
| 1497 | - headers.push_back(std::make_pair(field_name, field_value)); | ||
| 1498 | - } | ||
| 1499 | - | ||
| 1500 | - return ret; | ||
| 1501 | -} | ||
| 1502 | - | ||
| 1503 | -int SrsHttpParser::on_message_begin(http_parser* parser) | ||
| 1504 | -{ | ||
| 1505 | - SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
| 1506 | - srs_assert(obj); | ||
| 1507 | - | ||
| 1508 | - obj->state = SrsHttpParseStateStart; | ||
| 1509 | - | ||
| 1510 | - srs_info("***MESSAGE BEGIN***"); | ||
| 1511 | - | ||
| 1512 | - return 0; | ||
| 1513 | -} | ||
| 1514 | - | ||
| 1515 | -int SrsHttpParser::on_headers_complete(http_parser* parser) | ||
| 1516 | -{ | ||
| 1517 | - SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
| 1518 | - srs_assert(obj); | ||
| 1519 | - | ||
| 1520 | - obj->header = *parser; | ||
| 1521 | - // save the parser when header parse completed. | ||
| 1522 | - obj->state = SrsHttpParseStateHeaderComplete; | ||
| 1523 | - obj->header_parsed = (int)parser->nread; | ||
| 1524 | - | ||
| 1525 | - srs_info("***HEADERS COMPLETE***"); | ||
| 1526 | - | ||
| 1527 | - // see http_parser.c:1570, return 1 to skip body. | ||
| 1528 | - return 0; | ||
| 1529 | -} | ||
| 1530 | - | ||
| 1531 | -int SrsHttpParser::on_message_complete(http_parser* parser) | ||
| 1532 | -{ | ||
| 1533 | - SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
| 1534 | - srs_assert(obj); | ||
| 1535 | - | ||
| 1536 | - // save the parser when body parse completed. | ||
| 1537 | - obj->state = SrsHttpParseStateMessageComplete; | ||
| 1538 | - | ||
| 1539 | - srs_info("***MESSAGE COMPLETE***\n"); | ||
| 1540 | - | ||
| 1541 | - return 0; | ||
| 1542 | -} | ||
| 1543 | - | ||
| 1544 | -int SrsHttpParser::on_url(http_parser* parser, const char* at, size_t length) | ||
| 1545 | -{ | ||
| 1546 | - SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
| 1547 | - srs_assert(obj); | ||
| 1548 | - | ||
| 1549 | - if (length > 0) { | ||
| 1550 | - obj->url.append(at, (int)length); | ||
| 1551 | - } | ||
| 1552 | - | ||
| 1553 | - srs_info("Method: %d, Url: %.*s", parser->method, (int)length, at); | ||
| 1554 | - | ||
| 1555 | - return 0; | ||
| 1556 | -} | ||
| 1557 | - | ||
| 1558 | -int SrsHttpParser::on_header_field(http_parser* parser, const char* at, size_t length) | ||
| 1559 | -{ | ||
| 1560 | - SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
| 1561 | - srs_assert(obj); | ||
| 1562 | - | ||
| 1563 | - // field value=>name, reap the field. | ||
| 1564 | - if (!obj->expect_field_name) { | ||
| 1565 | - obj->headers.push_back(std::make_pair(obj->field_name, obj->field_value)); | ||
| 1566 | - | ||
| 1567 | - // reset the field name when parsed. | ||
| 1568 | - obj->field_name = ""; | ||
| 1569 | - obj->field_value = ""; | ||
| 1570 | - } | ||
| 1571 | - obj->expect_field_name = true; | ||
| 1572 | - | ||
| 1573 | - if (length > 0) { | ||
| 1574 | - obj->field_name.append(at, (int)length); | ||
| 1575 | - } | ||
| 1576 | - | ||
| 1577 | - srs_info("Header field(%d bytes): %.*s", (int)length, (int)length, at); | ||
| 1578 | - return 0; | ||
| 1579 | -} | ||
| 1580 | - | ||
| 1581 | -int SrsHttpParser::on_header_value(http_parser* parser, const char* at, size_t length) | ||
| 1582 | -{ | ||
| 1583 | - SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
| 1584 | - srs_assert(obj); | ||
| 1585 | - | ||
| 1586 | - if (length > 0) { | ||
| 1587 | - obj->field_value.append(at, (int)length); | ||
| 1588 | - } | ||
| 1589 | - obj->expect_field_name = false; | ||
| 1590 | - | ||
| 1591 | - srs_info("Header value(%d bytes): %.*s", (int)length, (int)length, at); | ||
| 1592 | - return 0; | ||
| 1593 | -} | ||
| 1594 | - | ||
| 1595 | -int SrsHttpParser::on_body(http_parser* parser, const char* at, size_t length) | ||
| 1596 | -{ | ||
| 1597 | - SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
| 1598 | - srs_assert(obj); | ||
| 1599 | - | ||
| 1600 | - srs_info("Body: %.*s", (int)length, at); | ||
| 1601 | - | ||
| 1602 | - return 0; | ||
| 1603 | -} | ||
| 1604 | - | ||
| 1605 | -SrsHttpUri::SrsHttpUri() | ||
| 1606 | -{ | ||
| 1607 | - port = SRS_DEFAULT_HTTP_PORT; | ||
| 1608 | -} | ||
| 1609 | - | ||
| 1610 | -SrsHttpUri::~SrsHttpUri() | ||
| 1611 | -{ | ||
| 1612 | -} | ||
| 1613 | - | ||
| 1614 | -int SrsHttpUri::initialize(string _url) | ||
| 1615 | -{ | ||
| 1616 | - int ret = ERROR_SUCCESS; | ||
| 1617 | - | ||
| 1618 | - url = _url; | ||
| 1619 | - const char* purl = url.c_str(); | ||
| 1620 | - | ||
| 1621 | - http_parser_url hp_u; | ||
| 1622 | - if((ret = http_parser_parse_url(purl, url.length(), 0, &hp_u)) != 0){ | ||
| 1623 | - int code = ret; | ||
| 1624 | - ret = ERROR_HTTP_PARSE_URI; | ||
| 1625 | - | ||
| 1626 | - srs_error("parse url %s failed, code=%d, ret=%d", purl, code, ret); | ||
| 1627 | - return ret; | ||
| 1628 | - } | ||
| 1629 | - | ||
| 1630 | - std::string field = get_uri_field(url, &hp_u, UF_SCHEMA); | ||
| 1631 | - if(!field.empty()){ | ||
| 1632 | - schema = field; | ||
| 1633 | - } | ||
| 1634 | - | ||
| 1635 | - host = get_uri_field(url, &hp_u, UF_HOST); | ||
| 1636 | - | ||
| 1637 | - field = get_uri_field(url, &hp_u, UF_PORT); | ||
| 1638 | - if(!field.empty()){ | ||
| 1639 | - port = atoi(field.c_str()); | ||
| 1640 | - } | ||
| 1641 | - | ||
| 1642 | - path = get_uri_field(url, &hp_u, UF_PATH); | ||
| 1643 | - srs_info("parse url %s success", purl); | ||
| 1644 | - | ||
| 1645 | - query = get_uri_field(url, &hp_u, UF_QUERY); | ||
| 1646 | - srs_info("parse query %s success", query.c_str()); | ||
| 1647 | - | ||
| 1648 | - return ret; | ||
| 1649 | -} | ||
| 1650 | - | ||
| 1651 | -const char* SrsHttpUri::get_url() | ||
| 1652 | -{ | ||
| 1653 | - return url.data(); | ||
| 1654 | -} | ||
| 1655 | - | ||
| 1656 | -const char* SrsHttpUri::get_schema() | ||
| 1657 | -{ | ||
| 1658 | - return schema.data(); | ||
| 1659 | -} | ||
| 1660 | - | ||
| 1661 | -const char* SrsHttpUri::get_host() | ||
| 1662 | -{ | ||
| 1663 | - return host.data(); | ||
| 1664 | -} | ||
| 1665 | - | ||
| 1666 | -int SrsHttpUri::get_port() | ||
| 1667 | -{ | ||
| 1668 | - return port; | ||
| 1669 | -} | ||
| 1670 | - | ||
| 1671 | -const char* SrsHttpUri::get_path() | ||
| 1672 | -{ | ||
| 1673 | - return path.data(); | ||
| 1674 | -} | ||
| 1675 | - | ||
| 1676 | -const char* SrsHttpUri::get_query() | ||
| 1677 | -{ | ||
| 1678 | - return query.data(); | ||
| 1679 | -} | ||
| 1680 | - | ||
| 1681 | -string SrsHttpUri::get_uri_field(string uri, http_parser_url* hp_u, http_parser_url_fields field) | ||
| 1682 | -{ | ||
| 1683 | - if((hp_u->field_set & (1 << field)) == 0){ | ||
| 1684 | - return ""; | ||
| 1685 | - } | ||
| 1686 | - | ||
| 1687 | - srs_verbose("uri field matched, off=%d, len=%d, value=%.*s", | ||
| 1688 | - hp_u->field_data[field].off, | ||
| 1689 | - hp_u->field_data[field].len, | ||
| 1690 | - hp_u->field_data[field].len, | ||
| 1691 | - uri.c_str() + hp_u->field_data[field].off); | ||
| 1692 | - | ||
| 1693 | - int offset = hp_u->field_data[field].off; | ||
| 1694 | - int len = hp_u->field_data[field].len; | ||
| 1695 | - | ||
| 1696 | - return uri.substr(offset, len); | ||
| 1697 | -} | ||
| 1698 | - | ||
| 1699 | -#endif | ||
| 1700 | - |
| @@ -39,6 +39,7 @@ using namespace std; | @@ -39,6 +39,7 @@ using namespace std; | ||
| 39 | #include <srs_rtmp_sdk.hpp> | 39 | #include <srs_rtmp_sdk.hpp> |
| 40 | #include <srs_app_dvr.hpp> | 40 | #include <srs_app_dvr.hpp> |
| 41 | #include <srs_app_config.hpp> | 41 | #include <srs_app_config.hpp> |
| 42 | +#include <srs_app_http_conn.hpp> | ||
| 42 | 43 | ||
| 43 | SrsGoApiRoot::SrsGoApiRoot() | 44 | SrsGoApiRoot::SrsGoApiRoot() |
| 44 | { | 45 | { |
| @@ -48,7 +49,7 @@ SrsGoApiRoot::~SrsGoApiRoot() | @@ -48,7 +49,7 @@ SrsGoApiRoot::~SrsGoApiRoot() | ||
| 48 | { | 49 | { |
| 49 | } | 50 | } |
| 50 | 51 | ||
| 51 | -int SrsGoApiRoot::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | 52 | +int SrsGoApiRoot::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) |
| 52 | { | 53 | { |
| 53 | std::stringstream ss; | 54 | std::stringstream ss; |
| 54 | 55 | ||
| @@ -59,7 +60,7 @@ int SrsGoApiRoot::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | @@ -59,7 +60,7 @@ int SrsGoApiRoot::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | ||
| 59 | << SRS_JOBJECT_END | 60 | << SRS_JOBJECT_END |
| 60 | << SRS_JOBJECT_END; | 61 | << SRS_JOBJECT_END; |
| 61 | 62 | ||
| 62 | - return srs_go_http_response_json(w, ss.str()); | 63 | + return srs_http_response_json(w, ss.str()); |
| 63 | } | 64 | } |
| 64 | 65 | ||
| 65 | SrsGoApiApi::SrsGoApiApi() | 66 | SrsGoApiApi::SrsGoApiApi() |
| @@ -70,7 +71,7 @@ SrsGoApiApi::~SrsGoApiApi() | @@ -70,7 +71,7 @@ SrsGoApiApi::~SrsGoApiApi() | ||
| 70 | { | 71 | { |
| 71 | } | 72 | } |
| 72 | 73 | ||
| 73 | -int SrsGoApiApi::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | 74 | +int SrsGoApiApi::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) |
| 74 | { | 75 | { |
| 75 | std::stringstream ss; | 76 | std::stringstream ss; |
| 76 | 77 | ||
| @@ -81,7 +82,7 @@ int SrsGoApiApi::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | @@ -81,7 +82,7 @@ int SrsGoApiApi::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | ||
| 81 | << SRS_JOBJECT_END | 82 | << SRS_JOBJECT_END |
| 82 | << SRS_JOBJECT_END; | 83 | << SRS_JOBJECT_END; |
| 83 | 84 | ||
| 84 | - return srs_go_http_response_json(w, ss.str()); | 85 | + return srs_http_response_json(w, ss.str()); |
| 85 | } | 86 | } |
| 86 | 87 | ||
| 87 | SrsGoApiV1::SrsGoApiV1() | 88 | SrsGoApiV1::SrsGoApiV1() |
| @@ -92,7 +93,7 @@ SrsGoApiV1::~SrsGoApiV1() | @@ -92,7 +93,7 @@ SrsGoApiV1::~SrsGoApiV1() | ||
| 92 | { | 93 | { |
| 93 | } | 94 | } |
| 94 | 95 | ||
| 95 | -int SrsGoApiV1::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | 96 | +int SrsGoApiV1::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) |
| 96 | { | 97 | { |
| 97 | std::stringstream ss; | 98 | std::stringstream ss; |
| 98 | 99 | ||
| @@ -112,7 +113,7 @@ int SrsGoApiV1::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | @@ -112,7 +113,7 @@ int SrsGoApiV1::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | ||
| 112 | << SRS_JOBJECT_END | 113 | << SRS_JOBJECT_END |
| 113 | << SRS_JOBJECT_END; | 114 | << SRS_JOBJECT_END; |
| 114 | 115 | ||
| 115 | - return srs_go_http_response_json(w, ss.str()); | 116 | + return srs_http_response_json(w, ss.str()); |
| 116 | } | 117 | } |
| 117 | 118 | ||
| 118 | SrsGoApiVersion::SrsGoApiVersion() | 119 | SrsGoApiVersion::SrsGoApiVersion() |
| @@ -123,7 +124,7 @@ SrsGoApiVersion::~SrsGoApiVersion() | @@ -123,7 +124,7 @@ SrsGoApiVersion::~SrsGoApiVersion() | ||
| 123 | { | 124 | { |
| 124 | } | 125 | } |
| 125 | 126 | ||
| 126 | -int SrsGoApiVersion::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | 127 | +int SrsGoApiVersion::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) |
| 127 | { | 128 | { |
| 128 | std::stringstream ss; | 129 | std::stringstream ss; |
| 129 | 130 | ||
| @@ -137,7 +138,7 @@ int SrsGoApiVersion::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | @@ -137,7 +138,7 @@ int SrsGoApiVersion::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | ||
| 137 | << SRS_JOBJECT_END | 138 | << SRS_JOBJECT_END |
| 138 | << SRS_JOBJECT_END; | 139 | << SRS_JOBJECT_END; |
| 139 | 140 | ||
| 140 | - return srs_go_http_response_json(w, ss.str()); | 141 | + return srs_http_response_json(w, ss.str()); |
| 141 | } | 142 | } |
| 142 | 143 | ||
| 143 | SrsGoApiSummaries::SrsGoApiSummaries() | 144 | SrsGoApiSummaries::SrsGoApiSummaries() |
| @@ -148,11 +149,11 @@ SrsGoApiSummaries::~SrsGoApiSummaries() | @@ -148,11 +149,11 @@ SrsGoApiSummaries::~SrsGoApiSummaries() | ||
| 148 | { | 149 | { |
| 149 | } | 150 | } |
| 150 | 151 | ||
| 151 | -int SrsGoApiSummaries::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | 152 | +int SrsGoApiSummaries::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) |
| 152 | { | 153 | { |
| 153 | std::stringstream ss; | 154 | std::stringstream ss; |
| 154 | srs_api_dump_summaries(ss); | 155 | srs_api_dump_summaries(ss); |
| 155 | - return srs_go_http_response_json(w, ss.str()); | 156 | + return srs_http_response_json(w, ss.str()); |
| 156 | } | 157 | } |
| 157 | 158 | ||
| 158 | SrsGoApiRusages::SrsGoApiRusages() | 159 | SrsGoApiRusages::SrsGoApiRusages() |
| @@ -163,7 +164,7 @@ SrsGoApiRusages::~SrsGoApiRusages() | @@ -163,7 +164,7 @@ SrsGoApiRusages::~SrsGoApiRusages() | ||
| 163 | { | 164 | { |
| 164 | } | 165 | } |
| 165 | 166 | ||
| 166 | -int SrsGoApiRusages::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* req) | 167 | +int SrsGoApiRusages::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* req) |
| 167 | { | 168 | { |
| 168 | std::stringstream ss; | 169 | std::stringstream ss; |
| 169 | 170 | ||
| @@ -193,7 +194,7 @@ int SrsGoApiRusages::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* req) | @@ -193,7 +194,7 @@ int SrsGoApiRusages::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* req) | ||
| 193 | << SRS_JOBJECT_END | 194 | << SRS_JOBJECT_END |
| 194 | << SRS_JOBJECT_END; | 195 | << SRS_JOBJECT_END; |
| 195 | 196 | ||
| 196 | - return srs_go_http_response_json(w, ss.str()); | 197 | + return srs_http_response_json(w, ss.str()); |
| 197 | } | 198 | } |
| 198 | 199 | ||
| 199 | SrsGoApiSelfProcStats::SrsGoApiSelfProcStats() | 200 | SrsGoApiSelfProcStats::SrsGoApiSelfProcStats() |
| @@ -204,7 +205,7 @@ SrsGoApiSelfProcStats::~SrsGoApiSelfProcStats() | @@ -204,7 +205,7 @@ SrsGoApiSelfProcStats::~SrsGoApiSelfProcStats() | ||
| 204 | { | 205 | { |
| 205 | } | 206 | } |
| 206 | 207 | ||
| 207 | -int SrsGoApiSelfProcStats::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | 208 | +int SrsGoApiSelfProcStats::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) |
| 208 | { | 209 | { |
| 209 | std::stringstream ss; | 210 | std::stringstream ss; |
| 210 | 211 | ||
| @@ -263,7 +264,7 @@ int SrsGoApiSelfProcStats::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* | @@ -263,7 +264,7 @@ int SrsGoApiSelfProcStats::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* | ||
| 263 | << SRS_JOBJECT_END | 264 | << SRS_JOBJECT_END |
| 264 | << SRS_JOBJECT_END; | 265 | << SRS_JOBJECT_END; |
| 265 | 266 | ||
| 266 | - return srs_go_http_response_json(w, ss.str()); | 267 | + return srs_http_response_json(w, ss.str()); |
| 267 | } | 268 | } |
| 268 | 269 | ||
| 269 | SrsGoApiSystemProcStats::SrsGoApiSystemProcStats() | 270 | SrsGoApiSystemProcStats::SrsGoApiSystemProcStats() |
| @@ -274,7 +275,7 @@ SrsGoApiSystemProcStats::~SrsGoApiSystemProcStats() | @@ -274,7 +275,7 @@ SrsGoApiSystemProcStats::~SrsGoApiSystemProcStats() | ||
| 274 | { | 275 | { |
| 275 | } | 276 | } |
| 276 | 277 | ||
| 277 | -int SrsGoApiSystemProcStats::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | 278 | +int SrsGoApiSystemProcStats::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) |
| 278 | { | 279 | { |
| 279 | std::stringstream ss; | 280 | std::stringstream ss; |
| 280 | 281 | ||
| @@ -298,7 +299,7 @@ int SrsGoApiSystemProcStats::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessag | @@ -298,7 +299,7 @@ int SrsGoApiSystemProcStats::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessag | ||
| 298 | << SRS_JOBJECT_END | 299 | << SRS_JOBJECT_END |
| 299 | << SRS_JOBJECT_END; | 300 | << SRS_JOBJECT_END; |
| 300 | 301 | ||
| 301 | - return srs_go_http_response_json(w, ss.str()); | 302 | + return srs_http_response_json(w, ss.str()); |
| 302 | } | 303 | } |
| 303 | 304 | ||
| 304 | SrsGoApiMemInfos::SrsGoApiMemInfos() | 305 | SrsGoApiMemInfos::SrsGoApiMemInfos() |
| @@ -309,7 +310,7 @@ SrsGoApiMemInfos::~SrsGoApiMemInfos() | @@ -309,7 +310,7 @@ SrsGoApiMemInfos::~SrsGoApiMemInfos() | ||
| 309 | { | 310 | { |
| 310 | } | 311 | } |
| 311 | 312 | ||
| 312 | -int SrsGoApiMemInfos::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | 313 | +int SrsGoApiMemInfos::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) |
| 313 | { | 314 | { |
| 314 | std::stringstream ss; | 315 | std::stringstream ss; |
| 315 | 316 | ||
| @@ -334,7 +335,7 @@ int SrsGoApiMemInfos::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | @@ -334,7 +335,7 @@ int SrsGoApiMemInfos::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | ||
| 334 | << SRS_JOBJECT_END | 335 | << SRS_JOBJECT_END |
| 335 | << SRS_JOBJECT_END; | 336 | << SRS_JOBJECT_END; |
| 336 | 337 | ||
| 337 | - return srs_go_http_response_json(w, ss.str()); | 338 | + return srs_http_response_json(w, ss.str()); |
| 338 | } | 339 | } |
| 339 | 340 | ||
| 340 | SrsGoApiAuthors::SrsGoApiAuthors() | 341 | SrsGoApiAuthors::SrsGoApiAuthors() |
| @@ -345,7 +346,7 @@ SrsGoApiAuthors::~SrsGoApiAuthors() | @@ -345,7 +346,7 @@ SrsGoApiAuthors::~SrsGoApiAuthors() | ||
| 345 | { | 346 | { |
| 346 | } | 347 | } |
| 347 | 348 | ||
| 348 | -int SrsGoApiAuthors::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | 349 | +int SrsGoApiAuthors::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) |
| 349 | { | 350 | { |
| 350 | std::stringstream ss; | 351 | std::stringstream ss; |
| 351 | 352 | ||
| @@ -359,7 +360,7 @@ int SrsGoApiAuthors::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | @@ -359,7 +360,7 @@ int SrsGoApiAuthors::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | ||
| 359 | << SRS_JOBJECT_END | 360 | << SRS_JOBJECT_END |
| 360 | << SRS_JOBJECT_END; | 361 | << SRS_JOBJECT_END; |
| 361 | 362 | ||
| 362 | - return srs_go_http_response_json(w, ss.str()); | 363 | + return srs_http_response_json(w, ss.str()); |
| 363 | } | 364 | } |
| 364 | 365 | ||
| 365 | SrsGoApiRequests::SrsGoApiRequests() | 366 | SrsGoApiRequests::SrsGoApiRequests() |
| @@ -370,9 +371,9 @@ SrsGoApiRequests::~SrsGoApiRequests() | @@ -370,9 +371,9 @@ SrsGoApiRequests::~SrsGoApiRequests() | ||
| 370 | { | 371 | { |
| 371 | } | 372 | } |
| 372 | 373 | ||
| 373 | -int SrsGoApiRequests::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | 374 | +int SrsGoApiRequests::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) |
| 374 | { | 375 | { |
| 375 | - SrsHttpMessage* req = r; | 376 | + ISrsHttpMessage* req = r; |
| 376 | 377 | ||
| 377 | std::stringstream ss; | 378 | std::stringstream ss; |
| 378 | 379 | ||
| @@ -420,7 +421,7 @@ int SrsGoApiRequests::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | @@ -420,7 +421,7 @@ int SrsGoApiRequests::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | ||
| 420 | << SRS_JOBJECT_END | 421 | << SRS_JOBJECT_END |
| 421 | << SRS_JOBJECT_END; | 422 | << SRS_JOBJECT_END; |
| 422 | 423 | ||
| 423 | - return srs_go_http_response_json(w, ss.str()); | 424 | + return srs_http_response_json(w, ss.str()); |
| 424 | } | 425 | } |
| 425 | 426 | ||
| 426 | SrsGoApiVhosts::SrsGoApiVhosts() | 427 | SrsGoApiVhosts::SrsGoApiVhosts() |
| @@ -431,7 +432,7 @@ SrsGoApiVhosts::~SrsGoApiVhosts() | @@ -431,7 +432,7 @@ SrsGoApiVhosts::~SrsGoApiVhosts() | ||
| 431 | { | 432 | { |
| 432 | } | 433 | } |
| 433 | 434 | ||
| 434 | -int SrsGoApiVhosts::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | 435 | +int SrsGoApiVhosts::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) |
| 435 | { | 436 | { |
| 436 | std::stringstream data; | 437 | std::stringstream data; |
| 437 | SrsStatistic* stat = SrsStatistic::instance(); | 438 | SrsStatistic* stat = SrsStatistic::instance(); |
| @@ -445,7 +446,7 @@ int SrsGoApiVhosts::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | @@ -445,7 +446,7 @@ int SrsGoApiVhosts::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | ||
| 445 | << SRS_JFIELD_ORG("vhosts", data.str()) | 446 | << SRS_JFIELD_ORG("vhosts", data.str()) |
| 446 | << SRS_JOBJECT_END; | 447 | << SRS_JOBJECT_END; |
| 447 | 448 | ||
| 448 | - return srs_go_http_response_json(w, ss.str()); | 449 | + return srs_http_response_json(w, ss.str()); |
| 449 | } | 450 | } |
| 450 | 451 | ||
| 451 | SrsGoApiStreams::SrsGoApiStreams() | 452 | SrsGoApiStreams::SrsGoApiStreams() |
| @@ -456,7 +457,7 @@ SrsGoApiStreams::~SrsGoApiStreams() | @@ -456,7 +457,7 @@ SrsGoApiStreams::~SrsGoApiStreams() | ||
| 456 | { | 457 | { |
| 457 | } | 458 | } |
| 458 | 459 | ||
| 459 | -int SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | 460 | +int SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) |
| 460 | { | 461 | { |
| 461 | std::stringstream data; | 462 | std::stringstream data; |
| 462 | SrsStatistic* stat = SrsStatistic::instance(); | 463 | SrsStatistic* stat = SrsStatistic::instance(); |
| @@ -470,7 +471,7 @@ int SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | @@ -470,7 +471,7 @@ int SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | ||
| 470 | << SRS_JFIELD_ORG("streams", data.str()) | 471 | << SRS_JFIELD_ORG("streams", data.str()) |
| 471 | << SRS_JOBJECT_END; | 472 | << SRS_JOBJECT_END; |
| 472 | 473 | ||
| 473 | - return srs_go_http_response_json(w, ss.str()); | 474 | + return srs_http_response_json(w, ss.str()); |
| 474 | } | 475 | } |
| 475 | 476 | ||
| 476 | SrsHttpApi::SrsHttpApi(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m) | 477 | SrsHttpApi::SrsHttpApi(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m) |
| @@ -529,7 +530,7 @@ int SrsHttpApi::do_cycle() | @@ -529,7 +530,7 @@ int SrsHttpApi::do_cycle() | ||
| 529 | 530 | ||
| 530 | // process http messages. | 531 | // process http messages. |
| 531 | for (;;) { | 532 | for (;;) { |
| 532 | - SrsHttpMessage* req = NULL; | 533 | + ISrsHttpMessage* req = NULL; |
| 533 | 534 | ||
| 534 | // get a http message | 535 | // get a http message |
| 535 | if ((ret = parser->parse_message(&skt, this, &req)) != ERROR_SUCCESS) { | 536 | if ((ret = parser->parse_message(&skt, this, &req)) != ERROR_SUCCESS) { |
| @@ -540,7 +541,7 @@ int SrsHttpApi::do_cycle() | @@ -540,7 +541,7 @@ int SrsHttpApi::do_cycle() | ||
| 540 | srs_assert(req); | 541 | srs_assert(req); |
| 541 | 542 | ||
| 542 | // always free it in this scope. | 543 | // always free it in this scope. |
| 543 | - SrsAutoFree(SrsHttpMessage, req); | 544 | + SrsAutoFree(ISrsHttpMessage, req); |
| 544 | 545 | ||
| 545 | // TODO: FIXME: use the post body. | 546 | // TODO: FIXME: use the post body. |
| 546 | std::string res; | 547 | std::string res; |
| @@ -566,7 +567,7 @@ int SrsHttpApi::do_cycle() | @@ -566,7 +567,7 @@ int SrsHttpApi::do_cycle() | ||
| 566 | return ret; | 567 | return ret; |
| 567 | } | 568 | } |
| 568 | 569 | ||
| 569 | -int SrsHttpApi::process_request(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | 570 | +int SrsHttpApi::process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) |
| 570 | { | 571 | { |
| 571 | int ret = ERROR_SUCCESS; | 572 | int ret = ERROR_SUCCESS; |
| 572 | 573 |
| @@ -33,13 +33,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -33,13 +33,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 33 | #ifdef SRS_AUTO_HTTP_API | 33 | #ifdef SRS_AUTO_HTTP_API |
| 34 | 34 | ||
| 35 | class SrsStSocket; | 35 | class SrsStSocket; |
| 36 | -class SrsHttpMessage; | 36 | +class ISrsHttpMessage; |
| 37 | class SrsHttpParser; | 37 | class SrsHttpParser; |
| 38 | class SrsHttpHandler; | 38 | class SrsHttpHandler; |
| 39 | 39 | ||
| 40 | #include <srs_app_st.hpp> | 40 | #include <srs_app_st.hpp> |
| 41 | #include <srs_app_conn.hpp> | 41 | #include <srs_app_conn.hpp> |
| 42 | -#include <srs_app_http.hpp> | 42 | +#include <srs_http_stack.hpp> |
| 43 | 43 | ||
| 44 | // for http root. | 44 | // for http root. |
| 45 | class SrsGoApiRoot : public ISrsHttpHandler | 45 | class SrsGoApiRoot : public ISrsHttpHandler |
| @@ -48,7 +48,7 @@ public: | @@ -48,7 +48,7 @@ public: | ||
| 48 | SrsGoApiRoot(); | 48 | SrsGoApiRoot(); |
| 49 | virtual ~SrsGoApiRoot(); | 49 | virtual ~SrsGoApiRoot(); |
| 50 | public: | 50 | public: |
| 51 | - virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r); | 51 | + virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); |
| 52 | }; | 52 | }; |
| 53 | 53 | ||
| 54 | class SrsGoApiApi : public ISrsHttpHandler | 54 | class SrsGoApiApi : public ISrsHttpHandler |
| @@ -57,7 +57,7 @@ public: | @@ -57,7 +57,7 @@ public: | ||
| 57 | SrsGoApiApi(); | 57 | SrsGoApiApi(); |
| 58 | virtual ~SrsGoApiApi(); | 58 | virtual ~SrsGoApiApi(); |
| 59 | public: | 59 | public: |
| 60 | - virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r); | 60 | + virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); |
| 61 | }; | 61 | }; |
| 62 | 62 | ||
| 63 | class SrsGoApiV1 : public ISrsHttpHandler | 63 | class SrsGoApiV1 : public ISrsHttpHandler |
| @@ -66,7 +66,7 @@ public: | @@ -66,7 +66,7 @@ public: | ||
| 66 | SrsGoApiV1(); | 66 | SrsGoApiV1(); |
| 67 | virtual ~SrsGoApiV1(); | 67 | virtual ~SrsGoApiV1(); |
| 68 | public: | 68 | public: |
| 69 | - virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r); | 69 | + virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); |
| 70 | }; | 70 | }; |
| 71 | 71 | ||
| 72 | class SrsGoApiVersion : public ISrsHttpHandler | 72 | class SrsGoApiVersion : public ISrsHttpHandler |
| @@ -75,7 +75,7 @@ public: | @@ -75,7 +75,7 @@ public: | ||
| 75 | SrsGoApiVersion(); | 75 | SrsGoApiVersion(); |
| 76 | virtual ~SrsGoApiVersion(); | 76 | virtual ~SrsGoApiVersion(); |
| 77 | public: | 77 | public: |
| 78 | - virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r); | 78 | + virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); |
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | class SrsGoApiSummaries : public ISrsHttpHandler | 81 | class SrsGoApiSummaries : public ISrsHttpHandler |
| @@ -84,7 +84,7 @@ public: | @@ -84,7 +84,7 @@ public: | ||
| 84 | SrsGoApiSummaries(); | 84 | SrsGoApiSummaries(); |
| 85 | virtual ~SrsGoApiSummaries(); | 85 | virtual ~SrsGoApiSummaries(); |
| 86 | public: | 86 | public: |
| 87 | - virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r); | 87 | + virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); |
| 88 | }; | 88 | }; |
| 89 | 89 | ||
| 90 | class SrsGoApiRusages : public ISrsHttpHandler | 90 | class SrsGoApiRusages : public ISrsHttpHandler |
| @@ -93,7 +93,7 @@ public: | @@ -93,7 +93,7 @@ public: | ||
| 93 | SrsGoApiRusages(); | 93 | SrsGoApiRusages(); |
| 94 | virtual ~SrsGoApiRusages(); | 94 | virtual ~SrsGoApiRusages(); |
| 95 | public: | 95 | public: |
| 96 | - virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r); | 96 | + virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); |
| 97 | }; | 97 | }; |
| 98 | 98 | ||
| 99 | class SrsGoApiSelfProcStats : public ISrsHttpHandler | 99 | class SrsGoApiSelfProcStats : public ISrsHttpHandler |
| @@ -102,7 +102,7 @@ public: | @@ -102,7 +102,7 @@ public: | ||
| 102 | SrsGoApiSelfProcStats(); | 102 | SrsGoApiSelfProcStats(); |
| 103 | virtual ~SrsGoApiSelfProcStats(); | 103 | virtual ~SrsGoApiSelfProcStats(); |
| 104 | public: | 104 | public: |
| 105 | - virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r); | 105 | + virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); |
| 106 | }; | 106 | }; |
| 107 | 107 | ||
| 108 | class SrsGoApiSystemProcStats : public ISrsHttpHandler | 108 | class SrsGoApiSystemProcStats : public ISrsHttpHandler |
| @@ -111,7 +111,7 @@ public: | @@ -111,7 +111,7 @@ public: | ||
| 111 | SrsGoApiSystemProcStats(); | 111 | SrsGoApiSystemProcStats(); |
| 112 | virtual ~SrsGoApiSystemProcStats(); | 112 | virtual ~SrsGoApiSystemProcStats(); |
| 113 | public: | 113 | public: |
| 114 | - virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r); | 114 | + virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); |
| 115 | }; | 115 | }; |
| 116 | 116 | ||
| 117 | class SrsGoApiMemInfos : public ISrsHttpHandler | 117 | class SrsGoApiMemInfos : public ISrsHttpHandler |
| @@ -120,7 +120,7 @@ public: | @@ -120,7 +120,7 @@ public: | ||
| 120 | SrsGoApiMemInfos(); | 120 | SrsGoApiMemInfos(); |
| 121 | virtual ~SrsGoApiMemInfos(); | 121 | virtual ~SrsGoApiMemInfos(); |
| 122 | public: | 122 | public: |
| 123 | - virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r); | 123 | + virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); |
| 124 | }; | 124 | }; |
| 125 | 125 | ||
| 126 | class SrsGoApiAuthors : public ISrsHttpHandler | 126 | class SrsGoApiAuthors : public ISrsHttpHandler |
| @@ -129,7 +129,7 @@ public: | @@ -129,7 +129,7 @@ public: | ||
| 129 | SrsGoApiAuthors(); | 129 | SrsGoApiAuthors(); |
| 130 | virtual ~SrsGoApiAuthors(); | 130 | virtual ~SrsGoApiAuthors(); |
| 131 | public: | 131 | public: |
| 132 | - virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r); | 132 | + virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); |
| 133 | }; | 133 | }; |
| 134 | 134 | ||
| 135 | class SrsGoApiRequests : public ISrsHttpHandler | 135 | class SrsGoApiRequests : public ISrsHttpHandler |
| @@ -138,7 +138,7 @@ public: | @@ -138,7 +138,7 @@ public: | ||
| 138 | SrsGoApiRequests(); | 138 | SrsGoApiRequests(); |
| 139 | virtual ~SrsGoApiRequests(); | 139 | virtual ~SrsGoApiRequests(); |
| 140 | public: | 140 | public: |
| 141 | - virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r); | 141 | + virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); |
| 142 | }; | 142 | }; |
| 143 | 143 | ||
| 144 | class SrsGoApiVhosts : public ISrsHttpHandler | 144 | class SrsGoApiVhosts : public ISrsHttpHandler |
| @@ -147,7 +147,7 @@ public: | @@ -147,7 +147,7 @@ public: | ||
| 147 | SrsGoApiVhosts(); | 147 | SrsGoApiVhosts(); |
| 148 | virtual ~SrsGoApiVhosts(); | 148 | virtual ~SrsGoApiVhosts(); |
| 149 | public: | 149 | public: |
| 150 | - virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r); | 150 | + virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); |
| 151 | }; | 151 | }; |
| 152 | 152 | ||
| 153 | class SrsGoApiStreams : public ISrsHttpHandler | 153 | class SrsGoApiStreams : public ISrsHttpHandler |
| @@ -156,7 +156,7 @@ public: | @@ -156,7 +156,7 @@ public: | ||
| 156 | SrsGoApiStreams(); | 156 | SrsGoApiStreams(); |
| 157 | virtual ~SrsGoApiStreams(); | 157 | virtual ~SrsGoApiStreams(); |
| 158 | public: | 158 | public: |
| 159 | - virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r); | 159 | + virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); |
| 160 | }; | 160 | }; |
| 161 | 161 | ||
| 162 | class SrsHttpApi : public SrsConnection | 162 | class SrsHttpApi : public SrsConnection |
| @@ -177,7 +177,7 @@ public: | @@ -177,7 +177,7 @@ public: | ||
| 177 | protected: | 177 | protected: |
| 178 | virtual int do_cycle(); | 178 | virtual int do_cycle(); |
| 179 | private: | 179 | private: |
| 180 | - virtual int process_request(ISrsHttpResponseWriter* w, SrsHttpMessage* r); | 180 | + virtual int process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); |
| 181 | }; | 181 | }; |
| 182 | 182 | ||
| 183 | #endif | 183 | #endif |
| @@ -29,13 +29,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -29,13 +29,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 29 | 29 | ||
| 30 | using namespace std; | 30 | using namespace std; |
| 31 | 31 | ||
| 32 | -#include <srs_app_http.hpp> | ||
| 33 | #include <srs_kernel_error.hpp> | 32 | #include <srs_kernel_error.hpp> |
| 34 | #include <srs_kernel_log.hpp> | 33 | #include <srs_kernel_log.hpp> |
| 35 | #include <srs_app_st_socket.hpp> | 34 | #include <srs_app_st_socket.hpp> |
| 36 | #include <srs_kernel_utility.hpp> | 35 | #include <srs_kernel_utility.hpp> |
| 37 | #include <srs_app_utility.hpp> | 36 | #include <srs_app_utility.hpp> |
| 38 | #include <srs_core_autofree.hpp> | 37 | #include <srs_core_autofree.hpp> |
| 38 | +#include <srs_app_http_conn.hpp> | ||
| 39 | 39 | ||
| 40 | SrsHttpClient::SrsHttpClient() | 40 | SrsHttpClient::SrsHttpClient() |
| 41 | { | 41 | { |
| @@ -71,7 +71,7 @@ int SrsHttpClient::initialize(string h, int p, int64_t t_us) | @@ -71,7 +71,7 @@ int SrsHttpClient::initialize(string h, int p, int64_t t_us) | ||
| 71 | return ret; | 71 | return ret; |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | -int SrsHttpClient::post(string path, string req, SrsHttpMessage** ppmsg) | 74 | +int SrsHttpClient::post(string path, string req, ISrsHttpMessage** ppmsg) |
| 75 | { | 75 | { |
| 76 | *ppmsg = NULL; | 76 | *ppmsg = NULL; |
| 77 | 77 | ||
| @@ -104,7 +104,7 @@ int SrsHttpClient::post(string path, string req, SrsHttpMessage** ppmsg) | @@ -104,7 +104,7 @@ int SrsHttpClient::post(string path, string req, SrsHttpMessage** ppmsg) | ||
| 104 | return ret; | 104 | return ret; |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | - SrsHttpMessage* msg = NULL; | 107 | + ISrsHttpMessage* msg = NULL; |
| 108 | if ((ret = parser->parse_message(skt, NULL, &msg)) != ERROR_SUCCESS) { | 108 | if ((ret = parser->parse_message(skt, NULL, &msg)) != ERROR_SUCCESS) { |
| 109 | srs_error("parse http post response failed. ret=%d", ret); | 109 | srs_error("parse http post response failed. ret=%d", ret); |
| 110 | return ret; | 110 | return ret; |
| @@ -117,7 +117,7 @@ int SrsHttpClient::post(string path, string req, SrsHttpMessage** ppmsg) | @@ -117,7 +117,7 @@ int SrsHttpClient::post(string path, string req, SrsHttpMessage** ppmsg) | ||
| 117 | return ret; | 117 | return ret; |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | -int SrsHttpClient::get(string path, std::string req, SrsHttpMessage** ppmsg) | 120 | +int SrsHttpClient::get(string path, std::string req, ISrsHttpMessage** ppmsg) |
| 121 | { | 121 | { |
| 122 | *ppmsg = NULL; | 122 | *ppmsg = NULL; |
| 123 | 123 | ||
| @@ -150,7 +150,7 @@ int SrsHttpClient::get(string path, std::string req, SrsHttpMessage** ppmsg) | @@ -150,7 +150,7 @@ int SrsHttpClient::get(string path, std::string req, SrsHttpMessage** ppmsg) | ||
| 150 | return ret; | 150 | return ret; |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | - SrsHttpMessage* msg = NULL; | 153 | + ISrsHttpMessage* msg = NULL; |
| 154 | if ((ret = parser->parse_message(skt, NULL, &msg)) != ERROR_SUCCESS) { | 154 | if ((ret = parser->parse_message(skt, NULL, &msg)) != ERROR_SUCCESS) { |
| 155 | srs_error("parse http post response failed. ret=%d", ret); | 155 | srs_error("parse http post response failed. ret=%d", ret); |
| 156 | return ret; | 156 | return ret; |
| @@ -37,7 +37,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -37,7 +37,7 @@ 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; | 40 | +class ISrsHttpMessage; |
| 41 | class SrsStSocket; | 41 | class SrsStSocket; |
| 42 | 42 | ||
| 43 | // the default timeout for http client. | 43 | // the default timeout for http client. |
| @@ -73,14 +73,14 @@ public: | @@ -73,14 +73,14 @@ public: | ||
| 73 | * @param req the data post to uri. empty string to ignore. | 73 | * @param req the data post to uri. empty string to ignore. |
| 74 | * @param ppmsg output the http message to read the response. | 74 | * @param ppmsg output the http message to read the response. |
| 75 | */ | 75 | */ |
| 76 | - virtual int post(std::string path, std::string req, SrsHttpMessage** ppmsg); | 76 | + virtual int post(std::string path, std::string req, ISrsHttpMessage** ppmsg); |
| 77 | /** | 77 | /** |
| 78 | * to get data from the uri. | 78 | * to get data from the uri. |
| 79 | * @param the path to request on. | 79 | * @param the path to request on. |
| 80 | * @param req the data post to uri. empty string to ignore. | 80 | * @param req the data post to uri. empty string to ignore. |
| 81 | * @param ppmsg output the http message to read the response. | 81 | * @param ppmsg output the http message to read the response. |
| 82 | */ | 82 | */ |
| 83 | - virtual int get(std::string path, std::string req, SrsHttpMessage** ppmsg); | 83 | + virtual int get(std::string path, std::string req, ISrsHttpMessage** ppmsg); |
| 84 | private: | 84 | private: |
| 85 | virtual void disconnect(); | 85 | virtual void disconnect(); |
| 86 | virtual int connect(); | 86 | virtual int connect(); |
| @@ -23,7 +23,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -23,7 +23,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 23 | 23 | ||
| 24 | #include <srs_app_http_conn.hpp> | 24 | #include <srs_app_http_conn.hpp> |
| 25 | 25 | ||
| 26 | -#ifdef SRS_AUTO_HTTP_SERVER | 26 | +#if defined(SRS_AUTO_HTTP_PARSER) || defined(SRS_AUTO_HTTP_SERVER) |
| 27 | 27 | ||
| 28 | #include <sys/types.h> | 28 | #include <sys/types.h> |
| 29 | #include <sys/stat.h> | 29 | #include <sys/stat.h> |
| @@ -33,6 +33,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -33,6 +33,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 33 | #include <sstream> | 33 | #include <sstream> |
| 34 | using namespace std; | 34 | using namespace std; |
| 35 | 35 | ||
| 36 | +#include <srs_rtmp_buffer.hpp> | ||
| 37 | +#include <srs_rtmp_utility.hpp> | ||
| 36 | #include <srs_kernel_log.hpp> | 38 | #include <srs_kernel_log.hpp> |
| 37 | #include <srs_kernel_error.hpp> | 39 | #include <srs_kernel_error.hpp> |
| 38 | #include <srs_app_st_socket.hpp> | 40 | #include <srs_app_st_socket.hpp> |
| @@ -51,6 +53,959 @@ using namespace std; | @@ -51,6 +53,959 @@ using namespace std; | ||
| 51 | #include <srs_app_source.hpp> | 53 | #include <srs_app_source.hpp> |
| 52 | #include <srs_app_server.hpp> | 54 | #include <srs_app_server.hpp> |
| 53 | 55 | ||
| 56 | +#endif | ||
| 57 | + | ||
| 58 | +#ifdef SRS_AUTO_HTTP_PARSER | ||
| 59 | + | ||
| 60 | +SrsHttpResponseWriter::SrsHttpResponseWriter(SrsStSocket* io) | ||
| 61 | +{ | ||
| 62 | + skt = io; | ||
| 63 | + hdr = new SrsHttpHeader(); | ||
| 64 | + header_wrote = false; | ||
| 65 | + status = SRS_CONSTS_HTTP_OK; | ||
| 66 | + content_length = -1; | ||
| 67 | + written = 0; | ||
| 68 | + header_sent = false; | ||
| 69 | +} | ||
| 70 | + | ||
| 71 | +SrsHttpResponseWriter::~SrsHttpResponseWriter() | ||
| 72 | +{ | ||
| 73 | + srs_freep(hdr); | ||
| 74 | +} | ||
| 75 | + | ||
| 76 | +int SrsHttpResponseWriter::final_request() | ||
| 77 | +{ | ||
| 78 | + // complete the chunked encoding. | ||
| 79 | + if (content_length == -1) { | ||
| 80 | + std::stringstream ss; | ||
| 81 | + ss << 0 << SRS_HTTP_CRLF << SRS_HTTP_CRLF; | ||
| 82 | + std::string ch = ss.str(); | ||
| 83 | + return skt->write((void*)ch.data(), (int)ch.length(), NULL); | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + // flush when send with content length | ||
| 87 | + return write(NULL, 0); | ||
| 88 | +} | ||
| 89 | + | ||
| 90 | +SrsHttpHeader* SrsHttpResponseWriter::header() | ||
| 91 | +{ | ||
| 92 | + return hdr; | ||
| 93 | +} | ||
| 94 | + | ||
| 95 | +int SrsHttpResponseWriter::write(char* data, int size) | ||
| 96 | +{ | ||
| 97 | + int ret = ERROR_SUCCESS; | ||
| 98 | + | ||
| 99 | + if (!header_wrote) { | ||
| 100 | + write_header(SRS_CONSTS_HTTP_OK); | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + written += size; | ||
| 104 | + if (content_length != -1 && written > content_length) { | ||
| 105 | + ret = ERROR_HTTP_CONTENT_LENGTH; | ||
| 106 | + srs_error("http: exceed content length. ret=%d", ret); | ||
| 107 | + return ret; | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + if ((ret = send_header(data, size)) != ERROR_SUCCESS) { | ||
| 111 | + srs_error("http: send header failed. ret=%d", ret); | ||
| 112 | + return ret; | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | + // ignore NULL content. | ||
| 116 | + if (!data) { | ||
| 117 | + return ret; | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + // directly send with content length | ||
| 121 | + if (content_length != -1) { | ||
| 122 | + return skt->write((void*)data, size, NULL); | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + // send in chunked encoding. | ||
| 126 | + std::stringstream ss; | ||
| 127 | + ss << hex << size << SRS_HTTP_CRLF; | ||
| 128 | + std::string ch = ss.str(); | ||
| 129 | + if ((ret = skt->write((void*)ch.data(), (int)ch.length(), NULL)) != ERROR_SUCCESS) { | ||
| 130 | + return ret; | ||
| 131 | + } | ||
| 132 | + if ((ret = skt->write((void*)data, size, NULL)) != ERROR_SUCCESS) { | ||
| 133 | + return ret; | ||
| 134 | + } | ||
| 135 | + if ((ret = skt->write((void*)SRS_HTTP_CRLF, 2, NULL)) != ERROR_SUCCESS) { | ||
| 136 | + return ret; | ||
| 137 | + } | ||
| 138 | + | ||
| 139 | + return ret; | ||
| 140 | +} | ||
| 141 | + | ||
| 142 | +void SrsHttpResponseWriter::write_header(int code) | ||
| 143 | +{ | ||
| 144 | + if (header_wrote) { | ||
| 145 | + srs_warn("http: multiple write_header calls, code=%d", code); | ||
| 146 | + return; | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + header_wrote = true; | ||
| 150 | + status = code; | ||
| 151 | + | ||
| 152 | + // parse the content length from header. | ||
| 153 | + content_length = hdr->content_length(); | ||
| 154 | +} | ||
| 155 | + | ||
| 156 | +int SrsHttpResponseWriter::send_header(char* data, int size) | ||
| 157 | +{ | ||
| 158 | + int ret = ERROR_SUCCESS; | ||
| 159 | + | ||
| 160 | + if (header_sent) { | ||
| 161 | + return ret; | ||
| 162 | + } | ||
| 163 | + header_sent = true; | ||
| 164 | + | ||
| 165 | + std::stringstream ss; | ||
| 166 | + | ||
| 167 | + // status_line | ||
| 168 | + ss << "HTTP/1.1 " << status << " " | ||
| 169 | + << srs_generate_http_status_text(status) << SRS_HTTP_CRLF; | ||
| 170 | + | ||
| 171 | + // detect content type | ||
| 172 | + if (srs_go_http_body_allowd(status)) { | ||
| 173 | + if (hdr->content_type().empty()) { | ||
| 174 | + hdr->set_content_type(srs_go_http_detect(data, size)); | ||
| 175 | + } | ||
| 176 | + } | ||
| 177 | + | ||
| 178 | + // set server if not set. | ||
| 179 | + if (hdr->get("Server").empty()) { | ||
| 180 | + hdr->set("Server", RTMP_SIG_SRS_KEY"/"RTMP_SIG_SRS_VERSION); | ||
| 181 | + } | ||
| 182 | + | ||
| 183 | + // chunked encoding | ||
| 184 | + if (content_length == -1) { | ||
| 185 | + hdr->set("Transfer-Encoding", "chunked"); | ||
| 186 | + } | ||
| 187 | + | ||
| 188 | + // keep alive to make vlc happy. | ||
| 189 | + hdr->set("Connection", "Keep-Alive"); | ||
| 190 | + | ||
| 191 | + // write headers | ||
| 192 | + hdr->write(ss); | ||
| 193 | + | ||
| 194 | + // header_eof | ||
| 195 | + ss << SRS_HTTP_CRLF; | ||
| 196 | + | ||
| 197 | + std::string buf = ss.str(); | ||
| 198 | + return skt->write((void*)buf.c_str(), buf.length(), NULL); | ||
| 199 | +} | ||
| 200 | + | ||
| 201 | +SrsHttpResponseReader::SrsHttpResponseReader(SrsHttpMessage* msg, SrsStSocket* io) | ||
| 202 | +{ | ||
| 203 | + skt = io; | ||
| 204 | + owner = msg; | ||
| 205 | + is_eof = false; | ||
| 206 | + nb_total_read = 0; | ||
| 207 | + nb_left_chunk = 0; | ||
| 208 | + buffer = NULL; | ||
| 209 | +} | ||
| 210 | + | ||
| 211 | +SrsHttpResponseReader::~SrsHttpResponseReader() | ||
| 212 | +{ | ||
| 213 | +} | ||
| 214 | + | ||
| 215 | +int SrsHttpResponseReader::initialize(SrsFastBuffer* body) | ||
| 216 | +{ | ||
| 217 | + int ret = ERROR_SUCCESS; | ||
| 218 | + | ||
| 219 | + nb_chunk = 0; | ||
| 220 | + nb_left_chunk = 0; | ||
| 221 | + nb_total_read = 0; | ||
| 222 | + buffer = body; | ||
| 223 | + | ||
| 224 | + return ret; | ||
| 225 | +} | ||
| 226 | + | ||
| 227 | +bool SrsHttpResponseReader::eof() | ||
| 228 | +{ | ||
| 229 | + return is_eof; | ||
| 230 | +} | ||
| 231 | + | ||
| 232 | +int SrsHttpResponseReader::read(char* data, int nb_data, int* nb_read) | ||
| 233 | +{ | ||
| 234 | + int ret = ERROR_SUCCESS; | ||
| 235 | + | ||
| 236 | + if (is_eof) { | ||
| 237 | + ret = ERROR_HTTP_RESPONSE_EOF; | ||
| 238 | + srs_error("http: response EOF. ret=%d", ret); | ||
| 239 | + return ret; | ||
| 240 | + } | ||
| 241 | + | ||
| 242 | + // chunked encoding. | ||
| 243 | + if (owner->is_chunked()) { | ||
| 244 | + return read_chunked(data, nb_data, nb_read); | ||
| 245 | + } | ||
| 246 | + | ||
| 247 | + // read by specified content-length | ||
| 248 | + int max = (int)owner->content_length() - (int)nb_total_read; | ||
| 249 | + if (max <= 0) { | ||
| 250 | + is_eof = true; | ||
| 251 | + return ret; | ||
| 252 | + } | ||
| 253 | + | ||
| 254 | + // change the max to read. | ||
| 255 | + nb_data = srs_min(nb_data, max); | ||
| 256 | + return read_specified(data, nb_data, nb_read); | ||
| 257 | +} | ||
| 258 | + | ||
| 259 | +int SrsHttpResponseReader::read_chunked(char* data, int nb_data, int* nb_read) | ||
| 260 | +{ | ||
| 261 | + int ret = ERROR_SUCCESS; | ||
| 262 | + | ||
| 263 | + // when no bytes left in chunk, | ||
| 264 | + // parse the chunk length first. | ||
| 265 | + if (nb_left_chunk <= 0) { | ||
| 266 | + char* at = NULL; | ||
| 267 | + int length = 0; | ||
| 268 | + while (!at) { | ||
| 269 | + // find the CRLF of chunk header end. | ||
| 270 | + char* start = buffer->bytes(); | ||
| 271 | + char* end = start + buffer->size(); | ||
| 272 | + for (char* p = start; p < end - 1; p++) { | ||
| 273 | + if (p[0] == SRS_HTTP_CR && p[1] == SRS_HTTP_LF) { | ||
| 274 | + // invalid chunk, ignore. | ||
| 275 | + if (p == start) { | ||
| 276 | + ret = ERROR_HTTP_INVALID_CHUNK_HEADER; | ||
| 277 | + srs_error("chunk header start with CRLF. ret=%d", ret); | ||
| 278 | + return ret; | ||
| 279 | + } | ||
| 280 | + length = (int)(p - start + 2); | ||
| 281 | + at = buffer->read_slice(length); | ||
| 282 | + break; | ||
| 283 | + } | ||
| 284 | + } | ||
| 285 | + | ||
| 286 | + // got at, ok. | ||
| 287 | + if (at) { | ||
| 288 | + break; | ||
| 289 | + } | ||
| 290 | + | ||
| 291 | + // when empty, only grow 1bytes, but the buffer will cache more. | ||
| 292 | + if ((ret = buffer->grow(skt, buffer->size() + 1)) != ERROR_SUCCESS) { | ||
| 293 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 294 | + srs_error("read body from server failed. ret=%d", ret); | ||
| 295 | + } | ||
| 296 | + return ret; | ||
| 297 | + } | ||
| 298 | + } | ||
| 299 | + srs_assert(length >= 3); | ||
| 300 | + | ||
| 301 | + // it's ok to set the pos and pos+1 to NULL. | ||
| 302 | + at[length - 1] = 0; | ||
| 303 | + at[length - 2] = 0; | ||
| 304 | + | ||
| 305 | + // size is the bytes size, excludes the chunk header and end CRLF. | ||
| 306 | + int ilength = (int)::strtol(at, NULL, 16); | ||
| 307 | + if (ilength < 0) { | ||
| 308 | + ret = ERROR_HTTP_INVALID_CHUNK_HEADER; | ||
| 309 | + srs_error("chunk header negative, length=%d. ret=%d", ilength, ret); | ||
| 310 | + return ret; | ||
| 311 | + } | ||
| 312 | + | ||
| 313 | + // all bytes in chunk is left now. | ||
| 314 | + nb_chunk = nb_left_chunk = ilength; | ||
| 315 | + } | ||
| 316 | + | ||
| 317 | + if (nb_chunk <= 0) { | ||
| 318 | + // for the last chunk, eof. | ||
| 319 | + is_eof = true; | ||
| 320 | + } else { | ||
| 321 | + // for not the last chunk, there must always exists bytes. | ||
| 322 | + // left bytes in chunk, read some. | ||
| 323 | + srs_assert(nb_left_chunk); | ||
| 324 | + | ||
| 325 | + int nb_bytes = srs_min(nb_left_chunk, nb_data); | ||
| 326 | + ret = read_specified(data, nb_bytes, &nb_bytes); | ||
| 327 | + | ||
| 328 | + // the nb_bytes used for output already read size of bytes. | ||
| 329 | + if (nb_read) { | ||
| 330 | + *nb_read = nb_bytes; | ||
| 331 | + } | ||
| 332 | + nb_left_chunk -= nb_bytes; | ||
| 333 | + srs_info("http: read %d bytes of chunk", nb_bytes); | ||
| 334 | + | ||
| 335 | + // error or still left bytes in chunk, ignore and read in future. | ||
| 336 | + if (nb_left_chunk > 0 || (ret != ERROR_SUCCESS)) { | ||
| 337 | + return ret; | ||
| 338 | + } | ||
| 339 | + srs_info("http: read total chunk %dB", nb_chunk); | ||
| 340 | + } | ||
| 341 | + | ||
| 342 | + // for both the last or not, the CRLF of chunk payload end. | ||
| 343 | + if ((ret = buffer->grow(skt, 2)) != ERROR_SUCCESS) { | ||
| 344 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 345 | + srs_error("read EOF of chunk from server failed. ret=%d", ret); | ||
| 346 | + } | ||
| 347 | + return ret; | ||
| 348 | + } | ||
| 349 | + buffer->read_slice(2); | ||
| 350 | + | ||
| 351 | + return ret; | ||
| 352 | +} | ||
| 353 | + | ||
| 354 | +int SrsHttpResponseReader::read_specified(char* data, int nb_data, int* nb_read) | ||
| 355 | +{ | ||
| 356 | + int ret = ERROR_SUCCESS; | ||
| 357 | + | ||
| 358 | + if (buffer->size() <= 0) { | ||
| 359 | + // when empty, only grow 1bytes, but the buffer will cache more. | ||
| 360 | + if ((ret = buffer->grow(skt, 1)) != ERROR_SUCCESS) { | ||
| 361 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 362 | + srs_error("read body from server failed. ret=%d", ret); | ||
| 363 | + } | ||
| 364 | + return ret; | ||
| 365 | + } | ||
| 366 | + } | ||
| 367 | + | ||
| 368 | + int nb_bytes = srs_min(nb_data, buffer->size()); | ||
| 369 | + | ||
| 370 | + // read data to buffer. | ||
| 371 | + srs_assert(nb_bytes); | ||
| 372 | + char* p = buffer->read_slice(nb_bytes); | ||
| 373 | + memcpy(data, p, nb_bytes); | ||
| 374 | + if (nb_read) { | ||
| 375 | + *nb_read = nb_bytes; | ||
| 376 | + } | ||
| 377 | + | ||
| 378 | + // increase the total read to determine whether EOF. | ||
| 379 | + nb_total_read += nb_bytes; | ||
| 380 | + | ||
| 381 | + // for not chunked | ||
| 382 | + if (!owner->is_chunked()) { | ||
| 383 | + // when read completed, eof. | ||
| 384 | + if (nb_total_read >= (int)owner->content_length()) { | ||
| 385 | + is_eof = true; | ||
| 386 | + } | ||
| 387 | + } | ||
| 388 | + | ||
| 389 | + return ret; | ||
| 390 | +} | ||
| 391 | + | ||
| 392 | +SrsHttpMessage::SrsHttpMessage(SrsStSocket* io, SrsConnection* c) : ISrsHttpMessage() | ||
| 393 | +{ | ||
| 394 | + conn = c; | ||
| 395 | + chunked = false; | ||
| 396 | + keep_alive = true; | ||
| 397 | + _uri = new SrsHttpUri(); | ||
| 398 | + _body = new SrsHttpResponseReader(this, io); | ||
| 399 | + _http_ts_send_buffer = new char[SRS_HTTP_TS_SEND_BUFFER_SIZE]; | ||
| 400 | +} | ||
| 401 | + | ||
| 402 | +SrsHttpMessage::~SrsHttpMessage() | ||
| 403 | +{ | ||
| 404 | + srs_freep(_body); | ||
| 405 | + srs_freep(_uri); | ||
| 406 | + srs_freep(_http_ts_send_buffer); | ||
| 407 | +} | ||
| 408 | + | ||
| 409 | +int SrsHttpMessage::update(string url, http_parser* header, SrsFastBuffer* body, vector<SrsHttpHeaderField>& headers) | ||
| 410 | +{ | ||
| 411 | + int ret = ERROR_SUCCESS; | ||
| 412 | + | ||
| 413 | + _url = url; | ||
| 414 | + _header = *header; | ||
| 415 | + _headers = headers; | ||
| 416 | + | ||
| 417 | + // whether chunked. | ||
| 418 | + std::string transfer_encoding = get_request_header("Transfer-Encoding"); | ||
| 419 | + chunked = (transfer_encoding == "chunked"); | ||
| 420 | + | ||
| 421 | + // whether keep alive. | ||
| 422 | + keep_alive = http_should_keep_alive(header); | ||
| 423 | + | ||
| 424 | + // set the buffer. | ||
| 425 | + if ((ret = _body->initialize(body)) != ERROR_SUCCESS) { | ||
| 426 | + return ret; | ||
| 427 | + } | ||
| 428 | + | ||
| 429 | + // parse uri from url. | ||
| 430 | + std::string host = get_request_header("Host"); | ||
| 431 | + | ||
| 432 | + // donot parse the empty host for uri, | ||
| 433 | + // for example, the response contains no host, | ||
| 434 | + // ignore it is ok. | ||
| 435 | + if (host.empty()) { | ||
| 436 | + return ret; | ||
| 437 | + } | ||
| 438 | + | ||
| 439 | + // parse uri to schema/server:port/path?query | ||
| 440 | + std::string uri = "http://" + host + _url; | ||
| 441 | + if ((ret = _uri->initialize(uri)) != ERROR_SUCCESS) { | ||
| 442 | + return ret; | ||
| 443 | + } | ||
| 444 | + | ||
| 445 | + // must format as key=value&...&keyN=valueN | ||
| 446 | + std::string q = _uri->get_query(); | ||
| 447 | + size_t pos = string::npos; | ||
| 448 | + while (!q.empty()) { | ||
| 449 | + std::string k = q; | ||
| 450 | + if ((pos = q.find("=")) != string::npos) { | ||
| 451 | + k = q.substr(0, pos); | ||
| 452 | + q = q.substr(pos + 1); | ||
| 453 | + } else { | ||
| 454 | + q = ""; | ||
| 455 | + } | ||
| 456 | + | ||
| 457 | + std::string v = q; | ||
| 458 | + if ((pos = q.find("&")) != string::npos) { | ||
| 459 | + v = q.substr(0, pos); | ||
| 460 | + q = q.substr(pos + 1); | ||
| 461 | + } else { | ||
| 462 | + q = ""; | ||
| 463 | + } | ||
| 464 | + | ||
| 465 | + _query[k] = v; | ||
| 466 | + } | ||
| 467 | + | ||
| 468 | + // parse ext. | ||
| 469 | + _ext = _uri->get_path(); | ||
| 470 | + if ((pos = _ext.rfind(".")) != string::npos) { | ||
| 471 | + _ext = _ext.substr(pos); | ||
| 472 | + } else { | ||
| 473 | + _ext = ""; | ||
| 474 | + } | ||
| 475 | + | ||
| 476 | + return ret; | ||
| 477 | +} | ||
| 478 | + | ||
| 479 | +SrsConnection* SrsHttpMessage::connection() | ||
| 480 | +{ | ||
| 481 | + return conn; | ||
| 482 | +} | ||
| 483 | + | ||
| 484 | +u_int8_t SrsHttpMessage::method() | ||
| 485 | +{ | ||
| 486 | + return (u_int8_t)_header.method; | ||
| 487 | +} | ||
| 488 | + | ||
| 489 | +u_int16_t SrsHttpMessage::status_code() | ||
| 490 | +{ | ||
| 491 | + return (u_int16_t)_header.status_code; | ||
| 492 | +} | ||
| 493 | + | ||
| 494 | +string SrsHttpMessage::method_str() | ||
| 495 | +{ | ||
| 496 | + if (is_http_get()) { | ||
| 497 | + return "GET"; | ||
| 498 | + } | ||
| 499 | + if (is_http_put()) { | ||
| 500 | + return "PUT"; | ||
| 501 | + } | ||
| 502 | + if (is_http_post()) { | ||
| 503 | + return "POST"; | ||
| 504 | + } | ||
| 505 | + if (is_http_delete()) { | ||
| 506 | + return "DELETE"; | ||
| 507 | + } | ||
| 508 | + if (is_http_options()) { | ||
| 509 | + return "OPTIONS"; | ||
| 510 | + } | ||
| 511 | + | ||
| 512 | + return "OTHER"; | ||
| 513 | +} | ||
| 514 | + | ||
| 515 | +bool SrsHttpMessage::is_http_get() | ||
| 516 | +{ | ||
| 517 | + return _header.method == SRS_CONSTS_HTTP_GET; | ||
| 518 | +} | ||
| 519 | + | ||
| 520 | +bool SrsHttpMessage::is_http_put() | ||
| 521 | +{ | ||
| 522 | + return _header.method == SRS_CONSTS_HTTP_PUT; | ||
| 523 | +} | ||
| 524 | + | ||
| 525 | +bool SrsHttpMessage::is_http_post() | ||
| 526 | +{ | ||
| 527 | + return _header.method == SRS_CONSTS_HTTP_POST; | ||
| 528 | +} | ||
| 529 | + | ||
| 530 | +bool SrsHttpMessage::is_http_delete() | ||
| 531 | +{ | ||
| 532 | + return _header.method == SRS_CONSTS_HTTP_DELETE; | ||
| 533 | +} | ||
| 534 | + | ||
| 535 | +bool SrsHttpMessage::is_http_options() | ||
| 536 | +{ | ||
| 537 | + return _header.method == SRS_CONSTS_HTTP_OPTIONS; | ||
| 538 | +} | ||
| 539 | + | ||
| 540 | +bool SrsHttpMessage::is_chunked() | ||
| 541 | +{ | ||
| 542 | + return chunked; | ||
| 543 | +} | ||
| 544 | + | ||
| 545 | +bool SrsHttpMessage::is_keep_alive() | ||
| 546 | +{ | ||
| 547 | + return keep_alive; | ||
| 548 | +} | ||
| 549 | + | ||
| 550 | +string SrsHttpMessage::uri() | ||
| 551 | +{ | ||
| 552 | + std::string uri = _uri->get_schema(); | ||
| 553 | + if (uri.empty()) { | ||
| 554 | + uri += "http"; | ||
| 555 | + } | ||
| 556 | + uri += "://"; | ||
| 557 | + | ||
| 558 | + uri += host(); | ||
| 559 | + uri += path(); | ||
| 560 | + return uri; | ||
| 561 | +} | ||
| 562 | + | ||
| 563 | +string SrsHttpMessage::url() | ||
| 564 | +{ | ||
| 565 | + return _uri->get_url(); | ||
| 566 | +} | ||
| 567 | + | ||
| 568 | +string SrsHttpMessage::host() | ||
| 569 | +{ | ||
| 570 | + return _uri->get_host(); | ||
| 571 | +} | ||
| 572 | + | ||
| 573 | +string SrsHttpMessage::path() | ||
| 574 | +{ | ||
| 575 | + return _uri->get_path(); | ||
| 576 | +} | ||
| 577 | + | ||
| 578 | +string SrsHttpMessage::ext() | ||
| 579 | +{ | ||
| 580 | + return _ext; | ||
| 581 | +} | ||
| 582 | + | ||
| 583 | +int SrsHttpMessage::body_read_all(string& body) | ||
| 584 | +{ | ||
| 585 | + int ret = ERROR_SUCCESS; | ||
| 586 | + | ||
| 587 | + // cache to read. | ||
| 588 | + char* buf = new char[SRS_HTTP_READ_CACHE_BYTES]; | ||
| 589 | + SrsAutoFree(char, buf); | ||
| 590 | + | ||
| 591 | + // whatever, read util EOF. | ||
| 592 | + while (!_body->eof()) { | ||
| 593 | + int nb_read = 0; | ||
| 594 | + if ((ret = _body->read(buf, SRS_HTTP_READ_CACHE_BYTES, &nb_read)) != ERROR_SUCCESS) { | ||
| 595 | + return ret; | ||
| 596 | + } | ||
| 597 | + | ||
| 598 | + if (nb_read > 0) { | ||
| 599 | + body.append(buf, nb_read); | ||
| 600 | + } | ||
| 601 | + } | ||
| 602 | + | ||
| 603 | + return ret; | ||
| 604 | +} | ||
| 605 | + | ||
| 606 | +ISrsHttpResponseReader* SrsHttpMessage::body_reader() | ||
| 607 | +{ | ||
| 608 | + return _body; | ||
| 609 | +} | ||
| 610 | + | ||
| 611 | +int64_t SrsHttpMessage::content_length() | ||
| 612 | +{ | ||
| 613 | + return _header.content_length; | ||
| 614 | +} | ||
| 615 | + | ||
| 616 | +string SrsHttpMessage::query_get(string key) | ||
| 617 | +{ | ||
| 618 | + std::string v; | ||
| 619 | + | ||
| 620 | + if (_query.find(key) != _query.end()) { | ||
| 621 | + v = _query[key]; | ||
| 622 | + } | ||
| 623 | + | ||
| 624 | + return v; | ||
| 625 | +} | ||
| 626 | + | ||
| 627 | +int SrsHttpMessage::request_header_count() | ||
| 628 | +{ | ||
| 629 | + return (int)_headers.size(); | ||
| 630 | +} | ||
| 631 | + | ||
| 632 | +string SrsHttpMessage::request_header_key_at(int index) | ||
| 633 | +{ | ||
| 634 | + srs_assert(index < request_header_count()); | ||
| 635 | + SrsHttpHeaderField item = _headers[index]; | ||
| 636 | + return item.first; | ||
| 637 | +} | ||
| 638 | + | ||
| 639 | +string SrsHttpMessage::request_header_value_at(int index) | ||
| 640 | +{ | ||
| 641 | + srs_assert(index < request_header_count()); | ||
| 642 | + SrsHttpHeaderField item = _headers[index]; | ||
| 643 | + return item.second; | ||
| 644 | +} | ||
| 645 | + | ||
| 646 | +string SrsHttpMessage::get_request_header(string name) | ||
| 647 | +{ | ||
| 648 | + std::vector<SrsHttpHeaderField>::iterator it; | ||
| 649 | + | ||
| 650 | + for (it = _headers.begin(); it != _headers.end(); ++it) { | ||
| 651 | + SrsHttpHeaderField& elem = *it; | ||
| 652 | + std::string key = elem.first; | ||
| 653 | + std::string value = elem.second; | ||
| 654 | + if (key == name) { | ||
| 655 | + return value; | ||
| 656 | + } | ||
| 657 | + } | ||
| 658 | + | ||
| 659 | + return ""; | ||
| 660 | +} | ||
| 661 | + | ||
| 662 | +SrsRequest* SrsHttpMessage::to_request(string vhost) | ||
| 663 | +{ | ||
| 664 | + SrsRequest* req = new SrsRequest(); | ||
| 665 | + | ||
| 666 | + req->app = _uri->get_path(); | ||
| 667 | + size_t pos = string::npos; | ||
| 668 | + if ((pos = req->app.rfind("/")) != string::npos) { | ||
| 669 | + req->stream = req->app.substr(pos + 1); | ||
| 670 | + req->app = req->app.substr(0, pos); | ||
| 671 | + } | ||
| 672 | + if ((pos = req->stream.rfind(".")) != string::npos) { | ||
| 673 | + req->stream = req->stream.substr(0, pos); | ||
| 674 | + } | ||
| 675 | + | ||
| 676 | + req->tcUrl = "rtmp://" + vhost + req->app; | ||
| 677 | + req->pageUrl = get_request_header("Referer"); | ||
| 678 | + req->objectEncoding = 0; | ||
| 679 | + | ||
| 680 | + srs_discovery_tc_url(req->tcUrl, | ||
| 681 | + req->schema, req->host, req->vhost, req->app, req->port, | ||
| 682 | + req->param); | ||
| 683 | + req->strip(); | ||
| 684 | + | ||
| 685 | + return req; | ||
| 686 | +} | ||
| 687 | + | ||
| 688 | +SrsHttpParser::SrsHttpParser() | ||
| 689 | +{ | ||
| 690 | + buffer = new SrsFastBuffer(); | ||
| 691 | +} | ||
| 692 | + | ||
| 693 | +SrsHttpParser::~SrsHttpParser() | ||
| 694 | +{ | ||
| 695 | + srs_freep(buffer); | ||
| 696 | +} | ||
| 697 | + | ||
| 698 | +int SrsHttpParser::initialize(enum http_parser_type type) | ||
| 699 | +{ | ||
| 700 | + int ret = ERROR_SUCCESS; | ||
| 701 | + | ||
| 702 | + memset(&settings, 0, sizeof(settings)); | ||
| 703 | + settings.on_message_begin = on_message_begin; | ||
| 704 | + settings.on_url = on_url; | ||
| 705 | + settings.on_header_field = on_header_field; | ||
| 706 | + settings.on_header_value = on_header_value; | ||
| 707 | + settings.on_headers_complete = on_headers_complete; | ||
| 708 | + settings.on_body = on_body; | ||
| 709 | + settings.on_message_complete = on_message_complete; | ||
| 710 | + | ||
| 711 | + http_parser_init(&parser, type); | ||
| 712 | + // callback object ptr. | ||
| 713 | + parser.data = (void*)this; | ||
| 714 | + | ||
| 715 | + return ret; | ||
| 716 | +} | ||
| 717 | + | ||
| 718 | +int SrsHttpParser::parse_message(SrsStSocket* skt, SrsConnection* conn, ISrsHttpMessage** ppmsg) | ||
| 719 | +{ | ||
| 720 | + *ppmsg = NULL; | ||
| 721 | + | ||
| 722 | + int ret = ERROR_SUCCESS; | ||
| 723 | + | ||
| 724 | + // reset request data. | ||
| 725 | + field_name = ""; | ||
| 726 | + field_value = ""; | ||
| 727 | + expect_field_name = true; | ||
| 728 | + state = SrsHttpParseStateInit; | ||
| 729 | + header = http_parser(); | ||
| 730 | + url = ""; | ||
| 731 | + headers.clear(); | ||
| 732 | + header_parsed = 0; | ||
| 733 | + | ||
| 734 | + // do parse | ||
| 735 | + if ((ret = parse_message_imp(skt)) != ERROR_SUCCESS) { | ||
| 736 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 737 | + srs_error("parse http msg failed. ret=%d", ret); | ||
| 738 | + } | ||
| 739 | + return ret; | ||
| 740 | + } | ||
| 741 | + | ||
| 742 | + // create msg | ||
| 743 | + SrsHttpMessage* msg = new SrsHttpMessage(skt, conn); | ||
| 744 | + | ||
| 745 | + // initalize http msg, parse url. | ||
| 746 | + if ((ret = msg->update(url, &header, buffer, headers)) != ERROR_SUCCESS) { | ||
| 747 | + srs_error("initialize http msg failed. ret=%d", ret); | ||
| 748 | + srs_freep(msg); | ||
| 749 | + return ret; | ||
| 750 | + } | ||
| 751 | + | ||
| 752 | + // parse ok, return the msg. | ||
| 753 | + *ppmsg = msg; | ||
| 754 | + | ||
| 755 | + return ret; | ||
| 756 | +} | ||
| 757 | + | ||
| 758 | +int SrsHttpParser::parse_message_imp(SrsStSocket* skt) | ||
| 759 | +{ | ||
| 760 | + int ret = ERROR_SUCCESS; | ||
| 761 | + | ||
| 762 | + while (true) { | ||
| 763 | + ssize_t nparsed = 0; | ||
| 764 | + | ||
| 765 | + // when got entire http header, parse it. | ||
| 766 | + // @see https://github.com/simple-rtmp-server/srs/issues/400 | ||
| 767 | + char* start = buffer->bytes(); | ||
| 768 | + char* end = start + buffer->size(); | ||
| 769 | + for (char* p = start; p <= end - 4; p++) { | ||
| 770 | + // SRS_HTTP_CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A | ||
| 771 | + if (p[0] == SRS_CONSTS_CR && p[1] == SRS_CONSTS_LF && p[2] == SRS_CONSTS_CR && p[3] == SRS_CONSTS_LF) { | ||
| 772 | + nparsed = http_parser_execute(&parser, &settings, buffer->bytes(), buffer->size()); | ||
| 773 | + srs_info("buffer=%d, nparsed=%d, header=%d", buffer->size(), (int)nparsed, header_parsed); | ||
| 774 | + break; | ||
| 775 | + } | ||
| 776 | + } | ||
| 777 | + | ||
| 778 | + // consume the parsed bytes. | ||
| 779 | + if (nparsed && header_parsed) { | ||
| 780 | + buffer->read_slice(header_parsed); | ||
| 781 | + } | ||
| 782 | + | ||
| 783 | + // ok atleast header completed, | ||
| 784 | + // never wait for body completed, for maybe chunked. | ||
| 785 | + if (state == SrsHttpParseStateHeaderComplete || state == SrsHttpParseStateMessageComplete) { | ||
| 786 | + break; | ||
| 787 | + } | ||
| 788 | + | ||
| 789 | + // when nothing parsed, read more to parse. | ||
| 790 | + if (nparsed == 0) { | ||
| 791 | + // when requires more, only grow 1bytes, but the buffer will cache more. | ||
| 792 | + if ((ret = buffer->grow(skt, buffer->size() + 1)) != ERROR_SUCCESS) { | ||
| 793 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 794 | + srs_error("read body from server failed. ret=%d", ret); | ||
| 795 | + } | ||
| 796 | + return ret; | ||
| 797 | + } | ||
| 798 | + } | ||
| 799 | + } | ||
| 800 | + | ||
| 801 | + // parse last header. | ||
| 802 | + if (!field_name.empty() && !field_value.empty()) { | ||
| 803 | + headers.push_back(std::make_pair(field_name, field_value)); | ||
| 804 | + } | ||
| 805 | + | ||
| 806 | + return ret; | ||
| 807 | +} | ||
| 808 | + | ||
| 809 | +int SrsHttpParser::on_message_begin(http_parser* parser) | ||
| 810 | +{ | ||
| 811 | + SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
| 812 | + srs_assert(obj); | ||
| 813 | + | ||
| 814 | + obj->state = SrsHttpParseStateStart; | ||
| 815 | + | ||
| 816 | + srs_info("***MESSAGE BEGIN***"); | ||
| 817 | + | ||
| 818 | + return 0; | ||
| 819 | +} | ||
| 820 | + | ||
| 821 | +int SrsHttpParser::on_headers_complete(http_parser* parser) | ||
| 822 | +{ | ||
| 823 | + SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
| 824 | + srs_assert(obj); | ||
| 825 | + | ||
| 826 | + obj->header = *parser; | ||
| 827 | + // save the parser when header parse completed. | ||
| 828 | + obj->state = SrsHttpParseStateHeaderComplete; | ||
| 829 | + obj->header_parsed = (int)parser->nread; | ||
| 830 | + | ||
| 831 | + srs_info("***HEADERS COMPLETE***"); | ||
| 832 | + | ||
| 833 | + // see http_parser.c:1570, return 1 to skip body. | ||
| 834 | + return 0; | ||
| 835 | +} | ||
| 836 | + | ||
| 837 | +int SrsHttpParser::on_message_complete(http_parser* parser) | ||
| 838 | +{ | ||
| 839 | + SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
| 840 | + srs_assert(obj); | ||
| 841 | + | ||
| 842 | + // save the parser when body parse completed. | ||
| 843 | + obj->state = SrsHttpParseStateMessageComplete; | ||
| 844 | + | ||
| 845 | + srs_info("***MESSAGE COMPLETE***\n"); | ||
| 846 | + | ||
| 847 | + return 0; | ||
| 848 | +} | ||
| 849 | + | ||
| 850 | +int SrsHttpParser::on_url(http_parser* parser, const char* at, size_t length) | ||
| 851 | +{ | ||
| 852 | + SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
| 853 | + srs_assert(obj); | ||
| 854 | + | ||
| 855 | + if (length > 0) { | ||
| 856 | + obj->url.append(at, (int)length); | ||
| 857 | + } | ||
| 858 | + | ||
| 859 | + srs_info("Method: %d, Url: %.*s", parser->method, (int)length, at); | ||
| 860 | + | ||
| 861 | + return 0; | ||
| 862 | +} | ||
| 863 | + | ||
| 864 | +int SrsHttpParser::on_header_field(http_parser* parser, const char* at, size_t length) | ||
| 865 | +{ | ||
| 866 | + SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
| 867 | + srs_assert(obj); | ||
| 868 | + | ||
| 869 | + // field value=>name, reap the field. | ||
| 870 | + if (!obj->expect_field_name) { | ||
| 871 | + obj->headers.push_back(std::make_pair(obj->field_name, obj->field_value)); | ||
| 872 | + | ||
| 873 | + // reset the field name when parsed. | ||
| 874 | + obj->field_name = ""; | ||
| 875 | + obj->field_value = ""; | ||
| 876 | + } | ||
| 877 | + obj->expect_field_name = true; | ||
| 878 | + | ||
| 879 | + if (length > 0) { | ||
| 880 | + obj->field_name.append(at, (int)length); | ||
| 881 | + } | ||
| 882 | + | ||
| 883 | + srs_info("Header field(%d bytes): %.*s", (int)length, (int)length, at); | ||
| 884 | + return 0; | ||
| 885 | +} | ||
| 886 | + | ||
| 887 | +int SrsHttpParser::on_header_value(http_parser* parser, const char* at, size_t length) | ||
| 888 | +{ | ||
| 889 | + SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
| 890 | + srs_assert(obj); | ||
| 891 | + | ||
| 892 | + if (length > 0) { | ||
| 893 | + obj->field_value.append(at, (int)length); | ||
| 894 | + } | ||
| 895 | + obj->expect_field_name = false; | ||
| 896 | + | ||
| 897 | + srs_info("Header value(%d bytes): %.*s", (int)length, (int)length, at); | ||
| 898 | + return 0; | ||
| 899 | +} | ||
| 900 | + | ||
| 901 | +int SrsHttpParser::on_body(http_parser* parser, const char* at, size_t length) | ||
| 902 | +{ | ||
| 903 | + SrsHttpParser* obj = (SrsHttpParser*)parser->data; | ||
| 904 | + srs_assert(obj); | ||
| 905 | + | ||
| 906 | + srs_info("Body: %.*s", (int)length, at); | ||
| 907 | + | ||
| 908 | + return 0; | ||
| 909 | +} | ||
| 910 | + | ||
| 911 | +SrsHttpUri::SrsHttpUri() | ||
| 912 | +{ | ||
| 913 | + port = SRS_DEFAULT_HTTP_PORT; | ||
| 914 | +} | ||
| 915 | + | ||
| 916 | +SrsHttpUri::~SrsHttpUri() | ||
| 917 | +{ | ||
| 918 | +} | ||
| 919 | + | ||
| 920 | +int SrsHttpUri::initialize(string _url) | ||
| 921 | +{ | ||
| 922 | + int ret = ERROR_SUCCESS; | ||
| 923 | + | ||
| 924 | + url = _url; | ||
| 925 | + const char* purl = url.c_str(); | ||
| 926 | + | ||
| 927 | + http_parser_url hp_u; | ||
| 928 | + if((ret = http_parser_parse_url(purl, url.length(), 0, &hp_u)) != 0){ | ||
| 929 | + int code = ret; | ||
| 930 | + ret = ERROR_HTTP_PARSE_URI; | ||
| 931 | + | ||
| 932 | + srs_error("parse url %s failed, code=%d, ret=%d", purl, code, ret); | ||
| 933 | + return ret; | ||
| 934 | + } | ||
| 935 | + | ||
| 936 | + std::string field = get_uri_field(url, &hp_u, UF_SCHEMA); | ||
| 937 | + if(!field.empty()){ | ||
| 938 | + schema = field; | ||
| 939 | + } | ||
| 940 | + | ||
| 941 | + host = get_uri_field(url, &hp_u, UF_HOST); | ||
| 942 | + | ||
| 943 | + field = get_uri_field(url, &hp_u, UF_PORT); | ||
| 944 | + if(!field.empty()){ | ||
| 945 | + port = atoi(field.c_str()); | ||
| 946 | + } | ||
| 947 | + | ||
| 948 | + path = get_uri_field(url, &hp_u, UF_PATH); | ||
| 949 | + srs_info("parse url %s success", purl); | ||
| 950 | + | ||
| 951 | + query = get_uri_field(url, &hp_u, UF_QUERY); | ||
| 952 | + srs_info("parse query %s success", query.c_str()); | ||
| 953 | + | ||
| 954 | + return ret; | ||
| 955 | +} | ||
| 956 | + | ||
| 957 | +const char* SrsHttpUri::get_url() | ||
| 958 | +{ | ||
| 959 | + return url.data(); | ||
| 960 | +} | ||
| 961 | + | ||
| 962 | +const char* SrsHttpUri::get_schema() | ||
| 963 | +{ | ||
| 964 | + return schema.data(); | ||
| 965 | +} | ||
| 966 | + | ||
| 967 | +const char* SrsHttpUri::get_host() | ||
| 968 | +{ | ||
| 969 | + return host.data(); | ||
| 970 | +} | ||
| 971 | + | ||
| 972 | +int SrsHttpUri::get_port() | ||
| 973 | +{ | ||
| 974 | + return port; | ||
| 975 | +} | ||
| 976 | + | ||
| 977 | +const char* SrsHttpUri::get_path() | ||
| 978 | +{ | ||
| 979 | + return path.data(); | ||
| 980 | +} | ||
| 981 | + | ||
| 982 | +const char* SrsHttpUri::get_query() | ||
| 983 | +{ | ||
| 984 | + return query.data(); | ||
| 985 | +} | ||
| 986 | + | ||
| 987 | +string SrsHttpUri::get_uri_field(string uri, http_parser_url* hp_u, http_parser_url_fields field) | ||
| 988 | +{ | ||
| 989 | + if((hp_u->field_set & (1 << field)) == 0){ | ||
| 990 | + return ""; | ||
| 991 | + } | ||
| 992 | + | ||
| 993 | + srs_verbose("uri field matched, off=%d, len=%d, value=%.*s", | ||
| 994 | + hp_u->field_data[field].off, | ||
| 995 | + hp_u->field_data[field].len, | ||
| 996 | + hp_u->field_data[field].len, | ||
| 997 | + uri.c_str() + hp_u->field_data[field].off); | ||
| 998 | + | ||
| 999 | + int offset = hp_u->field_data[field].off; | ||
| 1000 | + int len = hp_u->field_data[field].len; | ||
| 1001 | + | ||
| 1002 | + return uri.substr(offset, len); | ||
| 1003 | +} | ||
| 1004 | + | ||
| 1005 | +#endif | ||
| 1006 | + | ||
| 1007 | +#ifdef SRS_AUTO_HTTP_SERVER | ||
| 1008 | + | ||
| 54 | SrsVodStream::SrsVodStream(string root_dir) | 1009 | SrsVodStream::SrsVodStream(string root_dir) |
| 55 | : SrsHttpFileServer(root_dir) | 1010 | : SrsHttpFileServer(root_dir) |
| 56 | { | 1011 | { |
| @@ -60,7 +1015,7 @@ SrsVodStream::~SrsVodStream() | @@ -60,7 +1015,7 @@ SrsVodStream::~SrsVodStream() | ||
| 60 | { | 1015 | { |
| 61 | } | 1016 | } |
| 62 | 1017 | ||
| 63 | -int SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int offset) | 1018 | +int SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int offset) |
| 64 | { | 1019 | { |
| 65 | int ret = ERROR_SUCCESS; | 1020 | int ret = ERROR_SUCCESS; |
| 66 | 1021 | ||
| @@ -144,7 +1099,7 @@ int SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, SrsHttpMessage* r, | @@ -144,7 +1099,7 @@ int SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, SrsHttpMessage* r, | ||
| 144 | return ret; | 1099 | return ret; |
| 145 | } | 1100 | } |
| 146 | 1101 | ||
| 147 | -int SrsVodStream::serve_mp4_stream(ISrsHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int start, int end) | 1102 | +int SrsVodStream::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int start, int end) |
| 148 | { | 1103 | { |
| 149 | int ret = ERROR_SUCCESS; | 1104 | int ret = ERROR_SUCCESS; |
| 150 | 1105 | ||
| @@ -202,12 +1157,11 @@ SrsStreamCache::SrsStreamCache(SrsSource* s, SrsRequest* r) | @@ -202,12 +1157,11 @@ SrsStreamCache::SrsStreamCache(SrsSource* s, SrsRequest* r) | ||
| 202 | req = r->copy(); | 1157 | req = r->copy(); |
| 203 | source = s; | 1158 | source = s; |
| 204 | queue = new SrsMessageQueue(true); | 1159 | queue = new SrsMessageQueue(true); |
| 205 | - pthread = new SrsThread("http-stream", this, 0, false); | 1160 | + pthread = new SrsEndlessThread("http-stream", this); |
| 206 | } | 1161 | } |
| 207 | 1162 | ||
| 208 | SrsStreamCache::~SrsStreamCache() | 1163 | SrsStreamCache::~SrsStreamCache() |
| 209 | { | 1164 | { |
| 210 | - pthread->stop(); | ||
| 211 | srs_freep(pthread); | 1165 | srs_freep(pthread); |
| 212 | 1166 | ||
| 213 | srs_freep(queue); | 1167 | srs_freep(queue); |
| @@ -567,7 +1521,7 @@ SrsLiveStream::~SrsLiveStream() | @@ -567,7 +1521,7 @@ SrsLiveStream::~SrsLiveStream() | ||
| 567 | srs_freep(req); | 1521 | srs_freep(req); |
| 568 | } | 1522 | } |
| 569 | 1523 | ||
| 570 | -int SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | 1524 | +int SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) |
| 571 | { | 1525 | { |
| 572 | int ret = ERROR_SUCCESS; | 1526 | int ret = ERROR_SUCCESS; |
| 573 | 1527 | ||
| @@ -743,7 +1697,7 @@ void SrsHlsM3u8Stream::set_m3u8(std::string v) | @@ -743,7 +1697,7 @@ void SrsHlsM3u8Stream::set_m3u8(std::string v) | ||
| 743 | m3u8 = v; | 1697 | m3u8 = v; |
| 744 | } | 1698 | } |
| 745 | 1699 | ||
| 746 | -int SrsHlsM3u8Stream::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | 1700 | +int SrsHlsM3u8Stream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) |
| 747 | { | 1701 | { |
| 748 | int ret = ERROR_SUCCESS; | 1702 | int ret = ERROR_SUCCESS; |
| 749 | 1703 | ||
| @@ -775,7 +1729,7 @@ void SrsHlsTsStream::set_ts(std::string v) | @@ -775,7 +1729,7 @@ void SrsHlsTsStream::set_ts(std::string v) | ||
| 775 | ts = v; | 1729 | ts = v; |
| 776 | } | 1730 | } |
| 777 | 1731 | ||
| 778 | -int SrsHlsTsStream::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | 1732 | +int SrsHlsTsStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) |
| 779 | { | 1733 | { |
| 780 | int ret = ERROR_SUCCESS; | 1734 | int ret = ERROR_SUCCESS; |
| 781 | 1735 | ||
| @@ -1110,7 +2064,7 @@ int SrsHttpServer::on_reload_vhost_hls(string vhost) | @@ -1110,7 +2064,7 @@ int SrsHttpServer::on_reload_vhost_hls(string vhost) | ||
| 1110 | return ret; | 2064 | return ret; |
| 1111 | } | 2065 | } |
| 1112 | 2066 | ||
| 1113 | -int SrsHttpServer::hijack(SrsHttpMessage* request, ISrsHttpHandler** ph) | 2067 | +int SrsHttpServer::hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph) |
| 1114 | { | 2068 | { |
| 1115 | int ret = ERROR_SUCCESS; | 2069 | int ret = ERROR_SUCCESS; |
| 1116 | 2070 | ||
| @@ -1169,8 +2123,12 @@ int SrsHttpServer::hijack(SrsHttpMessage* request, ISrsHttpHandler** ph) | @@ -1169,8 +2123,12 @@ int SrsHttpServer::hijack(SrsHttpMessage* request, ISrsHttpHandler** ph) | ||
| 1169 | } | 2123 | } |
| 1170 | } | 2124 | } |
| 1171 | 2125 | ||
| 2126 | + // convert to concreate class. | ||
| 2127 | + SrsHttpMessage* hreq = dynamic_cast<SrsHttpMessage*>(request); | ||
| 2128 | + srs_assert(hreq); | ||
| 2129 | + | ||
| 1172 | // hijack for entry. | 2130 | // hijack for entry. |
| 1173 | - SrsRequest* r = request->to_request(vhost->arg0()); | 2131 | + SrsRequest* r = hreq->to_request(vhost->arg0()); |
| 1174 | SrsAutoFree(SrsRequest, r); | 2132 | SrsAutoFree(SrsRequest, r); |
| 1175 | SrsSource* s = SrsSource::fetch(r); | 2133 | SrsSource* s = SrsSource::fetch(r); |
| 1176 | if (!s) { | 2134 | if (!s) { |
| @@ -1389,7 +2347,7 @@ int SrsHttpConn::do_cycle() | @@ -1389,7 +2347,7 @@ int SrsHttpConn::do_cycle() | ||
| 1389 | 2347 | ||
| 1390 | // process http messages. | 2348 | // process http messages. |
| 1391 | for (;;) { | 2349 | for (;;) { |
| 1392 | - SrsHttpMessage* req = NULL; | 2350 | + ISrsHttpMessage* req = NULL; |
| 1393 | 2351 | ||
| 1394 | // get a http message | 2352 | // get a http message |
| 1395 | if ((ret = parser->parse_message(&skt, this, &req)) != ERROR_SUCCESS) { | 2353 | if ((ret = parser->parse_message(&skt, this, &req)) != ERROR_SUCCESS) { |
| @@ -1400,7 +2358,7 @@ int SrsHttpConn::do_cycle() | @@ -1400,7 +2358,7 @@ int SrsHttpConn::do_cycle() | ||
| 1400 | srs_assert(req); | 2358 | srs_assert(req); |
| 1401 | 2359 | ||
| 1402 | // always free it in this scope. | 2360 | // always free it in this scope. |
| 1403 | - SrsAutoFree(SrsHttpMessage, req); | 2361 | + SrsAutoFree(ISrsHttpMessage, req); |
| 1404 | 2362 | ||
| 1405 | // may should discard the body. | 2363 | // may should discard the body. |
| 1406 | if ((ret = on_got_http_message(req)) != ERROR_SUCCESS) { | 2364 | if ((ret = on_got_http_message(req)) != ERROR_SUCCESS) { |
| @@ -1423,7 +2381,7 @@ int SrsHttpConn::do_cycle() | @@ -1423,7 +2381,7 @@ int SrsHttpConn::do_cycle() | ||
| 1423 | return ret; | 2381 | return ret; |
| 1424 | } | 2382 | } |
| 1425 | 2383 | ||
| 1426 | -int SrsHttpConn::process_request(ISrsHttpResponseWriter* w, SrsHttpMessage* r) | 2384 | +int SrsHttpConn::process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) |
| 1427 | { | 2385 | { |
| 1428 | int ret = ERROR_SUCCESS; | 2386 | int ret = ERROR_SUCCESS; |
| 1429 | 2387 | ||
| @@ -1450,7 +2408,7 @@ SrsStaticHttpConn::~SrsStaticHttpConn() | @@ -1450,7 +2408,7 @@ SrsStaticHttpConn::~SrsStaticHttpConn() | ||
| 1450 | { | 2408 | { |
| 1451 | } | 2409 | } |
| 1452 | 2410 | ||
| 1453 | -int SrsStaticHttpConn::on_got_http_message(SrsHttpMessage* msg) | 2411 | +int SrsStaticHttpConn::on_got_http_message(ISrsHttpMessage* msg) |
| 1454 | { | 2412 | { |
| 1455 | int ret = ERROR_SUCCESS; | 2413 | int ret = ERROR_SUCCESS; |
| 1456 | 2414 |
| @@ -30,14 +30,22 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -30,14 +30,22 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 30 | 30 | ||
| 31 | #include <srs_core.hpp> | 31 | #include <srs_core.hpp> |
| 32 | 32 | ||
| 33 | -#ifdef SRS_AUTO_HTTP_SERVER | 33 | +#ifdef SRS_AUTO_HTTP_PARSER |
| 34 | +#include <http_parser.h> | ||
| 35 | +#endif | ||
| 36 | + | ||
| 37 | +#if defined(SRS_AUTO_HTTP_PARSER) || defined(SRS_AUTO_HTTP_SERVER) | ||
| 38 | + | ||
| 39 | +#include <map> | ||
| 40 | +#include <string> | ||
| 41 | +#include <vector> | ||
| 34 | 42 | ||
| 35 | #include <srs_app_st.hpp> | 43 | #include <srs_app_st.hpp> |
| 36 | -#include <srs_app_conn.hpp> | ||
| 37 | -#include <srs_app_http.hpp> | 44 | +#include <srs_http_stack.hpp> |
| 38 | #include <srs_app_reload.hpp> | 45 | #include <srs_app_reload.hpp> |
| 39 | #include <srs_kernel_file.hpp> | 46 | #include <srs_kernel_file.hpp> |
| 40 | #include <srs_app_thread.hpp> | 47 | #include <srs_app_thread.hpp> |
| 48 | +#include <srs_app_conn.hpp> | ||
| 41 | 49 | ||
| 42 | class SrsServer; | 50 | class SrsServer; |
| 43 | class SrsSource; | 51 | class SrsSource; |
| @@ -49,10 +57,313 @@ class SrsAacEncoder; | @@ -49,10 +57,313 @@ class SrsAacEncoder; | ||
| 49 | class SrsMp3Encoder; | 57 | class SrsMp3Encoder; |
| 50 | class SrsFlvEncoder; | 58 | class SrsFlvEncoder; |
| 51 | class SrsHttpParser; | 59 | class SrsHttpParser; |
| 52 | -class SrsHttpMessage; | 60 | +class ISrsHttpMessage; |
| 53 | class SrsHttpHandler; | 61 | class SrsHttpHandler; |
| 54 | class SrsMessageQueue; | 62 | class SrsMessageQueue; |
| 55 | class SrsSharedPtrMessage; | 63 | class SrsSharedPtrMessage; |
| 64 | +class SrsRequest; | ||
| 65 | +class SrsFastBuffer; | ||
| 66 | +class SrsHttpUri; | ||
| 67 | +class SrsConnection; | ||
| 68 | +class SrsHttpMessage; | ||
| 69 | + | ||
| 70 | +#endif | ||
| 71 | + | ||
| 72 | +#ifdef SRS_AUTO_HTTP_PARSER | ||
| 73 | + | ||
| 74 | +/** | ||
| 75 | + * response writer use st socket | ||
| 76 | + */ | ||
| 77 | +class SrsHttpResponseWriter : public ISrsHttpResponseWriter | ||
| 78 | +{ | ||
| 79 | +private: | ||
| 80 | + SrsStSocket* skt; | ||
| 81 | + SrsHttpHeader* hdr; | ||
| 82 | +private: | ||
| 83 | + // reply header has been (logically) written | ||
| 84 | + bool header_wrote; | ||
| 85 | + // status code passed to WriteHeader | ||
| 86 | + int status; | ||
| 87 | +private: | ||
| 88 | + // explicitly-declared Content-Length; or -1 | ||
| 89 | + int64_t content_length; | ||
| 90 | + // number of bytes written in body | ||
| 91 | + int64_t written; | ||
| 92 | +private: | ||
| 93 | + // wroteHeader tells whether the header's been written to "the | ||
| 94 | + // wire" (or rather: w.conn.buf). this is unlike | ||
| 95 | + // (*response).wroteHeader, which tells only whether it was | ||
| 96 | + // logically written. | ||
| 97 | + bool header_sent; | ||
| 98 | +public: | ||
| 99 | + SrsHttpResponseWriter(SrsStSocket* io); | ||
| 100 | + virtual ~SrsHttpResponseWriter(); | ||
| 101 | +public: | ||
| 102 | + virtual int final_request(); | ||
| 103 | + virtual SrsHttpHeader* header(); | ||
| 104 | + virtual int write(char* data, int size); | ||
| 105 | + virtual void write_header(int code); | ||
| 106 | + virtual int send_header(char* data, int size); | ||
| 107 | +}; | ||
| 108 | + | ||
| 109 | +/** | ||
| 110 | + * response reader use st socket. | ||
| 111 | + */ | ||
| 112 | +class SrsHttpResponseReader : virtual public ISrsHttpResponseReader | ||
| 113 | +{ | ||
| 114 | +private: | ||
| 115 | + SrsStSocket* skt; | ||
| 116 | + SrsHttpMessage* owner; | ||
| 117 | + SrsFastBuffer* buffer; | ||
| 118 | + bool is_eof; | ||
| 119 | + // the left bytes in chunk. | ||
| 120 | + int nb_left_chunk; | ||
| 121 | + // the number of bytes of current chunk. | ||
| 122 | + int nb_chunk; | ||
| 123 | + // already read total bytes. | ||
| 124 | + int64_t nb_total_read; | ||
| 125 | +public: | ||
| 126 | + SrsHttpResponseReader(SrsHttpMessage* msg, SrsStSocket* io); | ||
| 127 | + virtual ~SrsHttpResponseReader(); | ||
| 128 | +public: | ||
| 129 | + /** | ||
| 130 | + * initialize the response reader with buffer. | ||
| 131 | + */ | ||
| 132 | + virtual int initialize(SrsFastBuffer* buffer); | ||
| 133 | + // interface ISrsHttpResponseReader | ||
| 134 | +public: | ||
| 135 | + virtual bool eof(); | ||
| 136 | + virtual int read(char* data, int nb_data, int* nb_read); | ||
| 137 | +private: | ||
| 138 | + virtual int read_chunked(char* data, int nb_data, int* nb_read); | ||
| 139 | + virtual int read_specified(char* data, int nb_data, int* nb_read); | ||
| 140 | +}; | ||
| 141 | + | ||
| 142 | +// for http header. | ||
| 143 | +typedef std::pair<std::string, std::string> SrsHttpHeaderField; | ||
| 144 | + | ||
| 145 | +// A Request represents an HTTP request received by a server | ||
| 146 | +// or to be sent by a client. | ||
| 147 | +// | ||
| 148 | +// The field semantics differ slightly between client and server | ||
| 149 | +// usage. In addition to the notes on the fields below, see the | ||
| 150 | +// documentation for Request.Write and RoundTripper. | ||
| 151 | +/** | ||
| 152 | + * the http message, request or response. | ||
| 153 | + */ | ||
| 154 | +class SrsHttpMessage : public ISrsHttpMessage | ||
| 155 | +{ | ||
| 156 | +private: | ||
| 157 | + /** | ||
| 158 | + * parsed url. | ||
| 159 | + */ | ||
| 160 | + std::string _url; | ||
| 161 | + /** | ||
| 162 | + * the extension of file, for example, .flv | ||
| 163 | + */ | ||
| 164 | + std::string _ext; | ||
| 165 | + /** | ||
| 166 | + * parsed http header. | ||
| 167 | + */ | ||
| 168 | + http_parser _header; | ||
| 169 | + /** | ||
| 170 | + * body object, reader object. | ||
| 171 | + * @remark, user can get body in string by get_body(). | ||
| 172 | + */ | ||
| 173 | + SrsHttpResponseReader* _body; | ||
| 174 | + /** | ||
| 175 | + * whether the body is chunked. | ||
| 176 | + */ | ||
| 177 | + bool chunked; | ||
| 178 | + /** | ||
| 179 | + * whether the request indicates should keep alive | ||
| 180 | + * for the http connection. | ||
| 181 | + */ | ||
| 182 | + bool keep_alive; | ||
| 183 | + /** | ||
| 184 | + * uri parser | ||
| 185 | + */ | ||
| 186 | + SrsHttpUri* _uri; | ||
| 187 | + /** | ||
| 188 | + * use a buffer to read and send ts file. | ||
| 189 | + */ | ||
| 190 | + // TODO: FIXME: remove it. | ||
| 191 | + char* _http_ts_send_buffer; | ||
| 192 | + // http headers | ||
| 193 | + std::vector<SrsHttpHeaderField> _headers; | ||
| 194 | + // the query map | ||
| 195 | + std::map<std::string, std::string> _query; | ||
| 196 | + // the transport connection, can be NULL. | ||
| 197 | + SrsConnection* conn; | ||
| 198 | +public: | ||
| 199 | + SrsHttpMessage(SrsStSocket* io, SrsConnection* c); | ||
| 200 | + virtual ~SrsHttpMessage(); | ||
| 201 | +public: | ||
| 202 | + /** | ||
| 203 | + * set the original messages, then update the message. | ||
| 204 | + */ | ||
| 205 | + virtual int update(std::string url, http_parser* header, | ||
| 206 | + SrsFastBuffer* body, std::vector<SrsHttpHeaderField>& headers | ||
| 207 | + ); | ||
| 208 | +private: | ||
| 209 | + virtual SrsConnection* connection(); | ||
| 210 | +public: | ||
| 211 | + virtual u_int8_t method(); | ||
| 212 | + virtual u_int16_t status_code(); | ||
| 213 | + /** | ||
| 214 | + * method helpers. | ||
| 215 | + */ | ||
| 216 | + virtual std::string method_str(); | ||
| 217 | + virtual bool is_http_get(); | ||
| 218 | + virtual bool is_http_put(); | ||
| 219 | + virtual bool is_http_post(); | ||
| 220 | + virtual bool is_http_delete(); | ||
| 221 | + virtual bool is_http_options(); | ||
| 222 | + /** | ||
| 223 | + * whether body is chunked encoding, for reader only. | ||
| 224 | + */ | ||
| 225 | + virtual bool is_chunked(); | ||
| 226 | + /** | ||
| 227 | + * whether should keep the connection alive. | ||
| 228 | + */ | ||
| 229 | + virtual bool is_keep_alive(); | ||
| 230 | + /** | ||
| 231 | + * the uri contains the host and path. | ||
| 232 | + */ | ||
| 233 | + virtual std::string uri(); | ||
| 234 | + /** | ||
| 235 | + * the url maybe the path. | ||
| 236 | + */ | ||
| 237 | + virtual std::string url(); | ||
| 238 | + virtual std::string host(); | ||
| 239 | + virtual std::string path(); | ||
| 240 | + virtual std::string ext(); | ||
| 241 | +public: | ||
| 242 | + /** | ||
| 243 | + * read body to string. | ||
| 244 | + * @remark for small http body. | ||
| 245 | + */ | ||
| 246 | + virtual int body_read_all(std::string& body); | ||
| 247 | + /** | ||
| 248 | + * get the body reader, to read one by one. | ||
| 249 | + * @remark when body is very large, or chunked, use this. | ||
| 250 | + */ | ||
| 251 | + virtual ISrsHttpResponseReader* body_reader(); | ||
| 252 | + /** | ||
| 253 | + * the content length, -1 for chunked or not set. | ||
| 254 | + */ | ||
| 255 | + virtual int64_t content_length(); | ||
| 256 | + /** | ||
| 257 | + * get the param in query string, | ||
| 258 | + * for instance, query is "start=100&end=200", | ||
| 259 | + * then query_get("start") is "100", and query_get("end") is "200" | ||
| 260 | + */ | ||
| 261 | + virtual std::string query_get(std::string key); | ||
| 262 | + /** | ||
| 263 | + * get the headers. | ||
| 264 | + */ | ||
| 265 | + virtual int request_header_count(); | ||
| 266 | + virtual std::string request_header_key_at(int index); | ||
| 267 | + virtual std::string request_header_value_at(int index); | ||
| 268 | + virtual std::string get_request_header(std::string name); | ||
| 269 | +public: | ||
| 270 | + /** | ||
| 271 | + * convert the http message to a request. | ||
| 272 | + * @remark user must free the return request. | ||
| 273 | + */ | ||
| 274 | + virtual SrsRequest* to_request(std::string vhost); | ||
| 275 | +}; | ||
| 276 | + | ||
| 277 | +/** | ||
| 278 | + * wrapper for http-parser, | ||
| 279 | + * provides HTTP message originted service. | ||
| 280 | + */ | ||
| 281 | +class SrsHttpParser | ||
| 282 | +{ | ||
| 283 | +private: | ||
| 284 | + http_parser_settings settings; | ||
| 285 | + http_parser parser; | ||
| 286 | + // the global parse buffer. | ||
| 287 | + SrsFastBuffer* buffer; | ||
| 288 | +private: | ||
| 289 | + // http parse data, reset before parse message. | ||
| 290 | + bool expect_field_name; | ||
| 291 | + std::string field_name; | ||
| 292 | + std::string field_value; | ||
| 293 | + SrsHttpParseState state; | ||
| 294 | + http_parser header; | ||
| 295 | + std::string url; | ||
| 296 | + std::vector<SrsHttpHeaderField> headers; | ||
| 297 | + int header_parsed; | ||
| 298 | +public: | ||
| 299 | + SrsHttpParser(); | ||
| 300 | + virtual ~SrsHttpParser(); | ||
| 301 | +public: | ||
| 302 | + /** | ||
| 303 | + * initialize the http parser with specified type, | ||
| 304 | + * one parser can only parse request or response messages. | ||
| 305 | + */ | ||
| 306 | + virtual int initialize(enum http_parser_type type); | ||
| 307 | + /** | ||
| 308 | + * always parse a http message, | ||
| 309 | + * that is, the *ppmsg always NOT-NULL when return success. | ||
| 310 | + * or error and *ppmsg must be NULL. | ||
| 311 | + * @remark, if success, *ppmsg always NOT-NULL, *ppmsg always is_complete(). | ||
| 312 | + */ | ||
| 313 | + virtual int parse_message(SrsStSocket* skt, SrsConnection* conn, ISrsHttpMessage** ppmsg); | ||
| 314 | +private: | ||
| 315 | + /** | ||
| 316 | + * parse the HTTP message to member field: msg. | ||
| 317 | + */ | ||
| 318 | + virtual int parse_message_imp(SrsStSocket* skt); | ||
| 319 | +private: | ||
| 320 | + static int on_message_begin(http_parser* parser); | ||
| 321 | + static int on_headers_complete(http_parser* parser); | ||
| 322 | + static int on_message_complete(http_parser* parser); | ||
| 323 | + static int on_url(http_parser* parser, const char* at, size_t length); | ||
| 324 | + static int on_header_field(http_parser* parser, const char* at, size_t length); | ||
| 325 | + static int on_header_value(http_parser* parser, const char* at, size_t length); | ||
| 326 | + static int on_body(http_parser* parser, const char* at, size_t length); | ||
| 327 | +}; | ||
| 328 | + | ||
| 329 | +/** | ||
| 330 | + * used to resolve the http uri. | ||
| 331 | + */ | ||
| 332 | +class SrsHttpUri | ||
| 333 | +{ | ||
| 334 | +private: | ||
| 335 | + std::string url; | ||
| 336 | + std::string schema; | ||
| 337 | + std::string host; | ||
| 338 | + int port; | ||
| 339 | + std::string path; | ||
| 340 | + std::string query; | ||
| 341 | +public: | ||
| 342 | + SrsHttpUri(); | ||
| 343 | + virtual ~SrsHttpUri(); | ||
| 344 | +public: | ||
| 345 | + /** | ||
| 346 | + * initialize the http uri. | ||
| 347 | + */ | ||
| 348 | + virtual int initialize(std::string _url); | ||
| 349 | +public: | ||
| 350 | + virtual const char* get_url(); | ||
| 351 | + virtual const char* get_schema(); | ||
| 352 | + virtual const char* get_host(); | ||
| 353 | + virtual int get_port(); | ||
| 354 | + virtual const char* get_path(); | ||
| 355 | + virtual const char* get_query(); | ||
| 356 | +private: | ||
| 357 | + /** | ||
| 358 | + * get the parsed url field. | ||
| 359 | + * @return return empty string if not set. | ||
| 360 | + */ | ||
| 361 | + virtual std::string get_uri_field(std::string uri, http_parser_url* hp_u, http_parser_url_fields field); | ||
| 362 | +}; | ||
| 363 | + | ||
| 364 | +#endif | ||
| 365 | + | ||
| 366 | +#ifdef SRS_AUTO_HTTP_SERVER | ||
| 56 | 367 | ||
| 57 | /** | 368 | /** |
| 58 | * the flv vod stream supports flv?start=offset-bytes. | 369 | * the flv vod stream supports flv?start=offset-bytes. |
| @@ -66,8 +377,8 @@ public: | @@ -66,8 +377,8 @@ public: | ||
| 66 | SrsVodStream(std::string root_dir); | 377 | SrsVodStream(std::string root_dir); |
| 67 | virtual ~SrsVodStream(); | 378 | virtual ~SrsVodStream(); |
| 68 | protected: | 379 | protected: |
| 69 | - virtual int serve_flv_stream(ISrsHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath, int offset); | ||
| 70 | - virtual int serve_mp4_stream(ISrsHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath, int start, int end); | 380 | + virtual int serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int offset); |
| 381 | + virtual int serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int start, int end); | ||
| 71 | }; | 382 | }; |
| 72 | 383 | ||
| 73 | /** | 384 | /** |
| @@ -75,20 +386,20 @@ protected: | @@ -75,20 +386,20 @@ protected: | ||
| 75 | * for example, the audio stream cache to make android(weixin) happy. | 386 | * for example, the audio stream cache to make android(weixin) happy. |
| 76 | * we start a thread to shrink the queue. | 387 | * we start a thread to shrink the queue. |
| 77 | */ | 388 | */ |
| 78 | -class SrsStreamCache : public ISrsThreadHandler | 389 | +class SrsStreamCache : public ISrsEndlessThreadHandler |
| 79 | { | 390 | { |
| 80 | private: | 391 | private: |
| 81 | SrsMessageQueue* queue; | 392 | SrsMessageQueue* queue; |
| 82 | SrsSource* source; | 393 | SrsSource* source; |
| 83 | SrsRequest* req; | 394 | SrsRequest* req; |
| 84 | - SrsThread* pthread; | 395 | + SrsEndlessThread* pthread; |
| 85 | public: | 396 | public: |
| 86 | SrsStreamCache(SrsSource* s, SrsRequest* r); | 397 | SrsStreamCache(SrsSource* s, SrsRequest* r); |
| 87 | virtual ~SrsStreamCache(); | 398 | virtual ~SrsStreamCache(); |
| 88 | public: | 399 | public: |
| 89 | virtual int start(); | 400 | virtual int start(); |
| 90 | virtual int dump_cache(SrsConsumer* consumer); | 401 | virtual int dump_cache(SrsConsumer* consumer); |
| 91 | -// interface ISrsThreadHandler. | 402 | +// interface ISrsEndlessThreadHandler. |
| 92 | public: | 403 | public: |
| 93 | virtual int cycle(); | 404 | virtual int cycle(); |
| 94 | }; | 405 | }; |
| @@ -243,7 +554,7 @@ public: | @@ -243,7 +554,7 @@ public: | ||
| 243 | SrsLiveStream(SrsSource* s, SrsRequest* r, SrsStreamCache* c); | 554 | SrsLiveStream(SrsSource* s, SrsRequest* r, SrsStreamCache* c); |
| 244 | virtual ~SrsLiveStream(); | 555 | virtual ~SrsLiveStream(); |
| 245 | public: | 556 | public: |
| 246 | - virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r); | 557 | + virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); |
| 247 | private: | 558 | private: |
| 248 | virtual int streaming_send_messages(ISrsStreamEncoder* enc, SrsSharedPtrMessage** msgs, int nb_msgs); | 559 | virtual int streaming_send_messages(ISrsStreamEncoder* enc, SrsSharedPtrMessage** msgs, int nb_msgs); |
| 249 | }; | 560 | }; |
| @@ -289,7 +600,7 @@ public: | @@ -289,7 +600,7 @@ public: | ||
| 289 | public: | 600 | public: |
| 290 | virtual void set_m3u8(std::string v); | 601 | virtual void set_m3u8(std::string v); |
| 291 | public: | 602 | public: |
| 292 | - virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r); | 603 | + virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); |
| 293 | }; | 604 | }; |
| 294 | 605 | ||
| 295 | /** | 606 | /** |
| @@ -305,7 +616,7 @@ public: | @@ -305,7 +616,7 @@ public: | ||
| 305 | public: | 616 | public: |
| 306 | virtual void set_ts(std::string v); | 617 | virtual void set_ts(std::string v); |
| 307 | public: | 618 | public: |
| 308 | - virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r); | 619 | + virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); |
| 309 | }; | 620 | }; |
| 310 | 621 | ||
| 311 | /** | 622 | /** |
| @@ -358,14 +669,14 @@ public: | @@ -358,14 +669,14 @@ public: | ||
| 358 | virtual int hls_update_m3u8(SrsRequest* r, std::string m3u8); | 669 | virtual int hls_update_m3u8(SrsRequest* r, std::string m3u8); |
| 359 | virtual int hls_update_ts(SrsRequest* r, std::string uri, std::string ts); | 670 | virtual int hls_update_ts(SrsRequest* r, std::string uri, std::string ts); |
| 360 | virtual void unmount_hls(SrsRequest* r); | 671 | virtual void unmount_hls(SrsRequest* r); |
| 361 | -// interface ISrsThreadHandler. | 672 | +// interface ISrsReloadHandler. |
| 362 | public: | 673 | public: |
| 363 | virtual int on_reload_vhost_http_updated(); | 674 | virtual int on_reload_vhost_http_updated(); |
| 364 | virtual int on_reload_vhost_http_remux_updated(); | 675 | virtual int on_reload_vhost_http_remux_updated(); |
| 365 | virtual int on_reload_vhost_hls(std::string vhost); | 676 | virtual int on_reload_vhost_hls(std::string vhost); |
| 366 | // interface ISrsHttpMatchHijacker | 677 | // interface ISrsHttpMatchHijacker |
| 367 | public: | 678 | public: |
| 368 | - virtual int hijack(SrsHttpMessage* request, ISrsHttpHandler** ph); | 679 | + virtual int hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph); |
| 369 | private: | 680 | private: |
| 370 | virtual int initialize_static_file(); | 681 | virtual int initialize_static_file(); |
| 371 | virtual int initialize_flv_streaming(); | 682 | virtual int initialize_flv_streaming(); |
| @@ -392,9 +703,9 @@ protected: | @@ -392,9 +703,9 @@ protected: | ||
| 392 | // when got http message, | 703 | // when got http message, |
| 393 | // for the static service or api, discard any body. | 704 | // for the static service or api, discard any body. |
| 394 | // for the stream caster, for instance, http flv streaming, may discard the flv header or not. | 705 | // for the stream caster, for instance, http flv streaming, may discard the flv header or not. |
| 395 | - virtual int on_got_http_message(SrsHttpMessage* msg) = 0; | 706 | + virtual int on_got_http_message(ISrsHttpMessage* msg) = 0; |
| 396 | private: | 707 | private: |
| 397 | - virtual int process_request(ISrsHttpResponseWriter* w, SrsHttpMessage* r); | 708 | + virtual int process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); |
| 398 | }; | 709 | }; |
| 399 | 710 | ||
| 400 | class SrsStaticHttpConn : public SrsHttpConn | 711 | class SrsStaticHttpConn : public SrsHttpConn |
| @@ -403,7 +714,7 @@ public: | @@ -403,7 +714,7 @@ public: | ||
| 403 | SrsStaticHttpConn(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m); | 714 | SrsStaticHttpConn(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m); |
| 404 | virtual ~SrsStaticHttpConn(); | 715 | virtual ~SrsStaticHttpConn(); |
| 405 | public: | 716 | public: |
| 406 | - virtual int on_got_http_message(SrsHttpMessage* msg); | 717 | + virtual int on_got_http_message(ISrsHttpMessage* msg); |
| 407 | }; | 718 | }; |
| 408 | 719 | ||
| 409 | #endif | 720 | #endif |
| @@ -31,13 +31,13 @@ using namespace std; | @@ -31,13 +31,13 @@ using namespace std; | ||
| 31 | #include <srs_kernel_error.hpp> | 31 | #include <srs_kernel_error.hpp> |
| 32 | #include <srs_rtmp_sdk.hpp> | 32 | #include <srs_rtmp_sdk.hpp> |
| 33 | #include <srs_app_st_socket.hpp> | 33 | #include <srs_app_st_socket.hpp> |
| 34 | -#include <srs_app_http.hpp> | ||
| 35 | #include <srs_app_json.hpp> | 34 | #include <srs_app_json.hpp> |
| 36 | #include <srs_app_dvr.hpp> | 35 | #include <srs_app_dvr.hpp> |
| 37 | #include <srs_app_http_client.hpp> | 36 | #include <srs_app_http_client.hpp> |
| 38 | #include <srs_core_autofree.hpp> | 37 | #include <srs_core_autofree.hpp> |
| 39 | #include <srs_app_config.hpp> | 38 | #include <srs_app_config.hpp> |
| 40 | #include <srs_kernel_utility.hpp> | 39 | #include <srs_kernel_utility.hpp> |
| 40 | +#include <srs_app_http_conn.hpp> | ||
| 41 | 41 | ||
| 42 | #define SRS_HTTP_RESPONSE_OK SRS_XSTR(ERROR_SUCCESS) | 42 | #define SRS_HTTP_RESPONSE_OK SRS_XSTR(ERROR_SUCCESS) |
| 43 | 43 | ||
| @@ -371,11 +371,11 @@ int SrsHttpHooks::on_hls_notify(std::string url, SrsRequest* req, std::string ts | @@ -371,11 +371,11 @@ int SrsHttpHooks::on_hls_notify(std::string url, SrsRequest* req, std::string ts | ||
| 371 | } | 371 | } |
| 372 | srs_warn("GET %s", path.c_str()); | 372 | srs_warn("GET %s", path.c_str()); |
| 373 | 373 | ||
| 374 | - SrsHttpMessage* msg = NULL; | 374 | + ISrsHttpMessage* msg = NULL; |
| 375 | if ((ret = http.get(path.c_str(), "", &msg)) != ERROR_SUCCESS) { | 375 | if ((ret = http.get(path.c_str(), "", &msg)) != ERROR_SUCCESS) { |
| 376 | return ret; | 376 | return ret; |
| 377 | } | 377 | } |
| 378 | - SrsAutoFree(SrsHttpMessage, msg); | 378 | + SrsAutoFree(ISrsHttpMessage, msg); |
| 379 | 379 | ||
| 380 | int nb_buf = srs_min(nb_notify, SRS_HTTP_READ_BUFFER); | 380 | int nb_buf = srs_min(nb_notify, SRS_HTTP_READ_BUFFER); |
| 381 | char* buf = new char[nb_buf]; | 381 | char* buf = new char[nb_buf]; |
| @@ -416,11 +416,11 @@ int SrsHttpHooks::do_post(std::string url, std::string req, int& code, string& r | @@ -416,11 +416,11 @@ int SrsHttpHooks::do_post(std::string url, std::string req, int& code, string& r | ||
| 416 | return ret; | 416 | return ret; |
| 417 | } | 417 | } |
| 418 | 418 | ||
| 419 | - SrsHttpMessage* msg = NULL; | 419 | + ISrsHttpMessage* msg = NULL; |
| 420 | if ((ret = http.post(uri.get_path(), req, &msg)) != ERROR_SUCCESS) { | 420 | if ((ret = http.post(uri.get_path(), req, &msg)) != ERROR_SUCCESS) { |
| 421 | return ret; | 421 | return ret; |
| 422 | } | 422 | } |
| 423 | - SrsAutoFree(SrsHttpMessage, msg); | 423 | + SrsAutoFree(ISrsHttpMessage, msg); |
| 424 | 424 | ||
| 425 | code = msg->status_code(); | 425 | code = msg->status_code(); |
| 426 | if ((ret = msg->body_read_all(res)) != ERROR_SUCCESS) { | 426 | if ((ret = msg->body_read_all(res)) != ERROR_SUCCESS) { |
| @@ -55,7 +55,7 @@ SrsIngester::SrsIngester() | @@ -55,7 +55,7 @@ SrsIngester::SrsIngester() | ||
| 55 | { | 55 | { |
| 56 | _srs_config->subscribe(this); | 56 | _srs_config->subscribe(this); |
| 57 | 57 | ||
| 58 | - pthread = new SrsThread("ingest", this, SRS_AUTO_INGESTER_SLEEP_US, true); | 58 | + pthread = new SrsReusableThread("ingest", this, SRS_AUTO_INGESTER_SLEEP_US); |
| 59 | pprint = SrsPithyPrint::create_ingester(); | 59 | pprint = SrsPithyPrint::create_ingester(); |
| 60 | } | 60 | } |
| 61 | 61 |
| @@ -59,12 +59,12 @@ public: | @@ -59,12 +59,12 @@ public: | ||
| 59 | * encode with FFMPEG(optional), | 59 | * encode with FFMPEG(optional), |
| 60 | * push to SRS(or any RTMP server) over RTMP. | 60 | * push to SRS(or any RTMP server) over RTMP. |
| 61 | */ | 61 | */ |
| 62 | -class SrsIngester : public ISrsThreadHandler, public ISrsReloadHandler | 62 | +class SrsIngester : public ISrsReusableThreadHandler, public ISrsReloadHandler |
| 63 | { | 63 | { |
| 64 | private: | 64 | private: |
| 65 | std::vector<SrsIngesterFFMPEG*> ingesters; | 65 | std::vector<SrsIngesterFFMPEG*> ingesters; |
| 66 | private: | 66 | private: |
| 67 | - SrsThread* pthread; | 67 | + SrsReusableThread* pthread; |
| 68 | SrsPithyPrint* pprint; | 68 | SrsPithyPrint* pprint; |
| 69 | public: | 69 | public: |
| 70 | SrsIngester(); | 70 | SrsIngester(); |
| @@ -72,7 +72,7 @@ public: | @@ -72,7 +72,7 @@ public: | ||
| 72 | public: | 72 | public: |
| 73 | virtual int start(); | 73 | virtual int start(); |
| 74 | virtual void stop(); | 74 | virtual void stop(); |
| 75 | -// interface ISrsThreadHandler. | 75 | +// interface ISrsReusableThreadHandler. |
| 76 | public: | 76 | public: |
| 77 | virtual int cycle(); | 77 | virtual int cycle(); |
| 78 | virtual void on_thread_stop(); | 78 | virtual void on_thread_stop(); |
| @@ -135,27 +135,34 @@ public: | @@ -135,27 +135,34 @@ public: | ||
| 135 | }; | 135 | }; |
| 136 | 136 | ||
| 137 | /** | 137 | /** |
| 138 | -* to statistic the kbps of io. | ||
| 139 | -* itself can be a statistic source, for example, used for SRS bytes stat. | ||
| 140 | -* there are two usage scenarios: | ||
| 141 | -* 1. connections to calc kbps by sample(): | ||
| 142 | -* SrsKbps* kbps = ...; | ||
| 143 | -* kbps->set_io(in, out) | ||
| 144 | -* kbps->sample() | ||
| 145 | -* kbps->get_xxx_kbps(). | ||
| 146 | -* the connections know how many bytes already send/recv. | ||
| 147 | -* 2. server to calc kbps by add_delta(): | ||
| 148 | -* SrsKbps* kbps = ...; | ||
| 149 | -* kbps->set_io(NULL, NULL) | ||
| 150 | -* for each connection in connections: | ||
| 151 | -* IKbpsDelta* delta = connection; // where connection implements IKbpsDelta | ||
| 152 | -* delta->resample() | ||
| 153 | -* kbps->add_delta(delta) | ||
| 154 | -* delta->cleanup() | ||
| 155 | -* kbps->sample() | ||
| 156 | -* kbps->get_xxx_kbps(). | ||
| 157 | -* the server never know how many bytes already send/recv, for the connection maybe closed. | ||
| 158 | -*/ | 138 | + * to statistic the kbps of io. |
| 139 | + * itself can be a statistic source, for example, used for SRS bytes stat. | ||
| 140 | + * there are some usage scenarios: | ||
| 141 | + * 1. connections to calc kbps by sample(): | ||
| 142 | + * SrsKbps* kbps = ...; | ||
| 143 | + * kbps->set_io(in, out) | ||
| 144 | + * kbps->sample() | ||
| 145 | + * kbps->get_xxx_kbps(). | ||
| 146 | + * the connections know how many bytes already send/recv. | ||
| 147 | + * 2. server to calc kbps by add_delta(): | ||
| 148 | + * SrsKbps* kbps = ...; | ||
| 149 | + * kbps->set_io(NULL, NULL) | ||
| 150 | + * for each connection in connections: | ||
| 151 | + * IKbpsDelta* delta = connection; // where connection implements IKbpsDelta | ||
| 152 | + * delta->resample() | ||
| 153 | + * kbps->add_delta(delta) | ||
| 154 | + * delta->cleanup() | ||
| 155 | + * kbps->sample() | ||
| 156 | + * kbps->get_xxx_kbps(). | ||
| 157 | + * 3. kbps used as IKbpsDelta, to provides delta bytes: | ||
| 158 | + * SrsKbps* kbps = ...; | ||
| 159 | + * kbps->set_io(in, out); | ||
| 160 | + * IKbpsDelta* delta = (IKbpsDelta*)kbps; | ||
| 161 | + * delta->resample(); | ||
| 162 | + * printf("delta is %d/%d", delta->get_send_bytes_delta(), delta->get_recv_bytes_delta()); | ||
| 163 | + * delta->cleanup(); | ||
| 164 | + * the server never know how many bytes already send/recv, for the connection maybe closed. | ||
| 165 | + */ | ||
| 159 | class SrsKbps : public virtual ISrsProtocolStatistic, public virtual IKbpsDelta | 166 | class SrsKbps : public virtual ISrsProtocolStatistic, public virtual IKbpsDelta |
| 160 | { | 167 | { |
| 161 | private: | 168 | private: |
| @@ -79,7 +79,7 @@ SrsUdpListener::SrsUdpListener(ISrsUdpHandler* h, string i, int p) | @@ -79,7 +79,7 @@ SrsUdpListener::SrsUdpListener(ISrsUdpHandler* h, string i, int p) | ||
| 79 | nb_buf = SRS_UDP_MAX_PACKET_SIZE; | 79 | nb_buf = SRS_UDP_MAX_PACKET_SIZE; |
| 80 | buf = new char[nb_buf]; | 80 | buf = new char[nb_buf]; |
| 81 | 81 | ||
| 82 | - pthread = new SrsThread("udp", this, 0, true); | 82 | + pthread = new SrsReusableThread("udp", this); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | SrsUdpListener::~SrsUdpListener() | 85 | SrsUdpListener::~SrsUdpListener() |
| @@ -156,26 +156,24 @@ int SrsUdpListener::listen() | @@ -156,26 +156,24 @@ int SrsUdpListener::listen() | ||
| 156 | int SrsUdpListener::cycle() | 156 | int SrsUdpListener::cycle() |
| 157 | { | 157 | { |
| 158 | int ret = ERROR_SUCCESS; | 158 | int ret = ERROR_SUCCESS; |
| 159 | + | ||
| 160 | + // TODO: FIXME: support ipv6, @see man 7 ipv6 | ||
| 161 | + sockaddr_in from; | ||
| 162 | + int nb_from = sizeof(sockaddr_in); | ||
| 163 | + int nread = 0; | ||
| 164 | + | ||
| 165 | + if ((nread = st_recvfrom(_stfd, buf, nb_buf, (sockaddr*)&from, &nb_from, ST_UTIME_NO_TIMEOUT)) <= 0) { | ||
| 166 | + srs_warn("ignore recv udp packet failed, nread=%d", nread); | ||
| 167 | + return ret; | ||
| 168 | + } | ||
| 159 | 169 | ||
| 160 | - while (pthread->can_loop()) { | ||
| 161 | - // TODO: FIXME: support ipv6, @see man 7 ipv6 | ||
| 162 | - sockaddr_in from; | ||
| 163 | - int nb_from = sizeof(sockaddr_in); | ||
| 164 | - int nread = 0; | ||
| 165 | - | ||
| 166 | - if ((nread = st_recvfrom(_stfd, buf, nb_buf, (sockaddr*)&from, &nb_from, ST_UTIME_NO_TIMEOUT)) <= 0) { | ||
| 167 | - srs_warn("ignore recv udp packet failed, nread=%d", nread); | ||
| 168 | - continue; | ||
| 169 | - } | ||
| 170 | - | ||
| 171 | - if ((ret = handler->on_udp_packet(&from, buf, nread)) != ERROR_SUCCESS) { | ||
| 172 | - srs_warn("handle udp packet failed. ret=%d", ret); | ||
| 173 | - continue; | ||
| 174 | - } | ||
| 175 | - | ||
| 176 | - if (SRS_UDP_PACKET_RECV_CYCLE_INTERVAL_MS > 0) { | ||
| 177 | - st_usleep(SRS_UDP_PACKET_RECV_CYCLE_INTERVAL_MS * 1000); | ||
| 178 | - } | 170 | + if ((ret = handler->on_udp_packet(&from, buf, nread)) != ERROR_SUCCESS) { |
| 171 | + srs_warn("handle udp packet failed. ret=%d", ret); | ||
| 172 | + return ret; | ||
| 173 | + } | ||
| 174 | + | ||
| 175 | + if (SRS_UDP_PACKET_RECV_CYCLE_INTERVAL_MS > 0) { | ||
| 176 | + st_usleep(SRS_UDP_PACKET_RECV_CYCLE_INTERVAL_MS * 1000); | ||
| 179 | } | 177 | } |
| 180 | 178 | ||
| 181 | return ret; | 179 | return ret; |
| @@ -190,7 +188,7 @@ SrsTcpListener::SrsTcpListener(ISrsTcpHandler* h, string i, int p) | @@ -190,7 +188,7 @@ SrsTcpListener::SrsTcpListener(ISrsTcpHandler* h, string i, int p) | ||
| 190 | _fd = -1; | 188 | _fd = -1; |
| 191 | _stfd = NULL; | 189 | _stfd = NULL; |
| 192 | 190 | ||
| 193 | - pthread = new SrsThread("tcp", this, 0, true); | 191 | + pthread = new SrsReusableThread("tcp", this); |
| 194 | } | 192 | } |
| 195 | 193 | ||
| 196 | SrsTcpListener::~SrsTcpListener() | 194 | SrsTcpListener::~SrsTcpListener() |
| @@ -82,12 +82,12 @@ public: | @@ -82,12 +82,12 @@ public: | ||
| 82 | /** | 82 | /** |
| 83 | * bind udp port, start thread to recv packet and handler it. | 83 | * bind udp port, start thread to recv packet and handler it. |
| 84 | */ | 84 | */ |
| 85 | -class SrsUdpListener : public ISrsThreadHandler | 85 | +class SrsUdpListener : public ISrsReusableThreadHandler |
| 86 | { | 86 | { |
| 87 | private: | 87 | private: |
| 88 | int _fd; | 88 | int _fd; |
| 89 | st_netfd_t _stfd; | 89 | st_netfd_t _stfd; |
| 90 | - SrsThread* pthread; | 90 | + SrsReusableThread* pthread; |
| 91 | private: | 91 | private: |
| 92 | char* buf; | 92 | char* buf; |
| 93 | int nb_buf; | 93 | int nb_buf; |
| @@ -103,7 +103,7 @@ public: | @@ -103,7 +103,7 @@ public: | ||
| 103 | virtual st_netfd_t stfd(); | 103 | virtual st_netfd_t stfd(); |
| 104 | public: | 104 | public: |
| 105 | virtual int listen(); | 105 | virtual int listen(); |
| 106 | -// interface ISrsThreadHandler. | 106 | +// interface ISrsReusableThreadHandler. |
| 107 | public: | 107 | public: |
| 108 | virtual int cycle(); | 108 | virtual int cycle(); |
| 109 | }; | 109 | }; |
| @@ -111,12 +111,12 @@ public: | @@ -111,12 +111,12 @@ public: | ||
| 111 | /** | 111 | /** |
| 112 | * bind and listen tcp port, use handler to process the client. | 112 | * bind and listen tcp port, use handler to process the client. |
| 113 | */ | 113 | */ |
| 114 | -class SrsTcpListener : public ISrsThreadHandler | 114 | +class SrsTcpListener : public ISrsReusableThreadHandler |
| 115 | { | 115 | { |
| 116 | private: | 116 | private: |
| 117 | int _fd; | 117 | int _fd; |
| 118 | st_netfd_t _stfd; | 118 | st_netfd_t _stfd; |
| 119 | - SrsThread* pthread; | 119 | + SrsReusableThread* pthread; |
| 120 | private: | 120 | private: |
| 121 | ISrsTcpHandler* handler; | 121 | ISrsTcpHandler* handler; |
| 122 | std::string ip; | 122 | std::string ip; |
| @@ -128,7 +128,7 @@ public: | @@ -128,7 +128,7 @@ public: | ||
| 128 | virtual int fd(); | 128 | virtual int fd(); |
| 129 | public: | 129 | public: |
| 130 | virtual int listen(); | 130 | virtual int listen(); |
| 131 | -// interface ISrsThreadHandler. | 131 | +// interface ISrsReusableThreadHandler. |
| 132 | public: | 132 | public: |
| 133 | virtual int cycle(); | 133 | virtual int cycle(); |
| 134 | }; | 134 | }; |
| @@ -82,7 +82,7 @@ public: | @@ -82,7 +82,7 @@ public: | ||
| 82 | virtual void trace(const char* tag, int context_id, const char* fmt, ...); | 82 | virtual void trace(const char* tag, int context_id, const char* fmt, ...); |
| 83 | virtual void warn(const char* tag, int context_id, const char* fmt, ...); | 83 | virtual void warn(const char* tag, int context_id, const char* fmt, ...); |
| 84 | virtual void error(const char* tag, int context_id, const char* fmt, ...); | 84 | virtual void error(const char* tag, int context_id, const char* fmt, ...); |
| 85 | -// interface ISrsThreadHandler. | 85 | +// interface ISrsReloadHandler. |
| 86 | public: | 86 | public: |
| 87 | virtual int on_reload_log_tank(); | 87 | virtual int on_reload_log_tank(); |
| 88 | virtual int on_reload_log_level(); | 88 | virtual int on_reload_log_level(); |
| @@ -50,7 +50,7 @@ SrsRecvThread::SrsRecvThread(ISrsMessageHandler* msg_handler, SrsRtmpServer* rtm | @@ -50,7 +50,7 @@ SrsRecvThread::SrsRecvThread(ISrsMessageHandler* msg_handler, SrsRtmpServer* rtm | ||
| 50 | timeout = timeout_ms; | 50 | timeout = timeout_ms; |
| 51 | handler = msg_handler; | 51 | handler = msg_handler; |
| 52 | rtmp = rtmp_sdk; | 52 | rtmp = rtmp_sdk; |
| 53 | - trd = new SrsThread("recv", this, 0, true); | 53 | + trd = new SrsReusableThread2("recv", this); |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | SrsRecvThread::~SrsRecvThread() | 56 | SrsRecvThread::~SrsRecvThread() |
| @@ -72,11 +72,16 @@ void SrsRecvThread::stop() | @@ -72,11 +72,16 @@ void SrsRecvThread::stop() | ||
| 72 | trd->stop(); | 72 | trd->stop(); |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | +void SrsRecvThread::stop_loop() | ||
| 76 | +{ | ||
| 77 | + trd->interrupt(); | ||
| 78 | +} | ||
| 79 | + | ||
| 75 | int SrsRecvThread::cycle() | 80 | int SrsRecvThread::cycle() |
| 76 | { | 81 | { |
| 77 | int ret = ERROR_SUCCESS; | 82 | int ret = ERROR_SUCCESS; |
| 78 | 83 | ||
| 79 | - while (trd->can_loop()) { | 84 | + while (!trd->interrupted()) { |
| 80 | if (!handler->can_handle()) { | 85 | if (!handler->can_handle()) { |
| 81 | st_usleep(timeout * 1000); | 86 | st_usleep(timeout * 1000); |
| 82 | continue; | 87 | continue; |
| @@ -96,7 +101,7 @@ int SrsRecvThread::cycle() | @@ -96,7 +101,7 @@ int SrsRecvThread::cycle() | ||
| 96 | } | 101 | } |
| 97 | 102 | ||
| 98 | // we use no timeout to recv, should never got any error. | 103 | // we use no timeout to recv, should never got any error. |
| 99 | - trd->stop_loop(); | 104 | + trd->interrupt(); |
| 100 | 105 | ||
| 101 | // notice the handler got a recv error. | 106 | // notice the handler got a recv error. |
| 102 | handler->on_recv_error(ret); | 107 | handler->on_recv_error(ret); |
| @@ -109,11 +114,6 @@ int SrsRecvThread::cycle() | @@ -109,11 +114,6 @@ int SrsRecvThread::cycle() | ||
| 109 | return ret; | 114 | return ret; |
| 110 | } | 115 | } |
| 111 | 116 | ||
| 112 | -void SrsRecvThread::stop_loop() | ||
| 113 | -{ | ||
| 114 | - trd->stop_loop(); | ||
| 115 | -} | ||
| 116 | - | ||
| 117 | void SrsRecvThread::on_thread_start() | 117 | void SrsRecvThread::on_thread_start() |
| 118 | { | 118 | { |
| 119 | // the multiple messages writev improve performance large, | 119 | // the multiple messages writev improve performance large, |
| @@ -79,10 +79,10 @@ public: | @@ -79,10 +79,10 @@ public: | ||
| 79 | /** | 79 | /** |
| 80 | * the recv thread, use message handler to handle each received message. | 80 | * the recv thread, use message handler to handle each received message. |
| 81 | */ | 81 | */ |
| 82 | -class SrsRecvThread : public ISrsThreadHandler | 82 | +class SrsRecvThread : public ISrsReusableThread2Handler |
| 83 | { | 83 | { |
| 84 | protected: | 84 | protected: |
| 85 | - SrsThread* trd; | 85 | + SrsReusableThread2* trd; |
| 86 | ISrsMessageHandler* handler; | 86 | ISrsMessageHandler* handler; |
| 87 | SrsRtmpServer* rtmp; | 87 | SrsRtmpServer* rtmp; |
| 88 | int timeout; | 88 | int timeout; |
| @@ -92,9 +92,10 @@ public: | @@ -92,9 +92,10 @@ public: | ||
| 92 | public: | 92 | public: |
| 93 | virtual int start(); | 93 | virtual int start(); |
| 94 | virtual void stop(); | 94 | virtual void stop(); |
| 95 | - virtual int cycle(); | ||
| 96 | virtual void stop_loop(); | 95 | virtual void stop_loop(); |
| 96 | +// interface ISrsReusableThread2Handler | ||
| 97 | public: | 97 | public: |
| 98 | + virtual int cycle(); | ||
| 98 | virtual void on_thread_start(); | 99 | virtual void on_thread_start(); |
| 99 | virtual void on_thread_stop(); | 100 | virtual void on_thread_stop(); |
| 100 | }; | 101 | }; |
| @@ -41,7 +41,6 @@ using namespace std; | @@ -41,7 +41,6 @@ using namespace std; | ||
| 41 | #include <srs_app_config.hpp> | 41 | #include <srs_app_config.hpp> |
| 42 | #include <srs_app_refer.hpp> | 42 | #include <srs_app_refer.hpp> |
| 43 | #include <srs_app_hls.hpp> | 43 | #include <srs_app_hls.hpp> |
| 44 | -#include <srs_app_http.hpp> | ||
| 45 | #include <srs_app_bandwidth.hpp> | 44 | #include <srs_app_bandwidth.hpp> |
| 46 | #include <srs_app_st_socket.hpp> | 45 | #include <srs_app_st_socket.hpp> |
| 47 | #include <srs_app_http_hooks.hpp> | 46 | #include <srs_app_http_hooks.hpp> |
| @@ -192,7 +192,7 @@ SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o) | @@ -192,7 +192,7 @@ SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o) | ||
| 192 | stfd = fd; | 192 | stfd = fd; |
| 193 | skt = new SrsStSocket(fd); | 193 | skt = new SrsStSocket(fd); |
| 194 | rtsp = new SrsRtspStack(skt); | 194 | rtsp = new SrsRtspStack(skt); |
| 195 | - trd = new SrsThread("rtsp", this, 0, false); | 195 | + trd = new SrsOneCycleThread("rtsp", this); |
| 196 | 196 | ||
| 197 | req = NULL; | 197 | req = NULL; |
| 198 | io = NULL; | 198 | io = NULL; |
| @@ -210,7 +210,6 @@ SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o) | @@ -210,7 +210,6 @@ SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o) | ||
| 210 | SrsRtspConn::~SrsRtspConn() | 210 | SrsRtspConn::~SrsRtspConn() |
| 211 | { | 211 | { |
| 212 | srs_close_stfd(stfd); | 212 | srs_close_stfd(stfd); |
| 213 | - trd->stop(); | ||
| 214 | 213 | ||
| 215 | srs_freep(video_rtp); | 214 | srs_freep(video_rtp); |
| 216 | srs_freep(audio_rtp); | 215 | srs_freep(audio_rtp); |
| @@ -219,7 +218,9 @@ SrsRtspConn::~SrsRtspConn() | @@ -219,7 +218,9 @@ SrsRtspConn::~SrsRtspConn() | ||
| 219 | srs_freep(skt); | 218 | srs_freep(skt); |
| 220 | srs_freep(rtsp); | 219 | srs_freep(rtsp); |
| 221 | 220 | ||
| 222 | - close(); | 221 | + srs_freep(client); |
| 222 | + srs_freep(io); | ||
| 223 | + srs_freep(req); | ||
| 223 | 224 | ||
| 224 | srs_freep(vjitter); | 225 | srs_freep(vjitter); |
| 225 | srs_freep(ajitter); | 226 | srs_freep(ajitter); |
| @@ -412,9 +413,6 @@ int SrsRtspConn::cycle() | @@ -412,9 +413,6 @@ int SrsRtspConn::cycle() | ||
| 412 | srs_warn("client disconnect peer. ret=%d", ret); | 413 | srs_warn("client disconnect peer. ret=%d", ret); |
| 413 | } | 414 | } |
| 414 | 415 | ||
| 415 | - // terminate thread in the thread cycle itself. | ||
| 416 | - trd->stop_loop(); | ||
| 417 | - | ||
| 418 | return ERROR_SUCCESS; | 416 | return ERROR_SUCCESS; |
| 419 | } | 417 | } |
| 420 | 418 | ||
| @@ -763,14 +761,6 @@ int SrsRtspConn::connect_app(string ep_server, string ep_port) | @@ -763,14 +761,6 @@ int SrsRtspConn::connect_app(string ep_server, string ep_port) | ||
| 763 | return ret; | 761 | return ret; |
| 764 | } | 762 | } |
| 765 | 763 | ||
| 766 | -void SrsRtspConn::close() | ||
| 767 | -{ | ||
| 768 | - srs_freep(client); | ||
| 769 | - srs_freep(io); | ||
| 770 | - srs_freep(req); | ||
| 771 | - srs_close_stfd(stfd); | ||
| 772 | -} | ||
| 773 | - | ||
| 774 | SrsRtspCaster::SrsRtspCaster(SrsConfDirective* c) | 764 | SrsRtspCaster::SrsRtspCaster(SrsConfDirective* c) |
| 775 | { | 765 | { |
| 776 | // TODO: FIXME: support reload. | 766 | // TODO: FIXME: support reload. |
| @@ -113,7 +113,7 @@ public: | @@ -113,7 +113,7 @@ public: | ||
| 113 | /** | 113 | /** |
| 114 | * the rtsp connection serve the fd. | 114 | * the rtsp connection serve the fd. |
| 115 | */ | 115 | */ |
| 116 | -class SrsRtspConn : public ISrsThreadHandler | 116 | +class SrsRtspConn : public ISrsOneCycleThreadHandler |
| 117 | { | 117 | { |
| 118 | private: | 118 | private: |
| 119 | std::string output_template; | 119 | std::string output_template; |
| @@ -136,7 +136,7 @@ private: | @@ -136,7 +136,7 @@ private: | ||
| 136 | SrsStSocket* skt; | 136 | SrsStSocket* skt; |
| 137 | SrsRtspStack* rtsp; | 137 | SrsRtspStack* rtsp; |
| 138 | SrsRtspCaster* caster; | 138 | SrsRtspCaster* caster; |
| 139 | - SrsThread* trd; | 139 | + SrsOneCycleThread* trd; |
| 140 | private: | 140 | private: |
| 141 | SrsRequest* req; | 141 | SrsRequest* req; |
| 142 | SrsStSocket* io; | 142 | SrsStSocket* io; |
| @@ -163,7 +163,7 @@ private: | @@ -163,7 +163,7 @@ private: | ||
| 163 | // internal methods | 163 | // internal methods |
| 164 | public: | 164 | public: |
| 165 | virtual int on_rtp_packet(SrsRtpPacket* pkt, int stream_id); | 165 | virtual int on_rtp_packet(SrsRtpPacket* pkt, int stream_id); |
| 166 | -// interface ISrsThreadHandler | 166 | +// interface ISrsOneCycleThreadHandler |
| 167 | public: | 167 | public: |
| 168 | virtual int cycle(); | 168 | virtual int cycle(); |
| 169 | virtual void on_thread_stop(); | 169 | virtual void on_thread_stop(); |
| @@ -182,8 +182,6 @@ private: | @@ -182,8 +182,6 @@ private: | ||
| 182 | // @remark ignore when not connected, reconnect when disconnected. | 182 | // @remark ignore when not connected, reconnect when disconnected. |
| 183 | virtual int connect(); | 183 | virtual int connect(); |
| 184 | virtual int connect_app(std::string ep_server, std::string ep_port); | 184 | virtual int connect_app(std::string ep_server, std::string ep_port); |
| 185 | - // close the connected io and rtmp to ready to be re-connect. | ||
| 186 | - virtual void close(); | ||
| 187 | }; | 185 | }; |
| 188 | 186 | ||
| 189 | /** | 187 | /** |
| @@ -367,13 +367,12 @@ SrsSignalManager::SrsSignalManager(SrsServer* server) | @@ -367,13 +367,12 @@ SrsSignalManager::SrsSignalManager(SrsServer* server) | ||
| 367 | 367 | ||
| 368 | _server = server; | 368 | _server = server; |
| 369 | sig_pipe[0] = sig_pipe[1] = -1; | 369 | sig_pipe[0] = sig_pipe[1] = -1; |
| 370 | - pthread = new SrsThread("signal", this, 0, true); | 370 | + pthread = new SrsEndlessThread("signal", this); |
| 371 | signal_read_stfd = NULL; | 371 | signal_read_stfd = NULL; |
| 372 | } | 372 | } |
| 373 | 373 | ||
| 374 | SrsSignalManager::~SrsSignalManager() | 374 | SrsSignalManager::~SrsSignalManager() |
| 375 | { | 375 | { |
| 376 | - pthread->stop(); | ||
| 377 | srs_freep(pthread); | 376 | srs_freep(pthread); |
| 378 | 377 | ||
| 379 | srs_close_stfd(signal_read_stfd); | 378 | srs_close_stfd(signal_read_stfd); |
| @@ -179,7 +179,7 @@ public: | @@ -179,7 +179,7 @@ public: | ||
| 179 | * convert signal to io, | 179 | * convert signal to io, |
| 180 | * @see: st-1.9/docs/notes.html | 180 | * @see: st-1.9/docs/notes.html |
| 181 | */ | 181 | */ |
| 182 | -class SrsSignalManager : public ISrsThreadHandler | 182 | +class SrsSignalManager : public ISrsEndlessThreadHandler |
| 183 | { | 183 | { |
| 184 | private: | 184 | private: |
| 185 | /* Per-process pipe which is used as a signal queue. */ | 185 | /* Per-process pipe which is used as a signal queue. */ |
| @@ -188,14 +188,14 @@ private: | @@ -188,14 +188,14 @@ private: | ||
| 188 | st_netfd_t signal_read_stfd; | 188 | st_netfd_t signal_read_stfd; |
| 189 | private: | 189 | private: |
| 190 | SrsServer* _server; | 190 | SrsServer* _server; |
| 191 | - SrsThread* pthread; | 191 | + SrsEndlessThread* pthread; |
| 192 | public: | 192 | public: |
| 193 | SrsSignalManager(SrsServer* server); | 193 | SrsSignalManager(SrsServer* server); |
| 194 | virtual ~SrsSignalManager(); | 194 | virtual ~SrsSignalManager(); |
| 195 | public: | 195 | public: |
| 196 | virtual int initialize(); | 196 | virtual int initialize(); |
| 197 | virtual int start(); | 197 | virtual int start(); |
| 198 | -// interface ISrsThreadHandler. | 198 | +// interface ISrsEndlessThreadHandler. |
| 199 | public: | 199 | public: |
| 200 | virtual int cycle(); | 200 | virtual int cycle(); |
| 201 | private: | 201 | private: |
| @@ -167,6 +167,7 @@ public: | @@ -167,6 +167,7 @@ public: | ||
| 167 | * sample the kbps, add delta bytes of conn. | 167 | * sample the kbps, add delta bytes of conn. |
| 168 | * use kbps_sample() to get all result of kbps stat. | 168 | * use kbps_sample() to get all result of kbps stat. |
| 169 | */ | 169 | */ |
| 170 | + // TODO: FIXME: the add delta must use IKbpsDelta interface instead. | ||
| 170 | virtual void kbps_add_delta(SrsConnection* conn); | 171 | virtual void kbps_add_delta(SrsConnection* conn); |
| 171 | /** | 172 | /** |
| 172 | * calc the result for all kbps. | 173 | * calc the result for all kbps. |
-
请 注册 或 登录 后发表评论