正在显示
24 个修改的文件
包含
307 行增加
和
96 行删除
@@ -217,6 +217,7 @@ usr sys idl wai hiq siq| read writ| recv send| in out | int csw | @@ -217,6 +217,7 @@ usr sys idl wai hiq siq| read writ| recv send| in out | int csw | ||
217 | * nginx v1.5.0: 139524 lines <br/> | 217 | * nginx v1.5.0: 139524 lines <br/> |
218 | 218 | ||
219 | ## History | 219 | ## History |
220 | +* v1.0, 2014-04-05, support [http api](https://github.com/winlinvip/simple-rtmp-server/wiki/HTTPApi) and [http server](https://github.com/winlinvip/simple-rtmp-server/wiki/HTTPServer). | ||
220 | * v1.0, 2014-04-03, implements http framework and api/v1/version. | 221 | * v1.0, 2014-04-03, implements http framework and api/v1/version. |
221 | * v1.0, 2014-03-30, fix bug for st detecting epoll failed, force st to use epoll. | 222 | * v1.0, 2014-03-30, fix bug for st detecting epoll failed, force st to use epoll. |
222 | * v1.0, 2014-03-29, add wiki [Performance for RaspberryPi](https://github.com/winlinvip/simple-rtmp-server/wiki/RaspberryPi). | 223 | * v1.0, 2014-03-29, add wiki [Performance for RaspberryPi](https://github.com/winlinvip/simple-rtmp-server/wiki/RaspberryPi). |
@@ -31,6 +31,7 @@ echo "depends tools are ok" | @@ -31,6 +31,7 @@ echo "depends tools are ok" | ||
31 | ##################################################################################### | 31 | ##################################################################################### |
32 | # for Ubuntu, auto install tools by apt-get | 32 | # for Ubuntu, auto install tools by apt-get |
33 | ##################################################################################### | 33 | ##################################################################################### |
34 | +OS_IS_UBUNTU=NO | ||
34 | function Ubuntu_prepare() | 35 | function Ubuntu_prepare() |
35 | { | 36 | { |
36 | uname -v|grep Ubuntu >/dev/null 2>&1 | 37 | uname -v|grep Ubuntu >/dev/null 2>&1 |
@@ -38,6 +39,7 @@ function Ubuntu_prepare() | @@ -38,6 +39,7 @@ function Ubuntu_prepare() | ||
38 | return 0; | 39 | return 0; |
39 | fi | 40 | fi |
40 | 41 | ||
42 | + OS_IS_UBUNTU=YES | ||
41 | echo "Ubuntu detected, install tools if needed" | 43 | echo "Ubuntu detected, install tools if needed" |
42 | 44 | ||
43 | gcc --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then | 45 | gcc --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then |
@@ -113,12 +115,14 @@ Ubuntu_prepare; ret=$?; if [[ 0 -ne $ret ]]; then echo "Ubuntu prepare failed, r | @@ -113,12 +115,14 @@ Ubuntu_prepare; ret=$?; if [[ 0 -ne $ret ]]; then echo "Ubuntu prepare failed, r | ||
113 | ##################################################################################### | 115 | ##################################################################################### |
114 | # for Centos, auto install tools by yum | 116 | # for Centos, auto install tools by yum |
115 | ##################################################################################### | 117 | ##################################################################################### |
118 | +OS_IS_CENTOS=NO | ||
116 | function Centos_prepare() | 119 | function Centos_prepare() |
117 | { | 120 | { |
118 | if [[ ! -f /etc/redhat-release ]]; then | 121 | if [[ ! -f /etc/redhat-release ]]; then |
119 | return 0; | 122 | return 0; |
120 | fi | 123 | fi |
121 | 124 | ||
125 | + OS_IS_CENTOS=YES | ||
122 | echo "Centos detected, install tools if needed" | 126 | echo "Centos detected, install tools if needed" |
123 | 127 | ||
124 | gcc --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then | 128 | gcc --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then |
@@ -315,6 +319,9 @@ function write_nginx_html5() | @@ -315,6 +319,9 @@ function write_nginx_html5() | ||
315 | </video> | 319 | </video> |
316 | END | 320 | END |
317 | } | 321 | } |
322 | +# create the nginx dir, for http-server if not build nginx | ||
323 | +mkdir -p ${SRS_OBJS}/nginx | ||
324 | +# make nginx | ||
318 | __SRS_BUILD_NGINX=NO; if [ $SRS_ARM_UBUNTU12 = NO ]; then if [ $SRS_NGINX = YES ]; then __SRS_BUILD_NGINX=YES; fi fi | 325 | __SRS_BUILD_NGINX=NO; if [ $SRS_ARM_UBUNTU12 = NO ]; then if [ $SRS_NGINX = YES ]; then __SRS_BUILD_NGINX=YES; fi fi |
319 | if [ $__SRS_BUILD_NGINX = YES ]; then | 326 | if [ $__SRS_BUILD_NGINX = YES ]; then |
320 | if [[ -f ${SRS_OBJS}/nginx/sbin/nginx ]]; then | 327 | if [[ -f ${SRS_OBJS}/nginx/sbin/nginx ]]; then |
@@ -337,29 +344,29 @@ if [ $__SRS_BUILD_NGINX = YES ]; then | @@ -337,29 +344,29 @@ if [ $__SRS_BUILD_NGINX = YES ]; then | ||
337 | # nginx default use nobody, so cannot read the ts/m3u8 created by srs. | 344 | # nginx default use nobody, so cannot read the ts/m3u8 created by srs. |
338 | cp ${SRS_OBJS}/nginx/conf/nginx.conf ${SRS_OBJS}/nginx/conf/nginx.conf.bk | 345 | cp ${SRS_OBJS}/nginx/conf/nginx.conf ${SRS_OBJS}/nginx/conf/nginx.conf.bk |
339 | sed -i "s/^.user nobody;/user `whoami`;/g" ${SRS_OBJS}/nginx/conf/nginx.conf | 346 | sed -i "s/^.user nobody;/user `whoami`;/g" ${SRS_OBJS}/nginx/conf/nginx.conf |
340 | - | ||
341 | - # create forward dir | ||
342 | - mkdir -p ${SRS_OBJS}/nginx/html/live && | ||
343 | - mkdir -p ${SRS_OBJS}/nginx/html/forward/live | ||
344 | - | ||
345 | - # generate default html pages for android. | ||
346 | - html_file=${SRS_OBJS}/nginx/html/live/livestream.html && hls_stream=livestream.m3u8 && write_nginx_html5 | ||
347 | - html_file=${SRS_OBJS}/nginx/html/live/livestream_ld.html && hls_stream=livestream_ld.m3u8 && write_nginx_html5 | ||
348 | - html_file=${SRS_OBJS}/nginx/html/live/livestream_sd.html && hls_stream=livestream_sd.m3u8 && write_nginx_html5 | ||
349 | - html_file=${SRS_OBJS}/nginx/html/forward/live/livestream.html && hls_stream=livestream.m3u8 && write_nginx_html5 | ||
350 | - html_file=${SRS_OBJS}/nginx/html/forward/live/livestream_ld.html && hls_stream=livestream_ld.m3u8 && write_nginx_html5 | ||
351 | - html_file=${SRS_OBJS}/nginx/html/forward/live/livestream_sd.html && hls_stream=livestream_sd.m3u8 && write_nginx_html5 | ||
352 | - | ||
353 | - # copy players to nginx html dir. | ||
354 | - rm -rf ${SRS_OBJS}/nginx/html/players && | ||
355 | - ln -sf `pwd`/research/players ${SRS_OBJS}/nginx/html/players && | ||
356 | - rm -f ${SRS_OBJS}/nginx/crossdomain.xml && | ||
357 | - ln -sf `pwd`/research/players/crossdomain.xml ${SRS_OBJS}/nginx/html/crossdomain.xml | ||
358 | - | ||
359 | - # nginx.html to detect whether nginx is alive | ||
360 | - echo "nginx is ok" > ${SRS_OBJS}/nginx/html/nginx.html | ||
361 | fi | 347 | fi |
362 | 348 | ||
349 | +# create forward dir | ||
350 | +mkdir -p ${SRS_OBJS}/nginx/html/live && | ||
351 | +mkdir -p ${SRS_OBJS}/nginx/html/forward/live | ||
352 | + | ||
353 | +# generate default html pages for android. | ||
354 | +html_file=${SRS_OBJS}/nginx/html/live/livestream.html && hls_stream=livestream.m3u8 && write_nginx_html5 | ||
355 | +html_file=${SRS_OBJS}/nginx/html/live/livestream_ld.html && hls_stream=livestream_ld.m3u8 && write_nginx_html5 | ||
356 | +html_file=${SRS_OBJS}/nginx/html/live/livestream_sd.html && hls_stream=livestream_sd.m3u8 && write_nginx_html5 | ||
357 | +html_file=${SRS_OBJS}/nginx/html/forward/live/livestream.html && hls_stream=livestream.m3u8 && write_nginx_html5 | ||
358 | +html_file=${SRS_OBJS}/nginx/html/forward/live/livestream_ld.html && hls_stream=livestream_ld.m3u8 && write_nginx_html5 | ||
359 | +html_file=${SRS_OBJS}/nginx/html/forward/live/livestream_sd.html && hls_stream=livestream_sd.m3u8 && write_nginx_html5 | ||
360 | + | ||
361 | +# copy players to nginx html dir. | ||
362 | +rm -rf ${SRS_OBJS}/nginx/html/players && | ||
363 | +ln -sf `pwd`/research/players ${SRS_OBJS}/nginx/html/players && | ||
364 | +rm -f ${SRS_OBJS}/nginx/crossdomain.xml && | ||
365 | +ln -sf `pwd`/research/players/crossdomain.xml ${SRS_OBJS}/nginx/html/crossdomain.xml | ||
366 | + | ||
367 | +# nginx.html to detect whether nginx is alive | ||
368 | +echo "nginx is ok" > ${SRS_OBJS}/nginx/html/nginx.html | ||
369 | + | ||
363 | if [ $SRS_NGINX = YES ]; then | 370 | if [ $SRS_NGINX = YES ]; then |
364 | echo "#define SRS_NGINX" >> $SRS_AUTO_HEADERS_H | 371 | echo "#define SRS_NGINX" >> $SRS_AUTO_HEADERS_H |
365 | else | 372 | else |
@@ -411,31 +418,23 @@ mkdir -p `pwd`/${SRS_OBJS}/nginx/html/forward && | @@ -411,31 +418,23 @@ mkdir -p `pwd`/${SRS_OBJS}/nginx/html/forward && | ||
411 | ln -sf `pwd`/${SRS_OBJS}/nginx/html/forward research/api-server/static-dir/forward | 418 | ln -sf `pwd`/${SRS_OBJS}/nginx/html/forward research/api-server/static-dir/forward |
412 | ret=$?; if [[ $ret -ne 0 ]]; then echo "link players to cherrypy static-dir failed, ret=$ret"; exit $ret; fi | 419 | ret=$?; if [[ $ret -ne 0 ]]; then echo "link players to cherrypy static-dir failed, ret=$ret"; exit $ret; fi |
413 | 420 | ||
414 | -# only when the nginx is ok, | ||
415 | -# if api-server not enalbed, use nginx as demo. | 421 | +##################################################################################### |
422 | +# generate demo index.html | ||
423 | +##################################################################################### | ||
424 | +# if nginx enalbed, generate nginx index file. | ||
416 | if [ $__SRS_BUILD_NGINX = YES ]; then | 425 | if [ $__SRS_BUILD_NGINX = YES ]; then |
417 | - if [ $SRS_HTTP_CALLBACK = YES ]; then | ||
418 | - # override the default index. | ||
419 | - rm -f ${SRS_OBJS}/nginx/html/index.html && | ||
420 | - ln -sf `pwd`/research/players/nginx_index.html ${SRS_OBJS}/nginx/html/index.html | ||
421 | - else | ||
422 | - rm -f ${SRS_OBJS}/nginx/html/index.html && | ||
423 | - cat<<END > ${SRS_OBJS}/nginx/html/index.html | ||
424 | -<!DOCTYPE html> | ||
425 | -<html> | ||
426 | -<head> | ||
427 | - <title>SRS</title> | ||
428 | - <meta charset="utf-8"> | ||
429 | -</head> | ||
430 | -<body> | ||
431 | - <script type="text/javascript"> | ||
432 | - setTimeout(function(){ | ||
433 | - window.location.href = "players/index.html" + window.location.search; | ||
434 | - }, 500); | ||
435 | - </script> | ||
436 | -</body> | ||
437 | -END | ||
438 | - fi | 426 | + rm -f ${SRS_OBJS}/nginx/html/index.html && |
427 | + ln -sf `pwd`/research/players/nginx_index.html ${SRS_OBJS}/nginx/html/index.html | ||
428 | +fi | ||
429 | +# if http-server enalbed, use srs embeded http-server | ||
430 | +if [ $SRS_HTTP_SERVER = YES ]; then | ||
431 | + rm -f ${SRS_OBJS}/nginx/html/index.html && | ||
432 | + ln -sf `pwd`/research/players/srs-http-server_index.html ${SRS_OBJS}/nginx/html/index.html | ||
433 | +fi | ||
434 | +# if api-server enabled, generate for api server. | ||
435 | +if [ $SRS_HTTP_CALLBACK = YES ]; then | ||
436 | + rm -f ${SRS_OBJS}/nginx/html/index.html && | ||
437 | + ln -sf `pwd`/research/players/api-server_index.html ${SRS_OBJS}/nginx/html/index.html | ||
439 | fi | 438 | fi |
440 | 439 | ||
441 | ##################################################################################### | 440 | ##################################################################################### |
@@ -603,7 +602,11 @@ echo "" >> $SRS_AUTO_HEADERS_H | @@ -603,7 +602,11 @@ echo "" >> $SRS_AUTO_HEADERS_H | ||
603 | ##################################################################################### | 602 | ##################################################################################### |
604 | # generated the contributors from AUTHORS.txt | 603 | # generated the contributors from AUTHORS.txt |
605 | ##################################################################################### | 604 | ##################################################################################### |
606 | -SRS_CONSTRIBUTORS=`cat ../AUTHORS.txt|grep "*"|awk -F '\* ' '{print $2}'` | 605 | +if [ $OS_IS_CENTOS = YES ]; then |
606 | + SRS_CONSTRIBUTORS=`cat ../AUTHORS.txt|grep "*"|awk -F '* ' '{print $2}'` | ||
607 | +else | ||
608 | + SRS_CONSTRIBUTORS=`cat ../AUTHORS.txt|grep "*"|awk -F '\* ' '{print $2}'` | ||
609 | +fi | ||
607 | echo "#define SRS_CONSTRIBUTORS \"\\" >> $SRS_AUTO_HEADERS_H | 610 | echo "#define SRS_CONSTRIBUTORS \"\\" >> $SRS_AUTO_HEADERS_H |
608 | for CONTRIBUTOR in $SRS_CONSTRIBUTORS; do | 611 | for CONTRIBUTOR in $SRS_CONSTRIBUTORS; do |
609 | echo "${CONTRIBUTOR} \\" >> $SRS_AUTO_HEADERS_H | 612 | echo "${CONTRIBUTOR} \\" >> $SRS_AUTO_HEADERS_H |
@@ -168,12 +168,12 @@ if [ $SRS_DEV = YES ]; then | @@ -168,12 +168,12 @@ if [ $SRS_DEV = YES ]; then | ||
168 | SRS_NGINX=YES | 168 | SRS_NGINX=YES |
169 | SRS_SSL=YES | 169 | SRS_SSL=YES |
170 | SRS_FFMPEG=YES | 170 | SRS_FFMPEG=YES |
171 | - SRS_HTTP_CALLBACK=YES | 171 | + if [ $SRS_HTTP_CALLBACK = RESERVED ]; then SRS_HTTP_CALLBACK=YES; fi |
172 | SRS_HTTP_SERVER=YES | 172 | SRS_HTTP_SERVER=YES |
173 | SRS_HTTP_API=YES | 173 | SRS_HTTP_API=YES |
174 | SRS_LIBRTMP=YES | 174 | SRS_LIBRTMP=YES |
175 | - SRS_BWTC=YES | ||
176 | - SRS_RESEARCH=YES | 175 | + if [ $SRS_BWTC = RESERVED ]; then SRS_BWTC=YES; fi |
176 | + if [ $SRS_RESEARCH = RESERVED ]; then SRS_RESEARCH=YES; fi | ||
177 | SRS_UTEST=YES | 177 | SRS_UTEST=YES |
178 | if [ $SRS_GPERF = RESERVED ]; then SRS_GPERF=NO; fi | 178 | if [ $SRS_GPERF = RESERVED ]; then SRS_GPERF=NO; fi |
179 | if [ $SRS_GPERF_MC = RESERVED ]; then SRS_GPERF_MC=NO; fi | 179 | if [ $SRS_GPERF_MC = RESERVED ]; then SRS_GPERF_MC=NO; fi |
trunk/research/players/api-server_index.html
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | +<head> | ||
4 | + <title>SRS</title> | ||
5 | + <meta charset="utf-8"> | ||
6 | + <script type="text/javascript" src="players/js/jquery-1.10.2.min.js"></script> | ||
7 | + <script type="text/javascript" src="players/js/srs.page.js"></script> | ||
8 | + <script type="text/javascript" src="players/js/srs.utility.js"></script> | ||
9 | +</head> | ||
10 | +<body> | ||
11 | + <script type="text/javascript"> | ||
12 | + setTimeout(function(){ | ||
13 | + window.location.href = "players/index.html" + window.location.search; | ||
14 | + }, 500); | ||
15 | + </script> | ||
16 | +</body> |
trunk/research/players/index.html
100755 → 100644
@@ -15,6 +15,8 @@ function srs_get_version_code() { return "1.19"; } | @@ -15,6 +15,8 @@ function srs_get_version_code() { return "1.19"; } | ||
15 | function srs_get_player_vhost() { return "players"; } | 15 | function srs_get_player_vhost() { return "players"; } |
16 | // the api server port, for chat room. | 16 | // the api server port, for chat room. |
17 | function srs_get_api_server_port() { return 8085; } | 17 | function srs_get_api_server_port() { return 8085; } |
18 | +// the srs http server port | ||
19 | +function srs_get_srs_http_server_port() { return 8080; } | ||
18 | // get the stream published to vhost, | 20 | // get the stream published to vhost, |
19 | // generally we need to transcode the stream to support HLS and filters. | 21 | // generally we need to transcode the stream to support HLS and filters. |
20 | // for example, src_vhost is "players", we transcode stream to vhost "players_pub". | 22 | // for example, src_vhost is "players", we transcode stream to vhost "players_pub". |
trunk/research/players/jwplayer6.html
100755 → 100644
trunk/research/players/nginx_index.html
100755 → 100644
@@ -3,19 +3,11 @@ | @@ -3,19 +3,11 @@ | ||
3 | <head> | 3 | <head> |
4 | <title>SRS</title> | 4 | <title>SRS</title> |
5 | <meta charset="utf-8"> | 5 | <meta charset="utf-8"> |
6 | - <script type="text/javascript" src="players/js/jquery-1.10.2.min.js"></script> | ||
7 | - <script type="text/javascript" src="players/js/srs.page.js"></script> | ||
8 | - <script type="text/javascript" src="players/js/srs.utility.js"></script> | ||
9 | </head> | 6 | </head> |
10 | <body> | 7 | <body> |
11 | <script type="text/javascript"> | 8 | <script type="text/javascript"> |
12 | - var query = parse_query_string(); | ||
13 | - var url = window.location.protocol + "//" + query.hostname + ":" + srs_get_api_server_port() + "/index.html" + window.location.search; | ||
14 | - document.write("请确认api-server已经开启,跳转到api-server的页面(解决IE跨域问题)<br/>"); | ||
15 | - document.write("正在跳转,若您的浏览器没有跳转,请点击: <a href='" + url + "'>" + url + "</a>"); | ||
16 | - | ||
17 | setTimeout(function(){ | 9 | setTimeout(function(){ |
18 | - window.location.href = url; | ||
19 | - }, 3000); | 10 | + window.location.href = "players/index.html" + window.location.search; |
11 | + }, 500); | ||
20 | </script> | 12 | </script> |
21 | -</body> | 13 | +</body> |
trunk/research/players/osmf.html
100755 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | +<head> | ||
4 | + <title>SRS</title> | ||
5 | + <meta charset="utf-8"> | ||
6 | + <script type="text/javascript" src="players/js/jquery-1.10.2.min.js"></script> | ||
7 | + <script type="text/javascript" src="players/js/srs.page.js"></script> | ||
8 | + <script type="text/javascript" src="players/js/srs.utility.js"></script> | ||
9 | +</head> | ||
10 | +<body> | ||
11 | + <script type="text/javascript"> | ||
12 | + setTimeout(function(){ | ||
13 | + window.location.href = "players/index.html" + window.location.search; | ||
14 | + }, 500); | ||
15 | + </script> | ||
16 | +</body> |
trunk/research/players/srs_bwt.html
100755 → 100644
trunk/research/players/srs_chat.html
100755 → 100644
trunk/research/players/srs_player.html
100755 → 100644
trunk/research/players/srs_publisher.html
100755 → 100644
trunk/research/players/vlc.html
100755 → 100644
@@ -52,6 +52,13 @@ bool srs_path_equals(const char* expect, const char* path, int nb_path) | @@ -52,6 +52,13 @@ bool srs_path_equals(const char* expect, const char* path, int nb_path) | ||
52 | return equals; | 52 | return equals; |
53 | } | 53 | } |
54 | 54 | ||
55 | +bool srs_path_like(const char* expect, const char* path, int nb_path) | ||
56 | +{ | ||
57 | + int size = strlen(expect); | ||
58 | + bool equals = !strncmp(expect, path, srs_min(size, nb_path)); | ||
59 | + return equals; | ||
60 | +} | ||
61 | + | ||
55 | SrsHttpHandlerMatch::SrsHttpHandlerMatch() | 62 | SrsHttpHandlerMatch::SrsHttpHandlerMatch() |
56 | { | 63 | { |
57 | handler = NULL; | 64 | handler = NULL; |
@@ -217,6 +224,34 @@ SrsHttpHandler* SrsHttpHandler::res_content_type(std::stringstream& ss) | @@ -217,6 +224,34 @@ SrsHttpHandler* SrsHttpHandler::res_content_type(std::stringstream& ss) | ||
217 | return this; | 224 | return this; |
218 | } | 225 | } |
219 | 226 | ||
227 | +SrsHttpHandler* SrsHttpHandler::res_content_type_xml(std::stringstream& ss) | ||
228 | +{ | ||
229 | + ss << "Content-Type: text/xml;charset=utf-8" << __CRLF | ||
230 | + << "Allow: DELETE, GET, HEAD, OPTIONS, POST, PUT" << __CRLF; | ||
231 | + return this; | ||
232 | +} | ||
233 | + | ||
234 | +SrsHttpHandler* SrsHttpHandler::res_content_type_javascript(std::stringstream& ss) | ||
235 | +{ | ||
236 | + ss << "Content-Type: text/javascript;charset=utf-8" << __CRLF | ||
237 | + << "Allow: DELETE, GET, HEAD, OPTIONS, POST, PUT" << __CRLF; | ||
238 | + return this; | ||
239 | +} | ||
240 | + | ||
241 | +SrsHttpHandler* SrsHttpHandler::res_content_type_swf(std::stringstream& ss) | ||
242 | +{ | ||
243 | + ss << "Content-Type: application/x-shockwave-flash;charset=utf-8" << __CRLF | ||
244 | + << "Allow: DELETE, GET, HEAD, OPTIONS, POST, PUT" << __CRLF; | ||
245 | + return this; | ||
246 | +} | ||
247 | + | ||
248 | +SrsHttpHandler* SrsHttpHandler::res_content_type_css(std::stringstream& ss) | ||
249 | +{ | ||
250 | + ss << "Content-Type: text/css;charset=utf-8" << __CRLF | ||
251 | + << "Allow: DELETE, GET, HEAD, OPTIONS, POST, PUT" << __CRLF; | ||
252 | + return this; | ||
253 | +} | ||
254 | + | ||
220 | SrsHttpHandler* SrsHttpHandler::res_content_type_json(std::stringstream& ss) | 255 | SrsHttpHandler* SrsHttpHandler::res_content_type_json(std::stringstream& ss) |
221 | { | 256 | { |
222 | ss << "Content-Type: application/json;charset=utf-8" << __CRLF | 257 | ss << "Content-Type: application/json;charset=utf-8" << __CRLF |
@@ -299,6 +334,74 @@ int SrsHttpHandler::res_text(SrsSocket* skt, SrsHttpMessage* req, std::string bo | @@ -299,6 +334,74 @@ int SrsHttpHandler::res_text(SrsSocket* skt, SrsHttpMessage* req, std::string bo | ||
299 | return res_flush(skt, ss); | 334 | return res_flush(skt, ss); |
300 | } | 335 | } |
301 | 336 | ||
337 | +int SrsHttpHandler::res_xml(SrsSocket* skt, SrsHttpMessage* req, std::string body) | ||
338 | +{ | ||
339 | + std::stringstream ss; | ||
340 | + | ||
341 | + res_status_line(ss)->res_content_type_xml(ss) | ||
342 | + ->res_content_length(ss, (int)body.length()); | ||
343 | + | ||
344 | + if (req->requires_crossdomain()) { | ||
345 | + res_enable_crossdomain(ss); | ||
346 | + } | ||
347 | + | ||
348 | + res_header_eof(ss) | ||
349 | + ->res_body(ss, body); | ||
350 | + | ||
351 | + return res_flush(skt, ss); | ||
352 | +} | ||
353 | + | ||
354 | +int SrsHttpHandler::res_javascript(SrsSocket* skt, SrsHttpMessage* req, std::string body) | ||
355 | +{ | ||
356 | + std::stringstream ss; | ||
357 | + | ||
358 | + res_status_line(ss)->res_content_type_javascript(ss) | ||
359 | + ->res_content_length(ss, (int)body.length()); | ||
360 | + | ||
361 | + if (req->requires_crossdomain()) { | ||
362 | + res_enable_crossdomain(ss); | ||
363 | + } | ||
364 | + | ||
365 | + res_header_eof(ss) | ||
366 | + ->res_body(ss, body); | ||
367 | + | ||
368 | + return res_flush(skt, ss); | ||
369 | +} | ||
370 | + | ||
371 | +int SrsHttpHandler::res_swf(SrsSocket* skt, SrsHttpMessage* req, std::string body) | ||
372 | +{ | ||
373 | + std::stringstream ss; | ||
374 | + | ||
375 | + res_status_line(ss)->res_content_type_swf(ss) | ||
376 | + ->res_content_length(ss, (int)body.length()); | ||
377 | + | ||
378 | + if (req->requires_crossdomain()) { | ||
379 | + res_enable_crossdomain(ss); | ||
380 | + } | ||
381 | + | ||
382 | + res_header_eof(ss) | ||
383 | + ->res_body(ss, body); | ||
384 | + | ||
385 | + return res_flush(skt, ss); | ||
386 | +} | ||
387 | + | ||
388 | +int SrsHttpHandler::res_css(SrsSocket* skt, SrsHttpMessage* req, std::string body) | ||
389 | +{ | ||
390 | + std::stringstream ss; | ||
391 | + | ||
392 | + res_status_line(ss)->res_content_type_css(ss) | ||
393 | + ->res_content_length(ss, (int)body.length()); | ||
394 | + | ||
395 | + if (req->requires_crossdomain()) { | ||
396 | + res_enable_crossdomain(ss); | ||
397 | + } | ||
398 | + | ||
399 | + res_header_eof(ss) | ||
400 | + ->res_body(ss, body); | ||
401 | + | ||
402 | + return res_flush(skt, ss); | ||
403 | +} | ||
404 | + | ||
302 | int SrsHttpHandler::res_m3u8(SrsSocket* skt, SrsHttpMessage* req, std::string body) | 405 | int SrsHttpHandler::res_m3u8(SrsSocket* skt, SrsHttpMessage* req, std::string body) |
303 | { | 406 | { |
304 | std::stringstream ss; | 407 | std::stringstream ss; |
@@ -152,7 +152,12 @@ class SrsHttpHandler; | @@ -152,7 +152,12 @@ class SrsHttpHandler; | ||
152 | 152 | ||
153 | // compare the path. | 153 | // compare the path. |
154 | // full compare, extractly match. | 154 | // full compare, extractly match. |
155 | +// used for api match. | ||
155 | extern bool srs_path_equals(const char* expect, const char* path, int nb_path); | 156 | extern bool srs_path_equals(const char* expect, const char* path, int nb_path); |
157 | +// compare the path use like, | ||
158 | +// used for http stream to match, | ||
159 | +// if the path like the requires | ||
160 | +extern bool srs_path_like(const char* expect, const char* path, int nb_path); | ||
156 | 161 | ||
157 | // state of message | 162 | // state of message |
158 | enum SrsHttpParseState { | 163 | enum SrsHttpParseState { |
@@ -228,6 +233,10 @@ public: | @@ -228,6 +233,10 @@ public: | ||
228 | virtual SrsHttpHandler* res_status_line(std::stringstream& ss); | 233 | virtual SrsHttpHandler* res_status_line(std::stringstream& ss); |
229 | virtual SrsHttpHandler* res_status_line_error(std::stringstream& ss, int code, std::string reason_phrase); | 234 | virtual SrsHttpHandler* res_status_line_error(std::stringstream& ss, int code, std::string reason_phrase); |
230 | virtual SrsHttpHandler* res_content_type(std::stringstream& ss); | 235 | virtual SrsHttpHandler* res_content_type(std::stringstream& ss); |
236 | + virtual SrsHttpHandler* res_content_type_xml(std::stringstream& ss); | ||
237 | + virtual SrsHttpHandler* res_content_type_javascript(std::stringstream& ss); | ||
238 | + virtual SrsHttpHandler* res_content_type_swf(std::stringstream& ss); | ||
239 | + virtual SrsHttpHandler* res_content_type_css(std::stringstream& ss); | ||
231 | virtual SrsHttpHandler* res_content_type_json(std::stringstream& ss); | 240 | virtual SrsHttpHandler* res_content_type_json(std::stringstream& ss); |
232 | virtual SrsHttpHandler* res_content_type_m3u8(std::stringstream& ss); | 241 | virtual SrsHttpHandler* res_content_type_m3u8(std::stringstream& ss); |
233 | virtual SrsHttpHandler* res_content_type_mpegts(std::stringstream& ss); | 242 | virtual SrsHttpHandler* res_content_type_mpegts(std::stringstream& ss); |
@@ -239,6 +248,10 @@ public: | @@ -239,6 +248,10 @@ public: | ||
239 | public: | 248 | public: |
240 | virtual int res_options(SrsSocket* skt); | 249 | virtual int res_options(SrsSocket* skt); |
241 | virtual int res_text(SrsSocket* skt, SrsHttpMessage* req, std::string body); | 250 | virtual int res_text(SrsSocket* skt, SrsHttpMessage* req, std::string body); |
251 | + virtual int res_xml(SrsSocket* skt, SrsHttpMessage* req, std::string body); | ||
252 | + virtual int res_javascript(SrsSocket* skt, SrsHttpMessage* req, std::string body); | ||
253 | + virtual int res_swf(SrsSocket* skt, SrsHttpMessage* req, std::string body); | ||
254 | + virtual int res_css(SrsSocket* skt, SrsHttpMessage* req, std::string body); | ||
242 | virtual int res_m3u8(SrsSocket* skt, SrsHttpMessage* req, std::string body); | 255 | virtual int res_m3u8(SrsSocket* skt, SrsHttpMessage* req, std::string body); |
243 | virtual int res_mpegts(SrsSocket* skt, SrsHttpMessage* req, std::string body); | 256 | virtual int res_mpegts(SrsSocket* skt, SrsHttpMessage* req, std::string body); |
244 | virtual int res_json(SrsSocket* skt, SrsHttpMessage* req, std::string json); | 257 | virtual int res_json(SrsSocket* skt, SrsHttpMessage* req, std::string json); |
@@ -40,6 +40,8 @@ using namespace std; | @@ -40,6 +40,8 @@ using namespace std; | ||
40 | #include <srs_app_json.hpp> | 40 | #include <srs_app_json.hpp> |
41 | #include <srs_app_config.hpp> | 41 | #include <srs_app_config.hpp> |
42 | 42 | ||
43 | +#define SRS_HTTP_DEFAULT_PAGE "index.html" | ||
44 | + | ||
43 | SrsHttpRoot::SrsHttpRoot() | 45 | SrsHttpRoot::SrsHttpRoot() |
44 | { | 46 | { |
45 | // TODO: FIXME: support reload vhosts. | 47 | // TODO: FIXME: support reload vhosts. |
@@ -88,14 +90,26 @@ int SrsHttpRoot::initialize() | @@ -88,14 +90,26 @@ int SrsHttpRoot::initialize() | ||
88 | return ret; | 90 | return ret; |
89 | } | 91 | } |
90 | 92 | ||
91 | -bool SrsHttpRoot::can_handle(const char* path, int length, const char** pchild) | 93 | +int SrsHttpRoot::best_match(const char* path, int length, SrsHttpHandlerMatch** ppmatch) |
92 | { | 94 | { |
93 | - // reset the child path to path, | ||
94 | - // for child to reparse the path. | ||
95 | - *pchild = path; | 95 | + int ret = ERROR_SUCCESS; |
96 | + | ||
97 | + // find the best matched child handler. | ||
98 | + std::vector<SrsHttpHandler*>::iterator it; | ||
99 | + for (it = handlers.begin(); it != handlers.end(); ++it) { | ||
100 | + SrsHttpHandler* h = *it; | ||
101 | + | ||
102 | + // search all child handlers. | ||
103 | + h->best_match(path, length, ppmatch); | ||
104 | + } | ||
96 | 105 | ||
97 | - // never handle request for root. | ||
98 | - return true; | 106 | + // if already matched by child, return. |
107 | + if (*ppmatch) { | ||
108 | + return ret; | ||
109 | + } | ||
110 | + | ||
111 | + // not matched, error. | ||
112 | + return ERROR_HTTP_HANDLER_MATCH_URL; | ||
99 | } | 113 | } |
100 | 114 | ||
101 | bool SrsHttpRoot::is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase) | 115 | bool SrsHttpRoot::is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase) |
@@ -125,19 +139,12 @@ SrsHttpVhost::~SrsHttpVhost() | @@ -125,19 +139,12 @@ SrsHttpVhost::~SrsHttpVhost() | ||
125 | 139 | ||
126 | bool SrsHttpVhost::can_handle(const char* path, int length, const char** /*pchild*/) | 140 | bool SrsHttpVhost::can_handle(const char* path, int length, const char** /*pchild*/) |
127 | { | 141 | { |
128 | - int min_match = srs_min(length, (int)_mount.length()); | ||
129 | - return srs_path_equals(_mount.c_str(), path, min_match); | 142 | + return srs_path_like(_mount.c_str(), path, length); |
130 | } | 143 | } |
131 | 144 | ||
132 | bool SrsHttpVhost::is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase) | 145 | bool SrsHttpVhost::is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase) |
133 | { | 146 | { |
134 | - std::string fullpath = _dir + "/" + req->match()->unmatched_url; | ||
135 | - if (_mount == "/") { | ||
136 | - fullpath = _dir + "/" + req->match()->matched_url; | ||
137 | - if (!req->match()->unmatched_url.empty()) { | ||
138 | - fullpath += "/" + req->match()->unmatched_url; | ||
139 | - } | ||
140 | - } | 147 | + std::string fullpath = get_request_file(req); |
141 | 148 | ||
142 | if (::access(fullpath.c_str(), F_OK | R_OK) < 0) { | 149 | if (::access(fullpath.c_str(), F_OK | R_OK) < 0) { |
143 | srs_warn("check file %s does not exists", fullpath.c_str()); | 150 | srs_warn("check file %s does not exists", fullpath.c_str()); |
@@ -154,17 +161,7 @@ int SrsHttpVhost::do_process_request(SrsSocket* skt, SrsHttpMessage* req) | @@ -154,17 +161,7 @@ int SrsHttpVhost::do_process_request(SrsSocket* skt, SrsHttpMessage* req) | ||
154 | { | 161 | { |
155 | int ret = ERROR_SUCCESS; | 162 | int ret = ERROR_SUCCESS; |
156 | 163 | ||
157 | - std::string fullpath = _dir + "/" + req->match()->unmatched_url; | ||
158 | - if (_mount == "/") { | ||
159 | - fullpath = _dir + "/" + req->match()->matched_url; | ||
160 | - if (!req->match()->unmatched_url.empty()) { | ||
161 | - fullpath += "/" + req->match()->unmatched_url; | ||
162 | - } | ||
163 | - } | ||
164 | - | ||
165 | - if (srs_string_ends_with(fullpath, "/")) { | ||
166 | - fullpath += "index.html"; | ||
167 | - } | 164 | + std::string fullpath = get_request_file(req); |
168 | 165 | ||
169 | int fd = ::open(fullpath.c_str(), O_RDONLY); | 166 | int fd = ::open(fullpath.c_str(), O_RDONLY); |
170 | if (fd < 0) { | 167 | if (fd < 0) { |
@@ -194,6 +191,14 @@ int SrsHttpVhost::do_process_request(SrsSocket* skt, SrsHttpMessage* req) | @@ -194,6 +191,14 @@ int SrsHttpVhost::do_process_request(SrsSocket* skt, SrsHttpMessage* req) | ||
194 | return res_mpegts(skt, req, str); | 191 | return res_mpegts(skt, req, str); |
195 | } else if (srs_string_ends_with(fullpath, ".m3u8")) { | 192 | } else if (srs_string_ends_with(fullpath, ".m3u8")) { |
196 | return res_m3u8(skt, req, str); | 193 | return res_m3u8(skt, req, str); |
194 | + } else if (srs_string_ends_with(fullpath, ".xml")) { | ||
195 | + return res_xml(skt, req, str); | ||
196 | + } else if (srs_string_ends_with(fullpath, ".js")) { | ||
197 | + return res_javascript(skt, req, str); | ||
198 | + } else if (srs_string_ends_with(fullpath, ".swf")) { | ||
199 | + return res_swf(skt, req, str); | ||
200 | + } else if (srs_string_ends_with(fullpath, ".css")) { | ||
201 | + return res_css(skt, req, str); | ||
197 | } else { | 202 | } else { |
198 | return res_text(skt, req, str); | 203 | return res_text(skt, req, str); |
199 | } | 204 | } |
@@ -201,6 +206,31 @@ int SrsHttpVhost::do_process_request(SrsSocket* skt, SrsHttpMessage* req) | @@ -201,6 +206,31 @@ int SrsHttpVhost::do_process_request(SrsSocket* skt, SrsHttpMessage* req) | ||
201 | return ret; | 206 | return ret; |
202 | } | 207 | } |
203 | 208 | ||
209 | +string SrsHttpVhost::get_request_file(SrsHttpMessage* req) | ||
210 | +{ | ||
211 | + std::string fullpath = _dir + "/"; | ||
212 | + | ||
213 | + // if root, directly use the matched url. | ||
214 | + if (_mount == "/") { | ||
215 | + // add the dir | ||
216 | + fullpath += req->match()->matched_url; | ||
217 | + // if file speicified, add the file. | ||
218 | + if (!req->match()->unmatched_url.empty()) { | ||
219 | + fullpath += "/" + req->match()->unmatched_url; | ||
220 | + } | ||
221 | + } else { | ||
222 | + // virtual path, ignore the virutal path. | ||
223 | + fullpath += req->match()->unmatched_url; | ||
224 | + } | ||
225 | + | ||
226 | + // add default pages. | ||
227 | + if (srs_string_ends_with(fullpath, "/")) { | ||
228 | + fullpath += SRS_HTTP_DEFAULT_PAGE; | ||
229 | + } | ||
230 | + | ||
231 | + return fullpath; | ||
232 | +} | ||
233 | + | ||
204 | string SrsHttpVhost::vhost() | 234 | string SrsHttpVhost::vhost() |
205 | { | 235 | { |
206 | return _vhost; | 236 | return _vhost; |
@@ -49,7 +49,7 @@ public: | @@ -49,7 +49,7 @@ public: | ||
49 | virtual ~SrsHttpRoot(); | 49 | virtual ~SrsHttpRoot(); |
50 | public: | 50 | public: |
51 | virtual int initialize(); | 51 | virtual int initialize(); |
52 | - virtual bool can_handle(const char* path, int length, const char** pchild); | 52 | + virtual int best_match(const char* path, int length, SrsHttpHandlerMatch** ppmatch); |
53 | protected: | 53 | protected: |
54 | virtual bool is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase); | 54 | virtual bool is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase); |
55 | virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); | 55 | virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); |
@@ -69,6 +69,8 @@ public: | @@ -69,6 +69,8 @@ public: | ||
69 | protected: | 69 | protected: |
70 | virtual bool is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase); | 70 | virtual bool is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase); |
71 | virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); | 71 | virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); |
72 | +private: | ||
73 | + virtual std::string get_request_file(SrsHttpMessage* req); | ||
72 | public: | 74 | public: |
73 | virtual std::string vhost(); | 75 | virtual std::string vhost(); |
74 | virtual std::string mount(); | 76 | virtual std::string mount(); |
@@ -239,6 +239,7 @@ int SrsRtmpConn::stream_service_cycle() | @@ -239,6 +239,7 @@ int SrsRtmpConn::stream_service_cycle() | ||
239 | srs_error("identify client failed. ret=%d", ret); | 239 | srs_error("identify client failed. ret=%d", ret); |
240 | return ret; | 240 | return ret; |
241 | } | 241 | } |
242 | + req->strip(); | ||
242 | srs_trace("identify client success. type=%s, stream_name=%s", | 243 | srs_trace("identify client success. type=%s, stream_name=%s", |
243 | srs_client_type_string(type).c_str(), req->stream.c_str()); | 244 | srs_client_type_string(type).c_str(), req->stream.c_str()); |
244 | 245 |
@@ -63,6 +63,24 @@ string srs_string_trim_end(string str, string trim_chars) | @@ -63,6 +63,24 @@ string srs_string_trim_end(string str, string trim_chars) | ||
63 | return ret; | 63 | return ret; |
64 | } | 64 | } |
65 | 65 | ||
66 | +string srs_string_trim_start(string str, string trim_chars) | ||
67 | +{ | ||
68 | + std::string ret = str; | ||
69 | + | ||
70 | + for (int i = 0; i < (int)trim_chars.length(); i++) { | ||
71 | + char ch = trim_chars.at(i); | ||
72 | + | ||
73 | + while (!ret.empty() && ret.at(0) == ch) { | ||
74 | + ret.erase(ret.begin()); | ||
75 | + | ||
76 | + // ok, matched, should reset the search | ||
77 | + i = 0; | ||
78 | + } | ||
79 | + } | ||
80 | + | ||
81 | + return ret; | ||
82 | +} | ||
83 | + | ||
66 | string srs_string_remove(string str, string remove_chars) | 84 | string srs_string_remove(string str, string remove_chars) |
67 | { | 85 | { |
68 | std::string ret = str; | 86 | std::string ret = str; |
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
31 | // current release version | 31 | // current release version |
32 | #define VERSION_MAJOR "0" | 32 | #define VERSION_MAJOR "0" |
33 | #define VERSION_MINOR "9" | 33 | #define VERSION_MINOR "9" |
34 | -#define VERSION_REVISION "50" | 34 | +#define VERSION_REVISION "51" |
35 | #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION | 35 | #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION |
36 | // server info. | 36 | // server info. |
37 | #define RTMP_SIG_SRS_KEY "srs" | 37 | #define RTMP_SIG_SRS_KEY "srs" |
@@ -101,6 +101,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -101,6 +101,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
101 | extern std::string srs_string_replace(std::string str, std::string old_str, std::string new_str); | 101 | extern std::string srs_string_replace(std::string str, std::string old_str, std::string new_str); |
102 | // trim char in trim_chars of str | 102 | // trim char in trim_chars of str |
103 | extern std::string srs_string_trim_end(std::string str, std::string trim_chars); | 103 | extern std::string srs_string_trim_end(std::string str, std::string trim_chars); |
104 | +// trim char in trim_chars of str | ||
105 | +extern std::string srs_string_trim_start(std::string str, std::string trim_chars); | ||
104 | // remove char in remove_chars of str | 106 | // remove char in remove_chars of str |
105 | extern std::string srs_string_remove(std::string str, std::string remove_chars); | 107 | extern std::string srs_string_remove(std::string str, std::string remove_chars); |
106 | // whether string end with | 108 | // whether string end with |
@@ -127,15 +127,8 @@ int SrsRequest::discovery_app() | @@ -127,15 +127,8 @@ int SrsRequest::discovery_app() | ||
127 | app = url; | 127 | app = url; |
128 | vhost = host; | 128 | vhost = host; |
129 | srs_vhost_resolve(vhost, app); | 129 | srs_vhost_resolve(vhost, app); |
130 | - | ||
131 | - // remove the unsupported chars in names. | ||
132 | - vhost = srs_string_remove(vhost, "/ \n\r\t"); | ||
133 | - app = srs_string_remove(app, " \n\r\t"); | ||
134 | - stream = srs_string_remove(stream, " \n\r\t"); | ||
135 | 130 | ||
136 | - // remove end slash of app | ||
137 | - app = srs_string_trim_end(app, "/"); | ||
138 | - stream = srs_string_trim_end(stream, "/"); | 131 | + strip(); |
139 | 132 | ||
140 | return ret; | 133 | return ret; |
141 | } | 134 | } |
@@ -153,6 +146,22 @@ string SrsRequest::get_stream_url() | @@ -153,6 +146,22 @@ string SrsRequest::get_stream_url() | ||
153 | return url; | 146 | return url; |
154 | } | 147 | } |
155 | 148 | ||
149 | +void SrsRequest::strip() | ||
150 | +{ | ||
151 | + // remove the unsupported chars in names. | ||
152 | + vhost = srs_string_remove(vhost, "/ \n\r\t"); | ||
153 | + app = srs_string_remove(app, " \n\r\t"); | ||
154 | + stream = srs_string_remove(stream, " \n\r\t"); | ||
155 | + | ||
156 | + // remove end slash of app/stream | ||
157 | + app = srs_string_trim_end(app, "/"); | ||
158 | + stream = srs_string_trim_end(stream, "/"); | ||
159 | + | ||
160 | + // remove start slash of app/stream | ||
161 | + app = srs_string_trim_start(app, "/"); | ||
162 | + stream = srs_string_trim_start(stream, "/"); | ||
163 | +} | ||
164 | + | ||
156 | SrsResponse::SrsResponse() | 165 | SrsResponse::SrsResponse() |
157 | { | 166 | { |
158 | stream_id = SRS_DEFAULT_SID; | 167 | stream_id = SRS_DEFAULT_SID; |
@@ -82,6 +82,9 @@ public: | @@ -82,6 +82,9 @@ public: | ||
82 | */ | 82 | */ |
83 | virtual int discovery_app(); | 83 | virtual int discovery_app(); |
84 | virtual std::string get_stream_url(); | 84 | virtual std::string get_stream_url(); |
85 | + | ||
86 | + // strip url, user must strip when update the url. | ||
87 | + virtual void strip(); | ||
85 | }; | 88 | }; |
86 | 89 | ||
87 | /** | 90 | /** |
-
请 注册 或 登录 后发表评论