@@ -788,7 +788,14 @@ ngx_rtmp_notify_parse_http_retcode(ngx_rtmp_session_t *s,
788
788
if (c >= (u_char )'0' && c <= (u_char )'9' ) {
789
789
ngx_log_debug1 (NGX_LOG_DEBUG_RTMP , s -> connection -> log , 0 ,
790
790
"notify: HTTP retcode: %dxx" , (int )(c - '0' ));
791
- return c == (u_char )'2' ? NGX_OK : NGX_ERROR ;
791
+ switch (c ) {
792
+ case (u_char ) '2' :
793
+ return NGX_OK ;
794
+ case (u_char ) '3' :
795
+ return NGX_AGAIN ;
796
+ default :
797
+ return NGX_ERROR ;
798
+ }
792
799
}
793
800
794
801
ngx_log_error (NGX_LOG_INFO , s -> connection -> log , 0 ,
@@ -813,39 +820,198 @@ ngx_rtmp_notify_parse_http_retcode(ngx_rtmp_session_t *s,
813
820
}
814
821
815
822
823
+ static ngx_int_t
824
+ ngx_rtmp_notify_parse_http_header (ngx_rtmp_session_t * s ,
825
+ ngx_chain_t * in , ngx_str_t * name , u_char * data , size_t len )
826
+ {
827
+ ngx_buf_t * b ;
828
+ ngx_int_t matched ;
829
+ u_char * p , c ;
830
+ ngx_uint_t n ;
831
+
832
+ enum {
833
+ parse_name ,
834
+ parse_space ,
835
+ parse_value ,
836
+ parse_value_newline
837
+ } state = parse_name ;
838
+
839
+ n = 0 ;
840
+ matched = 0 ;
841
+
842
+ while (in ) {
843
+ b = in -> buf ;
844
+
845
+ for (p = b -> pos ; p != b -> last ; ++ p ) {
846
+ c = * p ;
847
+
848
+ ngx_log_debug3 (NGX_LOG_DEBUG_RTMP , s -> connection -> log , 0 ,
849
+ "header state:%i, n:%ui, c:%c" ,
850
+ (ngx_int_t ) state , n , c );
851
+
852
+ if (c == '\r' ) {
853
+ continue ;
854
+ }
855
+
856
+ switch (state ) {
857
+ case parse_value_newline :
858
+ if (c == ' ' || c == '\t' ) {
859
+ state = parse_space ;
860
+ break ;
861
+ }
862
+
863
+ if (matched ) {
864
+ return n ;
865
+ }
866
+
867
+ if (c == '\n' ) {
868
+ return NGX_OK ;
869
+ }
870
+
871
+ n = 0 ;
872
+ state = parse_name ;
873
+
874
+ case parse_name :
875
+ switch (c ) {
876
+ case ':' :
877
+ matched = (n == name -> len );
878
+ n = 0 ;
879
+ state = parse_space ;
880
+ break ;
881
+ case '\n' :
882
+ n = 0 ;
883
+ break ;
884
+ default :
885
+ if (n < name -> len &&
886
+ ngx_tolower (c ) == ngx_tolower (name -> data [n ]))
887
+ {
888
+ ++ n ;
889
+ break ;
890
+ }
891
+ n = name -> len + 1 ;
892
+ }
893
+ break ;
894
+
895
+ case parse_space :
896
+ if (c == ' ' || c == '\t' ) {
897
+ break ;
898
+ }
899
+ state = parse_value ;
900
+
901
+ case parse_value :
902
+ if (c == '\n' ) {
903
+ state = parse_value_newline ;
904
+ break ;
905
+ }
906
+
907
+ if (matched && n + 1 < len ) {
908
+ data [n ++ ] = c ;
909
+ }
910
+
911
+ break ;
912
+ }
913
+ }
914
+
915
+ in = in -> next ;
916
+ }
917
+
918
+ return NGX_OK ;
919
+ }
920
+
921
+
816
922
static ngx_int_t
817
923
ngx_rtmp_notify_connect_handle (ngx_rtmp_session_t * s ,
818
924
void * arg , ngx_chain_t * in )
819
925
{
820
- if (ngx_rtmp_notify_parse_http_retcode (s , in ) != NGX_OK ) {
926
+ ngx_rtmp_connect_t * v = arg ;
927
+ ngx_int_t rc ;
928
+ u_char app [NGX_RTMP_MAX_NAME ];
929
+
930
+ static ngx_str_t location = ngx_string ("location" );
931
+
932
+ rc = ngx_rtmp_notify_parse_http_retcode (s , in );
933
+ if (rc == NGX_ERROR ) {
821
934
return NGX_ERROR ;
822
935
}
823
936
824
- return next_connect (s , (ngx_rtmp_connect_t * )arg );
937
+ if (rc == NGX_AGAIN ) {
938
+ ngx_log_debug0 (NGX_LOG_DEBUG_RTMP , s -> connection -> log , 0 ,
939
+ "notify: connect redirect received" );
940
+
941
+ rc = ngx_rtmp_notify_parse_http_header (s , in , & location , app ,
942
+ sizeof (app ) - 1 );
943
+ if (rc > 0 ) {
944
+ * ngx_cpymem (v -> app , app , rc ) = 0 ;
945
+ ngx_log_error (NGX_LOG_INFO , s -> connection -> log , 0 ,
946
+ "notify: connect redirect to '%s'" , v -> app );
947
+ }
948
+ }
949
+
950
+ return next_connect (s , v );
825
951
}
826
952
827
953
828
954
static ngx_int_t
829
955
ngx_rtmp_notify_publish_handle (ngx_rtmp_session_t * s ,
830
956
void * arg , ngx_chain_t * in )
831
957
{
832
- if (ngx_rtmp_notify_parse_http_retcode (s , in ) != NGX_OK ) {
958
+ ngx_rtmp_publish_t * v = arg ;
959
+ ngx_int_t rc ;
960
+ u_char name [NGX_RTMP_MAX_NAME ];
961
+
962
+ static ngx_str_t location = ngx_string ("location" );
963
+
964
+ rc = ngx_rtmp_notify_parse_http_retcode (s , in );
965
+ if (rc == NGX_ERROR ) {
833
966
return NGX_ERROR ;
834
967
}
835
968
836
- return next_publish (s , (ngx_rtmp_publish_t * )arg );
969
+ if (rc == NGX_AGAIN ) {
970
+ ngx_log_debug0 (NGX_LOG_DEBUG_RTMP , s -> connection -> log , 0 ,
971
+ "notify: publish redirect received" );
972
+
973
+ rc = ngx_rtmp_notify_parse_http_header (s , in , & location , name ,
974
+ sizeof (name ) - 1 );
975
+ if (rc > 0 ) {
976
+ * ngx_cpymem (v -> name , name , rc ) = 0 ;
977
+ ngx_log_error (NGX_LOG_INFO , s -> connection -> log , 0 ,
978
+ "notify: publish redirect to '%s'" , v -> name );
979
+ }
980
+ }
981
+
982
+ return next_publish (s , v );
837
983
}
838
984
839
985
840
986
static ngx_int_t
841
987
ngx_rtmp_notify_play_handle (ngx_rtmp_session_t * s ,
842
988
void * arg , ngx_chain_t * in )
843
989
{
844
- if (ngx_rtmp_notify_parse_http_retcode (s , in ) != NGX_OK ) {
990
+ ngx_rtmp_play_t * v = arg ;
991
+ ngx_int_t rc ;
992
+ u_char name [NGX_RTMP_MAX_NAME ];
993
+
994
+ static ngx_str_t location = ngx_string ("location" );
995
+
996
+ rc = ngx_rtmp_notify_parse_http_retcode (s , in );
997
+ if (rc == NGX_ERROR ) {
845
998
return NGX_ERROR ;
846
999
}
847
1000
848
- return next_play (s , (ngx_rtmp_play_t * )arg );
1001
+ if (rc == NGX_AGAIN ) {
1002
+ ngx_log_debug0 (NGX_LOG_DEBUG_RTMP , s -> connection -> log , 0 ,
1003
+ "notify: play redirect received" );
1004
+
1005
+ rc = ngx_rtmp_notify_parse_http_header (s , in , & location , name ,
1006
+ sizeof (name ) - 1 );
1007
+ if (rc > 0 ) {
1008
+ * ngx_cpymem (v -> name , name , rc ) = 0 ;
1009
+ ngx_log_error (NGX_LOG_INFO , s -> connection -> log , 0 ,
1010
+ "notify: play redirect to '%s'" , v -> name );
1011
+ }
1012
+ }
1013
+
1014
+ return next_play (s , v );
849
1015
}
850
1016
851
1017
0 commit comments