Skip to content

Commit

Permalink
Merge pull request #26 from sergey-dryabzhinsky/add-publisher-redirec…
Browse files Browse the repository at this point in the history
…t-support

Add publisher redirect support, partially
  • Loading branch information
Sergey committed Aug 6, 2015
2 parents b3f0fb0 + bb67548 commit bcbef42
Show file tree
Hide file tree
Showing 3 changed files with 311 additions and 14 deletions.
2 changes: 1 addition & 1 deletion ngx_rtmp_amf.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ ngx_rtmp_amf_reverse_copy(void *dst, void* src, size_t len)
return dst;
}

#define NGX_RTMP_AMF_DEBUG_SIZE 16
#define NGX_RTMP_AMF_DEBUG_SIZE 72

#ifdef NGX_DEBUG
static void
Expand Down
184 changes: 171 additions & 13 deletions ngx_rtmp_notify_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ static char *ngx_rtmp_notify_on_app_event(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_rtmp_notify_method(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_rtmp_notify_send_redirect(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static ngx_int_t ngx_rtmp_notify_postconfiguration(ngx_conf_t *cf);
static void * ngx_rtmp_notify_create_app_conf(ngx_conf_t *cf);
static char * ngx_rtmp_notify_merge_app_conf(ngx_conf_t *cf,
Expand Down Expand Up @@ -70,6 +72,7 @@ typedef struct {
ngx_url_t *url[NGX_RTMP_NOTIFY_APP_MAX];
ngx_flag_t active;
ngx_uint_t method;
ngx_flag_t send_redirect;
ngx_msec_t update_timeout;
ngx_flag_t update_strict;
ngx_flag_t relay_redirect;
Expand All @@ -79,6 +82,7 @@ typedef struct {
typedef struct {
ngx_url_t *url[NGX_RTMP_NOTIFY_SRV_MAX];
ngx_uint_t method;
ngx_flag_t send_redirect;
} ngx_rtmp_notify_srv_conf_t;


Expand Down Expand Up @@ -191,6 +195,13 @@ static ngx_command_t ngx_rtmp_notify_commands[] = {
offsetof(ngx_rtmp_notify_app_conf_t, relay_redirect),
NULL },

{ ngx_string("notify_send_redirect"),
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
ngx_rtmp_notify_send_redirect,
NGX_RTMP_APP_CONF_OFFSET,
0,
NULL },

ngx_null_command
};

Expand Down Expand Up @@ -239,6 +250,7 @@ ngx_rtmp_notify_create_app_conf(ngx_conf_t *cf)
}

nacf->method = NGX_CONF_UNSET_UINT;
nacf->send_redirect = NGX_CONF_UNSET;
nacf->update_timeout = NGX_CONF_UNSET_MSEC;
nacf->update_strict = NGX_CONF_UNSET;
nacf->relay_redirect = NGX_CONF_UNSET;
Expand Down Expand Up @@ -267,6 +279,7 @@ ngx_rtmp_notify_merge_app_conf(ngx_conf_t *cf, void *parent, void *child)

ngx_conf_merge_uint_value(conf->method, prev->method,
NGX_RTMP_NETCALL_HTTP_POST);
ngx_conf_merge_value(conf->send_redirect, prev->send_redirect, 0);
ngx_conf_merge_msec_value(conf->update_timeout, prev->update_timeout,
30000);
ngx_conf_merge_value(conf->update_strict, prev->update_strict, 0);
Expand All @@ -292,6 +305,7 @@ ngx_rtmp_notify_create_srv_conf(ngx_conf_t *cf)
}

nscf->method = NGX_CONF_UNSET_UINT;
nscf->send_redirect = NGX_CONF_UNSET;

return nscf;
}
Expand All @@ -310,6 +324,7 @@ ngx_rtmp_notify_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)

ngx_conf_merge_uint_value(conf->method, prev->method,
NGX_RTMP_NETCALL_HTTP_POST);
ngx_conf_merge_value(conf->send_redirect, prev->send_redirect, 0);

return NGX_CONF_OK;
}
Expand Down Expand Up @@ -982,7 +997,9 @@ ngx_rtmp_notify_connect_handle(ngx_rtmp_session_t *s,
void *arg, ngx_chain_t *in)
{
ngx_rtmp_connect_t *v = arg;
ngx_int_t rc;
ngx_int_t rc, send;
ngx_str_t local_name;
ngx_rtmp_notify_srv_conf_t *nscf;
u_char app[NGX_RTMP_MAX_NAME];

static ngx_str_t location = ngx_string("location");
Expand All @@ -992,19 +1009,81 @@ ngx_rtmp_notify_connect_handle(ngx_rtmp_session_t *s,
return NGX_ERROR;
}

if (rc == NGX_AGAIN) {
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"notify: connect redirect received");
if (rc != NGX_AGAIN) {
goto next;
}

/* HTTP 3xx */

ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
"notify: connect redirect received");

rc = ngx_rtmp_notify_parse_http_header(s, in, &location, app,
sizeof(app) - 1);
if (rc <= 0) {
goto next;
}

ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
"notify: parsed location '%*s'", rc, app);

/* switch app */

if (ngx_strncasecmp(app, (u_char *) "rtmp://", 7)) {
*ngx_cpymem(v->app, app, rc) = 0;
ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
"notify: connect redirect to '%s'", v->app);
goto next;
}

/* redirect */

nscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_notify_module);

