winlin

Merge branch '2.0release' into develop

要显示太多修改。

为保证性能只显示 42 of 42+ 个文件。

@@ -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;
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.