Skip to content

Commit 15fe840

Browse files
committed
implemented connect/play/publish notify redirect
1 parent 9aa030f commit 15fe840

File tree

1 file changed

+173
-7
lines changed

1 file changed

+173
-7
lines changed

ngx_rtmp_notify_module.c

Lines changed: 173 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,14 @@ ngx_rtmp_notify_parse_http_retcode(ngx_rtmp_session_t *s,
788788
if (c >= (u_char)'0' && c <= (u_char)'9') {
789789
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
790790
"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+
}
792799
}
793800

794801
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,
813820
}
814821

815822

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+
816922
static ngx_int_t
817923
ngx_rtmp_notify_connect_handle(ngx_rtmp_session_t *s,
818924
void *arg, ngx_chain_t *in)
819925
{
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) {
821934
return NGX_ERROR;
822935
}
823936

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);
825951
}
826952

827953

828954
static ngx_int_t
829955
ngx_rtmp_notify_publish_handle(ngx_rtmp_session_t *s,
830956
void *arg, ngx_chain_t *in)
831957
{
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) {
833966
return NGX_ERROR;
834967
}
835968

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);
837983
}
838984

839985

840986
static ngx_int_t
841987
ngx_rtmp_notify_play_handle(ngx_rtmp_session_t *s,
842988
void *arg, ngx_chain_t *in)
843989
{
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) {
845998
return NGX_ERROR;
846999
}
8471000

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);
8491015
}
8501016

8511017

0 commit comments

Comments
 (0)