Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: arut/nginx-rtmp-module
base: f65f07deb3
...
head fork: arut/nginx-rtmp-module
compare: 4adc5f7487
Checking mergeability… Don't worry, you can still create the pull request.
  • 3 commits
  • 5 files changed
  • 0 commit comments
  • 1 contributor
View
112 ngx_rtmp_netcall_module.c
@@ -20,12 +20,9 @@ static void ngx_rtmp_netcall_recv(ngx_event_t *rev);
static void ngx_rtmp_netcall_send(ngx_event_t *wev);
-ngx_str_t ngx_rtmp_netcall_content_type_urlencoded =
- ngx_string("application/x-www-form-urlencoded");
-
-
typedef struct {
ngx_msec_t timeout;
+ size_t bufsize;
ngx_log_t *log;
} ngx_rtmp_netcall_app_conf_t;
@@ -38,11 +35,13 @@ typedef struct ngx_rtmp_netcall_session_s {
void *arg;
ngx_rtmp_netcall_handle_pt handle;
ngx_rtmp_netcall_filter_pt filter;
+ ngx_rtmp_netcall_sink_pt sink;
ngx_chain_t *in;
ngx_chain_t *inlast;
ngx_chain_t *out;
ngx_msec_t timeout;
- ngx_int_t detached;
+ unsigned detached:1;
+ size_t bufsize;
} ngx_rtmp_netcall_session_t;
@@ -60,6 +59,13 @@ static ngx_command_t ngx_rtmp_netcall_commands[] = {
offsetof(ngx_rtmp_netcall_app_conf_t, timeout),
NULL },
+ { ngx_string("netcall_buffer"),
+ NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_size_slot,
+ NGX_RTMP_SRV_CONF_OFFSET,
+ offsetof(ngx_rtmp_netcall_app_conf_t, bufsize),
+ NULL },
+
ngx_null_command
};
@@ -103,6 +109,8 @@ ngx_rtmp_netcall_create_app_conf(ngx_conf_t *cf)
}
nacf->timeout = NGX_CONF_UNSET_MSEC;
+ nacf->bufsize = NGX_CONF_UNSET_SIZE;
+
nacf->log = &cf->cycle->new_log;
return nacf;
@@ -116,6 +124,7 @@ ngx_rtmp_netcall_merge_app_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_rtmp_netcall_app_conf_t *conf = child;
ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 10000);
+ ngx_conf_merge_size_value(conf->bufsize, prev->bufsize, 1024);
return NGX_CONF_OK;
}
@@ -219,9 +228,11 @@ ngx_rtmp_netcall_create(ngx_rtmp_session_t *s, ngx_rtmp_netcall_init_t *ci)
}
cs->timeout = cacf->timeout;
+ cs->bufsize = cacf->bufsize;
cs->url = ci->url;
cs->session = s;
cs->filter = ci->filter;
+ cs->sink = ci->sink;
cs->handle = ci->handle;
if (cs->handle == NULL) {
cs->detached = 1;
@@ -281,6 +292,7 @@ ngx_rtmp_netcall_close(ngx_connection_t *cc)
ngx_pool_t *pool;
ngx_rtmp_session_t *s;
ngx_rtmp_netcall_ctx_t *ctx;
+ ngx_buf_t *b;
cs = cc->data;
@@ -294,6 +306,14 @@ ngx_rtmp_netcall_close(ngx_connection_t *cc)
s = cs->session;
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_netcall_module);
+ if (cs->in && cs->sink) {
+ cs->sink(cs->session, cs->in);
+
+ b = cs->in->buf;
+ b->pos = b->last = b->start;
+
+ }
+
for(css = &ctx->cs; *css; css = &((*css)->next)) {
if (*css == cs) {
*css = cs->next;
@@ -301,9 +321,7 @@ ngx_rtmp_netcall_close(ngx_connection_t *cc)
}
}
- if (cs->handle &&
- cs->handle(s, cs->arg, cs->in) != NGX_OK)
- {
+ if (cs->handle && cs->handle(s, cs->arg, cs->in) != NGX_OK) {
ngx_rtmp_finalize_session(s);
}
}
@@ -352,29 +370,43 @@ ngx_rtmp_netcall_recv(ngx_event_t *rev)
for ( ;; ) {
- if (cs->inlast == NULL
- || cs->inlast->buf->last == cs->inlast->buf->end)
+ if (cs->inlast == NULL ||
+ cs->inlast->buf->last == cs->inlast->buf->end)
{
- cl = ngx_alloc_chain_link(cc->pool);
- if (cl == NULL) {
- ngx_rtmp_netcall_close(cc);
- return;
- }
- cl->next = NULL;
+ if (cs->in && cs->sink) {
+ if (!cs->detached) {
+ if (cs->sink(cs->session, cs->in) != NGX_OK) {
+ ngx_rtmp_netcall_close(cc);
+ return;
+ }
+ }
- cl->buf = ngx_create_temp_buf(cc->pool, 1024);
- if (cl->buf == NULL) {
- ngx_rtmp_netcall_close(cc);
- return;
- }
+ b = cs->in->buf;
+ b->pos = b->last = b->start;
- if (cs->in == NULL) {
- cs->in = cl;
} else {
- cs->inlast->next = cl;
- }
+ cl = ngx_alloc_chain_link(cc->pool);
+ if (cl == NULL) {
+ ngx_rtmp_netcall_close(cc);
+ return;
+ }
- cs->inlast = cl;
+ cl->next = NULL;
+
+ cl->buf = ngx_create_temp_buf(cc->pool, cs->bufsize);
+ if (cl->buf == NULL) {
+ ngx_rtmp_netcall_close(cc);
+ return;
+ }
+
+ if (cs->in == NULL) {
+ cs->in = cl;
+ } else {
+ cs->inlast->next = cl;
+ }
+
+ cs->inlast = cl;
+ }
}
b = cs->inlast->buf;
@@ -459,14 +491,17 @@ ngx_rtmp_netcall_send(ngx_event_t *wev)
ngx_chain_t *
-ngx_rtmp_netcall_http_format_header(ngx_url_t *url, ngx_pool_t *pool,
- size_t content_length, ngx_str_t *content_type)
+ngx_rtmp_netcall_http_format_header(ngx_int_t method, ngx_str_t *uri,
+ ngx_str_t *host, ngx_pool_t *pool,
+ size_t content_length,
+ ngx_str_t *content_type)
{
ngx_chain_t *cl;
ngx_buf_t *b;
+ const char *method_s;
static char rq_tmpl[] =
- "POST %V HTTP/1.0\r\n"
+ "%s %V HTTP/1.0\r\n"
"Host: %V\r\n"
"Content-Type: %V\r\n"
"Connection: Close\r\n"
@@ -480,8 +515,9 @@ ngx_rtmp_netcall_http_format_header(ngx_url_t *url, ngx_pool_t *pool,
}
b = ngx_create_temp_buf(pool, sizeof(rq_tmpl)
- + url->uri.len
- + url->host.len
+ + sizeof("POST") - 1 /* longest method */
+ + uri->len
+ + host->len
+ content_type->len
+ 5);
@@ -490,9 +526,21 @@ ngx_rtmp_netcall_http_format_header(ngx_url_t *url, ngx_pool_t *pool,
}
cl->buf = b;
+ cl->next = NULL;
+
+ switch (method) {
+ case NGX_RTMP_NETCALL_HTTP_GET:
+ method_s = "GET";
+ break;
+ case NGX_RTMP_NETCALL_HTTP_POST:
+ method_s = "POST";
+ break;
+ default:
+ return NULL;
+ }
b->last = ngx_snprintf(b->last, b->end - b->last, rq_tmpl,
- &url->uri, &url->host, content_type, content_length);
+ method_s, uri, host, content_type, content_length);
return cl;
}
View
13 ngx_rtmp_netcall_module.h
@@ -15,9 +15,14 @@
typedef ngx_chain_t * (*ngx_rtmp_netcall_create_pt)(ngx_rtmp_session_t *s,
void *arg, ngx_pool_t *pool);
typedef ngx_int_t (*ngx_rtmp_netcall_filter_pt)(ngx_chain_t *in);
+typedef ngx_int_t (*ngx_rtmp_netcall_sink_pt)(ngx_rtmp_session_t *s,
+ ngx_chain_t *in);
typedef ngx_int_t (*ngx_rtmp_netcall_handle_pt)(ngx_rtmp_session_t *s,
void *arg, ngx_chain_t *in);
+#define NGX_RTMP_NETCALL_HTTP_GET 1
+#define NGX_RTMP_NETCALL_HTTP_POST 2
+
/* If handle is NULL then netcall is created detached
* which means it's completely independent of RTMP
@@ -32,6 +37,7 @@ typedef struct {
ngx_url_t *url;
ngx_rtmp_netcall_create_pt create;
ngx_rtmp_netcall_filter_pt filter;
+ ngx_rtmp_netcall_sink_pt sink;
ngx_rtmp_netcall_handle_pt handle;
void *arg;
size_t argsize;
@@ -41,14 +47,13 @@ typedef struct {
ngx_int_t ngx_rtmp_netcall_create(ngx_rtmp_session_t *s,
ngx_rtmp_netcall_init_t *ci);
-extern ngx_str_t ngx_rtmp_netcall_content_type_urlencoded;
-
/* HTTP handling */
ngx_chain_t * ngx_rtmp_netcall_http_format_session(ngx_rtmp_session_t *s,
ngx_pool_t *pool);
-ngx_chain_t * ngx_rtmp_netcall_http_format_header(ngx_url_t *url,
- ngx_pool_t *pool, size_t content_length, ngx_str_t *content_type);
+ngx_chain_t * ngx_rtmp_netcall_http_format_header(ngx_int_t method,
+ ngx_str_t *uri, ngx_str_t *host, ngx_pool_t *pool,
+ size_t content_length, ngx_str_t *content_type);
ngx_chain_t * ngx_rtmp_netcall_http_skip_header(ngx_chain_t *in);
View
41 ngx_rtmp_notify_module.c
@@ -28,6 +28,10 @@ static ngx_int_t ngx_rtmp_notify_done(ngx_rtmp_session_t *s, char *cbname,
ngx_url_t *url);
+ngx_str_t ngx_rtmp_notify_urlencoded =
+ ngx_string("application/x-www-form-urlencoded");
+
+
#define NGX_RTMP_NOTIFY_PUBLISHING 0x01
#define NGX_RTMP_NOTIFY_PLAYING 0x02
@@ -190,6 +194,7 @@ ngx_rtmp_notify_publish_create(ngx_rtmp_session_t *s, void *arg,
ngx_chain_t *hl, *cl, *pl;
ngx_buf_t *b;
ngx_str_t *addr_text;
+ ngx_url_t *url;
size_t name_len, type_len, args_len;
nacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_notify_module);
@@ -215,7 +220,7 @@ ngx_rtmp_notify_publish_create(ngx_rtmp_session_t *s, void *arg,
b = ngx_create_temp_buf(pool,
sizeof("&call=publish") +
- sizeof("&addr=") + addr_text->len +
+ sizeof("&addr=") + addr_text->len *3 +
sizeof("&name=") + name_len * 3 +
sizeof("&type=") + type_len * 3 +
1 + args_len);
@@ -244,9 +249,11 @@ ngx_rtmp_notify_publish_create(ngx_rtmp_session_t *s, void *arg,
}
/* HTTP header */
- hl = ngx_rtmp_netcall_http_format_header(nacf->url[NGX_RTMP_NOTIFY_PUBLISH],
+ url = nacf->url[NGX_RTMP_NOTIFY_PUBLISH];
+ hl = ngx_rtmp_netcall_http_format_header(NGX_RTMP_NETCALL_HTTP_POST,
+ &url->uri, &url->host,
pool, cl->buf->last - cl->buf->pos + (pl->buf->last - pl->buf->pos),
- &ngx_rtmp_netcall_content_type_urlencoded);
+ &ngx_rtmp_notify_urlencoded);
if (hl == NULL) {
return NULL;
@@ -270,6 +277,7 @@ ngx_rtmp_notify_play_create(ngx_rtmp_session_t *s, void *arg,
ngx_chain_t *hl, *cl, *pl;
ngx_buf_t *b;
ngx_str_t *addr_text;
+ ngx_url_t *url;
size_t name_len, args_len;
nacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_notify_module);
@@ -294,7 +302,7 @@ ngx_rtmp_notify_play_create(ngx_rtmp_session_t *s, void *arg,
b = ngx_create_temp_buf(pool,
sizeof("&call=play") +
- sizeof("&addr=") + addr_text->len +
+ sizeof("&addr=") + addr_text->len * 3 +
sizeof("&name=") + name_len * 3 +
sizeof("&start=&duration=&reset=") + NGX_OFF_T_LEN * 3
+ 1 + args_len);
@@ -324,9 +332,11 @@ ngx_rtmp_notify_play_create(ngx_rtmp_session_t *s, void *arg,
}
/* HTTP header */
- hl = ngx_rtmp_netcall_http_format_header(nacf->url[NGX_RTMP_NOTIFY_PLAY],
+ url = nacf->url[NGX_RTMP_NOTIFY_PLAY];
+ hl = ngx_rtmp_netcall_http_format_header(NGX_RTMP_NETCALL_HTTP_POST,
+ &url->uri, &url->host,
pool, cl->buf->last - cl->buf->pos + (pl->buf->last - pl->buf->pos),
- &ngx_rtmp_netcall_content_type_urlencoded);
+ &ngx_rtmp_notify_urlencoded);
if (hl == NULL) {
return NULL;
@@ -374,7 +384,7 @@ ngx_rtmp_notify_done_create(ngx_rtmp_session_t *s, void *arg,
b = ngx_create_temp_buf(pool,
sizeof("&call=") + cbname_len +
- sizeof("&addr=") + addr_text->len +
+ sizeof("&addr=") + addr_text->len * 3 +
sizeof("&name=") + name_len * 3
+ 1 + args_len);
if (b == NULL) {
@@ -401,9 +411,10 @@ ngx_rtmp_notify_done_create(ngx_rtmp_session_t *s, void *arg,
}
/* HTTP header */
- hl = ngx_rtmp_netcall_http_format_header(ds->url, pool,
- cl->buf->last - cl->buf->pos + (pl->buf->last - pl->buf->pos),
- &ngx_rtmp_netcall_content_type_urlencoded);
+ hl = ngx_rtmp_netcall_http_format_header(NGX_RTMP_NETCALL_HTTP_POST,
+ &ds->url->uri, &ds->url->host,
+ pool, cl->buf->last - cl->buf->pos + (pl->buf->last - pl->buf->pos),
+ &ngx_rtmp_notify_urlencoded);
if (hl == NULL) {
return NULL;
@@ -428,6 +439,7 @@ ngx_rtmp_notify_record_done_create(ngx_rtmp_session_t *s, void *arg,
ngx_chain_t *hl, *cl, *pl;
ngx_buf_t *b;
ngx_str_t *addr_text;
+ ngx_url_t *url;
size_t name_len, args_len;
nacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_notify_module);
@@ -455,7 +467,7 @@ ngx_rtmp_notify_record_done_create(ngx_rtmp_session_t *s, void *arg,
b = ngx_create_temp_buf(pool,
sizeof("&call=record_done") +
sizeof("&recorder=") + v->recorder.len +
- sizeof("&addr=") + addr_text->len +
+ sizeof("&addr=") + addr_text->len *3 +
sizeof("&name=") + name_len * 3 +
sizeof("&path=") + v->path.len * 3 +
+ 1 + args_len);
@@ -489,10 +501,11 @@ ngx_rtmp_notify_record_done_create(ngx_rtmp_session_t *s, void *arg,
}
/* HTTP header */
- hl = ngx_rtmp_netcall_http_format_header(
- nacf->url[NGX_RTMP_NOTIFY_RECORD_DONE],
+ url = nacf->url[NGX_RTMP_NOTIFY_RECORD_DONE];
+ hl = ngx_rtmp_netcall_http_format_header(NGX_RTMP_NETCALL_HTTP_POST,
+ &url->uri, &url->host,
pool, cl->buf->last - cl->buf->pos + (pl->buf->last - pl->buf->pos),
- &ngx_rtmp_netcall_content_type_urlencoded);
+ &ngx_rtmp_notify_urlencoded);
if (hl == NULL) {
return NULL;
View
299 ngx_rtmp_play_module.c
@@ -5,6 +5,7 @@
#include "ngx_rtmp_play_module.h"
#include "ngx_rtmp_cmd_module.h"
+#include "ngx_rtmp_netcall_module.h"
#include "ngx_rtmp_streams.h"
@@ -14,6 +15,8 @@ static ngx_rtmp_seek_pt next_seek;
static ngx_rtmp_pause_pt next_pause;
+static char *ngx_rtmp_play_url(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
static void *ngx_rtmp_play_create_main_conf(ngx_conf_t *cf);
static ngx_int_t ngx_rtmp_play_postconfiguration(ngx_conf_t *cf);
static void * ngx_rtmp_play_create_app_conf(ngx_conf_t *cf);
@@ -24,15 +27,29 @@ static ngx_int_t ngx_rtmp_play_done(ngx_rtmp_session_t *s);
static ngx_int_t ngx_rtmp_play_start(ngx_rtmp_session_t *s, double timestamp);
static ngx_int_t ngx_rtmp_play_stop(ngx_rtmp_session_t *s);
static void ngx_rtmp_play_send(ngx_event_t *e);
+static ngx_int_t ngx_rtmp_play_open(ngx_rtmp_session_t *s, double start);
+static ngx_int_t ngx_rtmp_play_remote_handle(ngx_rtmp_session_t *s,
+ void *arg, ngx_chain_t *in);
+static ngx_chain_t * ngx_rtmp_play_remote_create(ngx_rtmp_session_t *s,
+ void *arg, ngx_pool_t *pool);
+static ngx_int_t ngx_rtmp_play_open_remote(ngx_rtmp_session_t *s,
+ ngx_rtmp_play_t *v);
static ngx_command_t ngx_rtmp_play_commands[] = {
{ ngx_string("play"),
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
+ ngx_rtmp_play_url,
+ NGX_RTMP_APP_CONF_OFFSET,
+ 0,
+ NULL },
+
+ { ngx_string("play_temp_path"),
+ NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_RTMP_APP_CONF_OFFSET,
- offsetof(ngx_rtmp_play_app_conf_t, root),
+ offsetof(ngx_rtmp_play_app_conf_t, temp_path),
NULL },
ngx_null_command
@@ -111,6 +128,7 @@ ngx_rtmp_play_merge_app_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_rtmp_play_app_conf_t *conf = child;
ngx_conf_merge_str_value(conf->root, prev->root, "");
+ ngx_conf_merge_str_value(conf->temp_path, prev->temp_path, "/tmp");
return NGX_CONF_OK;
}
@@ -352,7 +370,6 @@ ngx_rtmp_play_play(ngx_rtmp_session_t *s, ngx_rtmp_play_t *v)
ngx_rtmp_play_app_conf_t *pacf;
ngx_rtmp_play_ctx_t *ctx;
u_char *p;
- ngx_event_t *e;
ngx_rtmp_play_fmt_t *fmt, **pfmt;
ngx_str_t *pfx, *sfx;
ngx_str_t name;
@@ -364,7 +381,7 @@ ngx_rtmp_play_play(ngx_rtmp_session_t *s, ngx_rtmp_play_t *v)
pacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_play_module);
- if (pacf == NULL || pacf->root.len == 0) {
+ if (pacf == NULL || (pacf->root.len == 0 && pacf->url == NULL)) {
goto next;
}
@@ -441,8 +458,11 @@ ngx_rtmp_play_play(ngx_rtmp_session_t *s, ngx_rtmp_play_t *v)
goto next;
}
+ ctx->file.fd = NGX_INVALID_FILE;
+
ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
- "play: %V", &ctx->fmt->name);
+ "play %s: %V", pacf->url ? "remote" : "local",
+ &ctx->fmt->name);
sfx = &ctx->fmt->sfx;
@@ -454,6 +474,23 @@ ngx_rtmp_play_play(ngx_rtmp_session_t *s, ngx_rtmp_play_t *v)
sfx = &nosfx;
}
+ /* remote? */
+ if (pacf->url) {
+ ctx->name.data = ngx_palloc(s->connection->pool, name.len + sfx->len);
+ if (ctx->name.data == NULL) {
+ return NGX_ERROR;
+ }
+
+ p = ngx_sprintf(ctx->name.data, "%V%V", &name, sfx);
+ *p = 0;
+
+ ctx->name.len = p - ctx->name.data;
+
+ return ngx_rtmp_play_open_remote(s, v);
+ }
+
+ /* open local */
+
p = ngx_snprintf(path, sizeof(path), "%V/%V%V", &pacf->root, &name, sfx);
*p = 0;
@@ -461,13 +498,34 @@ ngx_rtmp_play_play(ngx_rtmp_session_t *s, ngx_rtmp_play_t *v)
NGX_FILE_DEFAULT_ACCESS);
if (ctx->file.fd == NGX_INVALID_FILE) {
- ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
+ ngx_log_error(NGX_LOG_ERR, s->connection->log, ngx_errno,
"play: error opening file '%s'", path);
return NGX_ERROR;
}
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
- "play: opened file '%s'", path);
+ "play: opened local file '%s'", path);
+
+ if (ngx_rtmp_play_open(s, v->start) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+next:
+ return next_play(s, v);
+}
+
+
+static ngx_int_t
+ngx_rtmp_play_open(ngx_rtmp_session_t *s, double start)
+{
+ ngx_rtmp_play_ctx_t *ctx;
+ ngx_event_t *e;
+
+ ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_play_module);
+
+ if (ctx->file.fd == NGX_INVALID_FILE) {
+ return NGX_ERROR;
+ }
e = &ctx->send_evt;
e->data = s;
@@ -480,12 +538,235 @@ ngx_rtmp_play_play(ngx_rtmp_session_t *s, ngx_rtmp_play_t *v)
return NGX_ERROR;
}
- if (ngx_rtmp_play_start(s, v->start) != NGX_OK) {
+ if (ngx_rtmp_play_start(s, start) != NGX_OK) {
return NGX_ERROR;
}
-next:
- return next_play(s, v);
+ return NGX_OK;
+}
+
+
+static ngx_chain_t *
+ngx_rtmp_play_remote_create(ngx_rtmp_session_t *s, void *arg, ngx_pool_t *pool)
+{
+ ngx_rtmp_play_t *v = arg;
+
+ ngx_rtmp_play_app_conf_t *pacf;
+ ngx_rtmp_play_ctx_t *ctx;
+ ngx_chain_t *hl;
+ ngx_str_t *addr_text, uri;
+ u_char *p;
+ size_t args_len, len;
+ static ngx_str_t text_plain = ngx_string("text/plain");
+
+ pacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_play_module);
+
+ ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_play_module);
+
+ args_len = ngx_strlen(v->args);
+ addr_text = &s->connection->addr_text;
+
+ len = pacf->url->uri.len + 1 + ctx->name.len +
+ sizeof("?addr=") + addr_text->len * 3 +
+ 1 + args_len;
+
+ uri.data = ngx_palloc(pool, len);
+ if (uri.data == NULL) {
+ return NULL;
+ }
+
+ p = uri.data;
+
+ p = ngx_cpymem(p, pacf->url->uri.data, pacf->url->uri.len);
+
+ if (p == uri.data || p[-1] != '/') {
+ *p++ = '/';
+ }
+
+ p = ngx_cpymem(p, ctx->name.data, ctx->name.len);
+ p = ngx_cpymem(p, (u_char*)"?addr=", sizeof("&addr=") -1);
+ p = (u_char*)ngx_escape_uri(p, addr_text->data, addr_text->len, 0);
+ if (args_len) {
+ *p++ = '&';
+ p = (u_char *) ngx_cpymem(p, v->args, args_len);
+ }
+
+ uri.len = p - uri.data;
+
+ /* HTTP header */
+ hl = ngx_rtmp_netcall_http_format_header(NGX_RTMP_NETCALL_HTTP_GET,
+ &uri, &pacf->url->host, pool, 0, &text_plain);
+
+ if (hl == NULL) {
+ return NULL;
+ }
+
+ return hl;
+}
+
+
+static ngx_int_t
+ngx_rtmp_play_remote_handle(ngx_rtmp_session_t *s, void *arg, ngx_chain_t *in)
+{
+ ngx_rtmp_play_t *v = arg;
+
+ if (ngx_rtmp_play_open(s, v->start) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ return next_play(s, (ngx_rtmp_play_t *)arg);
+}
+
+
+static ngx_int_t
+ngx_rtmp_play_remote_sink(ngx_rtmp_session_t *s, ngx_chain_t *in)
+{
+ ngx_rtmp_play_ctx_t *ctx;
+ ngx_buf_t *b;
+ ngx_int_t rc;
+
+ ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_play_module);
+
+ /* skip HTTP header */
+ while (in && ctx->ncrs != 2) {
+ b = in->buf;
+
+ for (; b->pos != b->last && ctx->ncrs != 2; ++b->pos) {
+ switch (*b->pos) {
+ case '\n':
+ ++ctx->ncrs;
+ case '\r':
+ break;
+ default:
+ ctx->ncrs = 0;
+ }
+ }
+
+ if (b->pos == b->last) {
+ in = in->next;
+ }
+ }
+
+ /* write to temp file */
+ for (; in; in = in->next) {
+ b = in->buf;
+
+ if (b->pos == b->last) {
+ continue;
+ }
+
+ rc = ngx_write_fd(ctx->file.fd, b->pos, b->last - b->pos);
+
+ if (rc == NGX_ERROR) {
+ ngx_log_error(NGX_LOG_INFO, s->connection->log, ngx_errno,
+ "play: error writing to temp file");
+ return NGX_ERROR;
+ }
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_rtmp_play_open_remote(ngx_rtmp_session_t *s, ngx_rtmp_play_t *v)
+{
+ ngx_rtmp_play_app_conf_t *pacf;
+ ngx_rtmp_play_ctx_t *ctx;
+ ngx_rtmp_netcall_init_t ci;
+ u_char *p;
+ ngx_err_t err;
+ static u_char path[NGX_MAX_PATH];
+ static ngx_uint_t counter;
+
+ pacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_play_module);
+
+ ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_play_module);
+
+ for ( ;; ) {
+ p = ngx_snprintf(path, sizeof(path), "%V/nginx-rtmp-play%ui",
+ &pacf->temp_path, counter++);
+ *p = 0;
+
+ ctx->file.fd = ngx_open_tempfile(path, 0, 0);
+
+ if (ctx->file.fd != NGX_INVALID_FILE) {
+ break;
+ }
+
+ err = ngx_errno;
+
+ if (err != NGX_EEXIST) {
+ ngx_log_error(NGX_LOG_INFO, s->connection->log, err,
+ "play: failed to create temp file");
+
+ return NGX_ERROR;
+ }
+ }
+
+ ngx_memzero(&ci, sizeof(ci));
+
+ ci.url = pacf->url;;
+ ci.create = ngx_rtmp_play_remote_create;
+ ci.sink = ngx_rtmp_play_remote_sink;
+ ci.handle = ngx_rtmp_play_remote_handle;
+ ci.arg = v;
+ ci.argsize = sizeof(*v);
+
+ return ngx_rtmp_netcall_create(s, &ci);
+}
+
+
+static char *
+ngx_rtmp_play_url(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_rtmp_play_app_conf_t *pacf = conf;
+
+ ngx_str_t url;
+ ngx_url_t *u;
+ size_t add;
+ ngx_str_t *value;
+
+ value = cf->args->elts;
+
+ if (ngx_strncasecmp(value[1].data, (u_char *) "http://", 7)) {
+
+ /* local file */
+
+ pacf->root = value[1];
+ return NGX_CONF_OK;
+ }
+
+ /* http case */
+
+ url = value[1];
+
+ add = sizeof("http://") - 1;
+
+ url.data += add;
+ url.len -= add;
+
+ u = ngx_pcalloc(cf->pool, sizeof(ngx_url_t));
+ if (u == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ u->url.len = url.len;
+ u->url.data = url.data;
+ u->default_port = 80;
+ u->uri_part = 1;
+
+ if (ngx_parse_url(cf->pool, u) != NGX_OK) {
+ if (u->err) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "%s in url \"%V\"", u->err, &u->url);
+ }
+ return NGX_CONF_ERROR;
+ }
+
+ pacf->url = u;
+
+ return NGX_CONF_OK;
}
View
4 ngx_rtmp_play_module.h
@@ -39,11 +39,15 @@ typedef struct {
ngx_file_t file;
ngx_rtmp_play_fmt_t *fmt;
ngx_event_t send_evt;
+ ngx_uint_t ncrs;
+ ngx_str_t name;
} ngx_rtmp_play_ctx_t;
typedef struct {
ngx_str_t root;
+ ngx_str_t temp_path;
+ ngx_url_t *url;
} ngx_rtmp_play_app_conf_t;

No commit comments for this range

Something went wrong with that request. Please try again.