if (nscf->send_redirect) {
// Send 302 redirect and go next

ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
"notify: connect send 302 redirect");
ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
"notify: -- for app '%s' to new location '%*s'", v->app, rc, app);

local_name.data = ngx_palloc(s->connection->pool, rc+1);
local_name.len = rc;
*ngx_cpymem(local_name.data, app, rc) = 0;

/* MAGICK HERE */

if (!ngx_strncasecmp(s->flashver.data, (u_char *) "FMLE/", 5)) {
// Official method, by FMS SDK
send = ngx_rtmp_send_redirect_status(s, "onStatus", "Connect here", local_name);
send &= ngx_rtmp_send_redirect_status(s, "netStatus", "Connect here", local_name);

rc = ngx_rtmp_notify_parse_http_header(s, in, &location, app,
sizeof(app) - 1);
if (rc > 0) {
*ngx_cpymem(v->app, app, rc) = 0;
ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
"notify: connect redirect to '%s'", v->app);
"notify: connect send(o) status = '%ui'", send == NGX_OK);
} else {
// Something by rtmpdump lib
send = ngx_rtmp_send_redirect_status(s, "_error", "Connect here", local_name);

ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
"notify: connect send(e) status = '%ui'", send == NGX_OK);
}

ngx_pfree(s->connection->pool, local_name.data);

// Something by rtmpdump lib
send = ngx_rtmp_send_close_method(s, "close");
ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
"notify: connect send(e) close method = '%ui'", send == NGX_OK);

return send;
// return next_disconnect(s);
// Don't close connection here! Client must catch message and do it by itself.
// goto next;
}

next:

return next_connect(s, v);
}

Expand All @@ -1030,7 +1109,7 @@ ngx_rtmp_notify_publish_handle(ngx_rtmp_session_t *s,
void *arg, ngx_chain_t *in)
{
ngx_rtmp_publish_t *v = arg;
ngx_int_t rc;
ngx_int_t rc, send;
ngx_str_t local_name;
ngx_rtmp_relay_target_t target;
ngx_url_t *u;
Expand All @@ -1051,7 +1130,7 @@ ngx_rtmp_notify_publish_handle(ngx_rtmp_session_t *s,

/* HTTP 3xx */

ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
"notify: publish redirect received");

rc = ngx_rtmp_notify_parse_http_header(s, in, &location, name,
Expand All @@ -1070,11 +1149,59 @@ ngx_rtmp_notify_publish_handle(ngx_rtmp_session_t *s,
/* push */

nacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_notify_module);
if (nacf->relay_redirect) {

if (nacf->send_redirect) {
// Send 302 redirect and go next

ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
"notify: publish send 302 redirect");
ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
"notify: -- for stream '%s' to new location '%*s'", v->name, rc, name);

local_name.data = ngx_palloc(s->connection->pool, rc+1);
local_name.len = rc;
*ngx_cpymem(local_name.data, name, rc) = 0;

/* MAGICK HERE */

if (!ngx_strncasecmp(s->flashver.data, (u_char *) "FMLE/", 5)) {
// Official method, by FMS SDK
send = ngx_rtmp_send_redirect_status(s, "onStatus", "Connect here", local_name);
send &= ngx_rtmp_send_redirect_status(s, "netStatus", "Connect here", local_name);

ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
"notify: publish send(o) status = '%ui'", send == NGX_OK);
} else {

// Something by rtmpdump lib
send = ngx_rtmp_send_redirect_status(s, "_error", "Connect here", local_name);

ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
"notify: publish send(e) status = '%ui'", send == NGX_OK);
}

ngx_pfree(s->connection->pool, local_name.data);

ngx_rtmp_notify_clear_flag(s, NGX_RTMP_NOTIFY_PUBLISHING);
// return send;

// Something by rtmpdump lib
send = ngx_rtmp_send_close_method(s);
ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
"notify: publish send(e) close method = '%ui'", send == NGX_OK);

return send;
// return next_disconnect(s);
// Don't close connection here! Client must catch message and do it by itself.
// goto next;

} else if (nacf->relay_redirect) {
// Relay local streams, change name

ngx_rtmp_notify_set_name(v->name, NGX_RTMP_MAX_NAME, name, (size_t) rc);
}

ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
"notify: push '%s' to '%*s'", v->name, rc, name);

local_name.data = v->name;
Expand Down Expand Up @@ -1727,6 +1854,37 @@ ngx_rtmp_notify_method(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_OK;
}

static char *
ngx_rtmp_notify_send_redirect(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_rtmp_notify_app_conf_t *nacf = conf;

ngx_rtmp_notify_srv_conf_t *nscf;
ngx_str_t *value;

value = cf->args->elts;
value++;

if (value->len == sizeof("on") - 1 &&
ngx_strncasecmp(value->data, (u_char *) "on", value->len) == 0)
{
nacf->send_redirect = 1;

} else if (value->len == sizeof("off") - 1 &&
ngx_strncasecmp(value->data, (u_char *) "off", value->len) == 0)
{
nacf->send_redirect = 0;

} else {
return "got unexpected send_redirect value";
}

nscf = ngx_rtmp_conf_get_module_srv_conf(cf, ngx_rtmp_notify_module);
nscf->send_redirect = nacf->send_redirect;

return NGX_CONF_OK;
}


static ngx_int_t
ngx_rtmp_notify_postconfiguration(ngx_conf_t *cf)
Expand Down
Loading

0 comments on commit bcbef42

Please sign in to comment.