[-]
[+]
|
Changed |
nginx-1.2.changes
|
|
[-]
[+]
|
Changed |
nginx-1.2.spec
^
|
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/CHANGES
^
|
@@ -1,4 +1,76 @@
+Changes with nginx 1.2.7 12 Feb 2013
+
+ *) Change: now if the "include" directive with mask is used on Unix
+ systems, included files are sorted in alphabetical order.
+
+ *) Change: the "add_header" directive adds headers to 201 responses.
+
+ *) Feature: the "geo" directive now supports IPv6 addresses in CIDR
+ notation.
+
+ *) Feature: the "flush" and "gzip" parameters of the "access_log"
+ directive.
+
+ *) Feature: variables support in the "auth_basic" directive.
+
+ *) Feature: the $pipe, $request_length, $time_iso8601, and $time_local
+ variables can now be used not only in the "log_format" directive.
+ Thanks to Kiril Kalchev.
+
+ *) Feature: IPv6 support in the ngx_http_geoip_module.
+ Thanks to Gregor Kališnik.
+
+ *) Bugfix: nginx could not be built with the ngx_http_perl_module in
+ some cases.
+
+ *) Bugfix: a segmentation fault might occur in a worker process if the
+ ngx_http_xslt_module was used.
+
+ *) Bugfix: nginx could not be built on MacOSX in some cases.
+ Thanks to Piotr Sikora.
+
+ *) Bugfix: the "limit_rate" directive with high rates might result in
+ truncated responses on 32-bit platforms.
+ Thanks to Alexey Antropov.
+
+ *) Bugfix: a segmentation fault might occur in a worker process if the
+ "if" directive was used.
+ Thanks to Piotr Sikora.
+
+ *) Bugfix: a "100 Continue" response was issued with "413 Request Entity
+ Too Large" responses.
+
+ *) Bugfix: the "image_filter", "image_filter_jpeg_quality" and
+ "image_filter_sharpen" directives might be inherited incorrectly.
+ Thanks to Ian Babrou.
+
+ *) Bugfix: "crypt_r() failed" errors might appear if the "auth_basic"
+ directive was used on Linux.
+
+ *) Bugfix: in backup servers handling.
+ Thanks to Thomas Chen.
+
+ *) Bugfix: proxied HEAD requests might return incorrect response if the
+ "gzip" directive was used.
+
+ *) Bugfix: a segmentation fault occurred on start or during
+ reconfiguration if the "keepalive" directive was specified more than
+ once in a single upstream block.
+
+ *) Bugfix: in the "proxy_method" directive.
+
+ *) Bugfix: a segmentation fault might occur in a worker process if
+ resolver was used with the poll method.
+
+ *) Bugfix: nginx might hog CPU during SSL handshake with a backend if
+ the select, poll, or /dev/poll methods were used.
+
+ *) Bugfix: the "[crit] SSL_write() failed (SSL:)" error.
+
+ *) Bugfix: in the "fastcgi_keep_conn" directive.
+
+
Changes with nginx 1.2.6 11 Dec 2012
*) Feature: the $request_time and $msec variables can now be used not
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/CHANGES.ru
^
|
@@ -1,4 +1,80 @@
+Изменения в nginx 1.2.7 12.02.2013
+
+ *) Изменение: теперь при использовании директивы include с маской на
+ Unix-системах включаемые файлы сортируются в алфавитном порядке.
+
+ *) Изменение: директива add_header добавляет строки в ответы с кодом
+ 201.
+
+ *) Добавление: директива geo теперь поддерживает IPv6 адреса в формате
+ CIDR.
+
+ *) Добавление: параметры flush и gzip в директиве access_log.
+
+ *) Добавление: директива auth_basic поддерживает переменные.
+
+ *) Добавление: переменные $pipe, $request_length, $time_iso8601 и
+ $time_local теперь можно использовать не только в директиве
+ log_format.
+ Спасибо Kiril Kalchev.
+
+ *) Добавление: поддержка IPv6 в модуле ngx_http_geoip_module.
+ Спасибо Gregor Kališnik.
+
+ *) Исправление: nginx в некоторых случаях не собирался с модулем
+ ngx_http_perl_module.
+
+ *) Исправление: в рабочем процессе мог произойти segmentation fault,
+ если использовался модуль ngx_http_xslt_module.
+
+ *) Исправление: nginx мог не собираться на MacOSX.
+ Спасибо Piotr Sikora.
+
+ *) Исправление: при использовании директивы limit_rate с большими
+ значениями скорости на 32-битных системах ответ мог возвращаться не
+ целиком.
+ Спасибо Алексею Антропову.
+
+ *) Исправление: в рабочем процессе мог произойти segmentation fault,
+ если использовалась директива if.
+ Спасибо Piotr Sikora.
+
+ *) Исправление: ответ "100 Continue" выдавался вместе с ответом "413
+ Request Entity Too Large".
+
+ *) Исправление: директивы image_filter, image_filter_jpeg_quality и
+ image_filter_sharpen могли наследоваться некорректно.
+ Спасибо Ивану Боброву.
+
+ *) Исправление: при использовании директивы auth_basic под Linux могли
+ возникать ошибки "crypt_r() failed".
+
+ *) Исправление: в обработке backup-серверов.
+ Спасибо Thomas Chen.
+
+ *) Исправление: при проксировании HEAD-запросов мог возвращаться
+ некорректный ответ, если использовалась директива gzip.
+
+ *) Исправление: на старте или во время переконфигурации происходил
+ segmentation fault, если директива keepalive была указана несколько
+ раз в одном блоке upstream.
+
+ *) Исправление: директива proxy_method работала неверно, если была
+ указана на уровне http.
+
+ *) Исправление: в рабочем процессе мог произойти segmentation fault,
+ если использовался resolver и метод poll.
+
+ *) Исправление: nginx мог нагружать процессор во время SSL handshake с
+ бэкендом при использовании методов обработки соединений select, poll
+ и /dev/poll.
+
+ *) Исправление: ошибка "[crit] SSL_write() failed (SSL:)".
+
+ *) Исправление: в директиве fastcgi_keep_conn.
+
+
Изменения в nginx 1.2.6 11.12.2012
*) Добавление: переменные $request_time и $msec теперь можно
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/LICENSE
^
|
@@ -1,6 +1,6 @@
/*
- * Copyright (C) 2002-2012 Igor Sysoev
- * Copyright (C) 2011,2012 Nginx, Inc.
+ * Copyright (C) 2002-2013 Igor Sysoev
+ * Copyright (C) 2011-2013 Nginx, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/auto/cc/msvc
^
|
@@ -73,9 +73,6 @@
# disable logo
CFLAGS="$CFLAGS -nologo"
-
-LINK="\$(CC)"
-
# the link flags
CORE_LINK="$CORE_LINK -link -verbose:lib"
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/auto/lib/geoip/conf
^
|
@@ -6,7 +6,7 @@
ngx_feature="GeoIP library"
ngx_feature_name=
ngx_feature_run=no
- ngx_feature_incs=
+ ngx_feature_incs="#include <GeoIP.h>"
ngx_feature_path=
ngx_feature_libs="-lGeoIP"
ngx_feature_test="GeoIP_open(NULL, 0)"
@@ -18,6 +18,7 @@
# FreeBSD port
ngx_feature="GeoIP library in /usr/local/"
+ ngx_feature_path="/usr/local/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lGeoIP"
@@ -34,7 +35,7 @@
# NetBSD port
ngx_feature="GeoIP library in /usr/pkg/"
- ngx_feature_path="/usr/pkg/include/"
+ ngx_feature_path="/usr/pkg/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lGeoIP"
@@ -64,8 +65,22 @@
if [ $ngx_found = yes ]; then
+
+ CORE_INCS="$CORE_INCS $ngx_feature_path"
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
+ if [ $NGX_IPV6 = YES ]; then
+ ngx_feature="GeoIP IPv6 support"
+ ngx_feature_name="NGX_HAVE_GEOIP_V6"
+ ngx_feature_run=no
+ ngx_feature_incs="#include <stdio.h>
+ #include <GeoIP.h>"
+ #ngx_feature_path=
+ #ngx_feature_libs=
+ ngx_feature_test="printf(\"%d\", GEOIP_CITY_EDITION_REV0_V6);"
+ . auto/feature
+ fi
+
else
cat << END
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/auto/lib/libgd/conf
^
|
@@ -35,7 +35,7 @@
# NetBSD port
ngx_feature="GD library in /usr/pkg/"
- ngx_feature_path="/usr/pkg/include/"
+ ngx_feature_path="/usr/pkg/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lgd"
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/auto/lib/pcre/conf
^
|
@@ -172,6 +172,7 @@
ngx_feature="PCRE JIT support"
ngx_feature_name="NGX_HAVE_PCRE_JIT"
ngx_feature_test="int jit = 0;
+ pcre_free_study(NULL);
pcre_config(PCRE_CONFIG_JIT, &jit);
if (jit != 1) return 1;"
. auto/feature
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/auto/lib/perl/make
^
|
@@ -26,9 +26,7 @@
cd $NGX_OBJS/src/http/modules/perl \
&& NGX_PM_CFLAGS="\$(NGX_PM_CFLAGS) -g $NGX_CC_OPT" \
- NGX_PCRE=$PCRE \
- NGX_OBJS=$NGX_OBJS \
- NGX_OPENSSL=$OPENSSL \
+ NGX_INCS="$CORE_INCS $NGX_OBJS $HTTP_INCS" \
$NGX_PERL Makefile.PL \
LIB=$NGX_PERL_MODULES \
INSTALLSITEMAN3DIR=$NGX_PERL_MODULES_MAN
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/auto/lib/zlib/conf
^
|
@@ -9,11 +9,13 @@
case "$NGX_CC_NAME" in
msvc* | owc* | bcc)
+ have=NGX_ZLIB . auto/have
LINK_DEPS="$LINK_DEPS $ZLIB/zlib.lib"
CORE_LIBS="$CORE_LIBS $ZLIB/zlib.lib"
;;
icc*)
+ have=NGX_ZLIB . auto/have
LINK_DEPS="$LINK_DEPS $ZLIB/libz.a"
# to allow -ipo optimization we link with the *.o but not library
@@ -30,6 +32,7 @@
;;
*)
+ have=NGX_ZLIB . auto/have
LINK_DEPS="$LINK_DEPS $ZLIB/libz.a"
CORE_LIBS="$CORE_LIBS $ZLIB/libz.a"
#CORE_LIBS="$CORE_LIBS -L $ZLIB -lz"
@@ -45,7 +48,7 @@
# FreeBSD, Solaris, Linux
ngx_feature="zlib library"
- ngx_feature_name=
+ ngx_feature_name="NGX_ZLIB"
ngx_feature_run=no
ngx_feature_incs="#include <zlib.h>"
ngx_feature_path=
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/man/nginx.8
^
|
@@ -1,6 +1,6 @@
.\"
-.\" Copyright (c) 2010 Sergey A. Osokin
-.\" Copyright (c) 2011,2012 Nginx, Inc.
+.\" Copyright (C) 2010 Sergey A. Osokin
+.\" Copyright (C) Nginx, Inc.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/core/nginx.h
^
|
@@ -9,8 +9,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 1002006
-#define NGINX_VERSION "1.2.6"
+#define nginx_version 1002007
+#define NGINX_VERSION "1.2.7"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/core/ngx_conf_file.c
^
|
@@ -945,7 +945,8 @@
file->name = *name;
}
- file->buffer = NULL;
+ file->flush = NULL;
+ file->data = NULL;
return file;
}
@@ -954,7 +955,6 @@
static void
ngx_conf_flush_files(ngx_cycle_t *cycle)
{
- ssize_t n, len;
ngx_uint_t i;
ngx_list_part_t *part;
ngx_open_file_t *file;
@@ -975,23 +975,8 @@
i = 0;
}
- len = file[i].pos - file[i].buffer;
-
- if (file[i].buffer == NULL || len == 0) {
- continue;
- }
-
- n = ngx_write_fd(file[i].fd, file[i].buffer, len);
-
- if (n == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- ngx_write_fd_n " to \"%s\" failed",
- file[i].name.data);
-
- } else if (n != len) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz",
- file[i].name.data, n, len);
+ if (file[i].flush) {
+ file[i].flush(&file[i], cycle->log);
}
}
}
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/core/ngx_conf_file.h
^
|
@@ -91,17 +91,8 @@
ngx_fd_t fd;
ngx_str_t name;
- u_char *buffer;
- u_char *pos;
- u_char *last;
-
-#if 0
- /* e.g. append mode, error_log */
- ngx_uint_t flags;
- /* e.g. reopen db file */
- ngx_uint_t (*handler)(void *data, ngx_open_file_t *file);
+ void (*flush)(ngx_open_file_t *file, ngx_log_t *log);
void *data;
-#endif
};
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/core/ngx_cycle.c
^
|
@@ -1115,7 +1115,6 @@
void
ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user)
{
- ssize_t n, len;
ngx_fd_t fd;
ngx_uint_t i;
ngx_list_part_t *part;
@@ -1139,24 +1138,8 @@
continue;
}
- len = file[i].pos - file[i].buffer;
-
- if (file[i].buffer && len != 0) {
-
- n = ngx_write_fd(file[i].fd, file[i].buffer, len);
-
- if (n == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- ngx_write_fd_n " to \"%s\" failed",
- file[i].name.data);
-
- } else if (n != len) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz",
- file[i].name.data, n, len);
- }
-
- file[i].pos = file[i].buffer;
+ if (file[i].flush) {
+ file[i].flush(&file[i], cycle->log);
}
fd = ngx_open_file(file[i].name.data, NGX_FILE_APPEND,
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/core/ngx_file.c
^
|
@@ -732,14 +732,14 @@
n = ngx_read_fd(fd, buf, len);
- if (n == NGX_FILE_ERROR) {
+ if (n == -1) {
ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
ngx_read_fd_n " \"%s\" failed", from);
goto failed;
}
if ((size_t) n != len) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+ ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
ngx_read_fd_n " has read only %z of %uz from %s",
n, size, from);
goto failed;
@@ -747,14 +747,14 @@
n = ngx_write_fd(nfd, buf, len);
- if (n == NGX_FILE_ERROR) {
+ if (n == -1) {
ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
ngx_write_fd_n " \"%s\" failed", to);
goto failed;
}
if ((size_t) n != len) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+ ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
ngx_write_fd_n " has written only %z of %uz to %s",
n, size, to);
goto failed;
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/core/ngx_inet.c
^
|
@@ -465,7 +465,7 @@
* prevent MSVC8 warning:
* potentially uninitialized local variable 'inaddr6' used
*/
- ngx_memzero(inaddr6.s6_addr, sizeof(struct in6_addr));
+ ngx_memzero(&inaddr6, sizeof(struct in6_addr));
#endif
inaddr = ngx_inet_addr(text, len);
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/core/ngx_inet.h
^
|
@@ -30,7 +30,7 @@
#if (NGX_HAVE_UNIX_DOMAIN)
#define NGX_SOCKADDR_STRLEN (sizeof("unix:") - 1 + NGX_UNIX_ADDRSTRLEN)
#else
-#define NGX_SOCKADDR_STRLEN (NGX_INET6_ADDRSTRLEN + sizeof(":65535") - 1)
+#define NGX_SOCKADDR_STRLEN (NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1)
#endif
#if (NGX_HAVE_UNIX_DOMAIN)
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/core/ngx_radix_tree.c
^
|
@@ -9,7 +9,7 @@
#include <ngx_core.h>
-static void *ngx_radix_alloc(ngx_radix_tree_t *tree);
+static ngx_radix_node_t *ngx_radix_alloc(ngx_radix_tree_t *tree);
ngx_radix_tree_t *
@@ -263,13 +263,210 @@
}
-static void *
+#if (NGX_HAVE_INET6)
+
+ngx_int_t
+ngx_radix128tree_insert(ngx_radix_tree_t *tree, u_char *key, u_char *mask,
+ uintptr_t value)
+{
+ u_char bit;
+ ngx_uint_t i;
+ ngx_radix_node_t *node, *next;
+
+ i = 0;
+ bit = 0x80;
+
+ node = tree->root;
+ next = tree->root;
+
+ while (bit & mask[i]) {
+ if (key[i] & bit) {
+ next = node->right;
+
+ } else {
+ next = node->left;
+ }
+
+ if (next == NULL) {
+ break;
+ }
+
+ bit >>= 1;
+ node = next;
+
+ if (bit == 0) {
+ if (++i == 16) {
+ break;
+ }
+
+ bit = 0x80;
+ }
+ }
+
+ if (next) {
+ if (node->value != NGX_RADIX_NO_VALUE) {
+ return NGX_BUSY;
+ }
+
+ node->value = value;
+ return NGX_OK;
+ }
+
+ while (bit & mask[i]) {
+ next = ngx_radix_alloc(tree);
+ if (next == NULL) {
+ return NGX_ERROR;
+ }
+
+ next->right = NULL;
+ next->left = NULL;
+ next->parent = node;
+ next->value = NGX_RADIX_NO_VALUE;
+
+ if (key[i] & bit) {
+ node->right = next;
+
+ } else {
+ node->left = next;
+ }
+
+ bit >>= 1;
+ node = next;
+
+ if (bit == 0) {
+ if (++i == 16) {
+ break;
+ }
+
+ bit = 0x80;
+ }
+ }
+
+ node->value = value;
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_radix128tree_delete(ngx_radix_tree_t *tree, u_char *key, u_char *mask)
+{
+ u_char bit;
+ ngx_uint_t i;
+ ngx_radix_node_t *node;
+
+ i = 0;
+ bit = 0x80;
+ node = tree->root;
+
+ while (node && (bit & mask[i])) {
+ if (key[i] & bit) {
+ node = node->right;
+
+ } else {
+ node = node->left;
+ }
+
+ bit >>= 1;
+
+ if (bit == 0) {
+ if (++i == 16) {
+ break;
+ }
+
+ bit = 0x80;
+ }
+ }
+
+ if (node == NULL) {
+ return NGX_ERROR;
+ }
+
+ if (node->right || node->left) {
+ if (node->value != NGX_RADIX_NO_VALUE) {
+ node->value = NGX_RADIX_NO_VALUE;
+ return NGX_OK;
+ }
+
+ return NGX_ERROR;
+ }
+
+ for ( ;; ) {
+ if (node->parent->right == node) {
+ node->parent->right = NULL;
+
+ } else {
+ node->parent->left = NULL;
+ }
+
+ node->right = tree->free;
+ tree->free = node;
+
+ node = node->parent;
+
+ if (node->right || node->left) {
+ break;
+ }
+
+ if (node->value != NGX_RADIX_NO_VALUE) {
+ break;
+ }
+
+ if (node->parent == NULL) {
+ break;
+ }
+ }
+
+ return NGX_OK;
+}
+
+
+uintptr_t
+ngx_radix128tree_find(ngx_radix_tree_t *tree, u_char *key)
+{
+ u_char bit;
+ uintptr_t value;
+ ngx_uint_t i;
+ ngx_radix_node_t *node;
+
+ i = 0;
+ bit = 0x80;
+ value = NGX_RADIX_NO_VALUE;
+ node = tree->root;
+
+ while (node) {
+ if (node->value != NGX_RADIX_NO_VALUE) {
+ value = node->value;
+ }
+
+ if (key[i] & bit) {
+ node = node->right;
+
+ } else {
+ node = node->left;
+ }
+
+ bit >>= 1;
+
+ if (bit == 0) {
+ i++;
+ bit = 0x80;
+ }
+ }
+
+ return value;
+}
+
+#endif
+
+
+static ngx_radix_node_t *
ngx_radix_alloc(ngx_radix_tree_t *tree)
{
- char *p;
+ ngx_radix_node_t *p;
if (tree->free) {
- p = (char *) tree->free;
+ p = tree->free;
tree->free = tree->free->right;
return p;
}
@@ -283,7 +480,7 @@
tree->size = ngx_pagesize;
}
- p = tree->start;
+ p = (ngx_radix_node_t *) tree->start;
tree->start += sizeof(ngx_radix_node_t);
tree->size -= sizeof(ngx_radix_node_t);
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/core/ngx_radix_tree.h
^
|
@@ -36,11 +36,20 @@
ngx_radix_tree_t *ngx_radix_tree_create(ngx_pool_t *pool,
ngx_int_t preallocate);
+
ngx_int_t ngx_radix32tree_insert(ngx_radix_tree_t *tree,
uint32_t key, uint32_t mask, uintptr_t value);
ngx_int_t ngx_radix32tree_delete(ngx_radix_tree_t *tree,
uint32_t key, uint32_t mask);
uintptr_t ngx_radix32tree_find(ngx_radix_tree_t *tree, uint32_t key);
+#if (NGX_HAVE_INET6)
+ngx_int_t ngx_radix128tree_insert(ngx_radix_tree_t *tree,
+ u_char *key, u_char *mask, uintptr_t value);
+ngx_int_t ngx_radix128tree_delete(ngx_radix_tree_t *tree,
+ u_char *key, u_char *mask);
+uintptr_t ngx_radix128tree_find(ngx_radix_tree_t *tree, u_char *key);
+#endif
+
#endif /* _NGX_RADIX_TREE_H_INCLUDED_ */
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/event/modules/ngx_poll_module.c
^
|
@@ -371,7 +371,7 @@
found = 0;
- if (revents & POLLIN) {
+ if ((revents & POLLIN) && c->read->active) {
found = 1;
ev = c->read;
@@ -388,7 +388,7 @@
ngx_locked_post_event(ev, queue);
}
- if (revents & POLLOUT) {
+ if ((revents & POLLOUT) && c->write->active) {
found = 1;
ev = c->write;
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/event/ngx_event.c
^
|
@@ -892,6 +892,10 @@
ngx_conf_t pcf;
ngx_event_module_t *m;
+ if (*(void **) conf) {
+ return "is duplicate";
+ }
+
/* count the number of the event modules and set up their indices */
ngx_event_max_module = 0;
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/event/ngx_event_openssl.c
^
|
@@ -528,10 +528,10 @@
return NGX_ERROR;
}
- SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh);
-
SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE);
+ SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh);
+
EC_KEY_free(ecdh);
#endif
#endif
@@ -693,6 +693,10 @@
return NGX_ERROR;
}
+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
return NGX_AGAIN;
}
@@ -701,6 +705,10 @@
c->read->handler = ngx_ssl_handshake_handler;
c->write->handler = ngx_ssl_handshake_handler;
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
return NGX_ERROR;
}
@@ -1053,8 +1061,8 @@
buf->end = buf->start + NGX_SSL_BUFSIZE;
}
- send = 0;
- flush = (in == NULL) ? 1 : 0;
+ send = buf->last - buf->pos;
+ flush = (in == NULL) ? 1 : buf->flush;
for ( ;; ) {
@@ -1076,7 +1084,6 @@
if (send + size > limit) {
size = (ssize_t) (limit - send);
- flush = 1;
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
@@ -1093,10 +1100,16 @@
}
}
+ if (!flush && send < limit && buf->last < buf->end) {
+ break;
+ }
+
size = buf->last - buf->pos;
- if (!flush && buf->last < buf->end && c->ssl->buffer) {
- break;
+ if (size == 0) {
+ buf->flush = 0;
+ c->buffered &= ~NGX_SSL_BUFFERED;
+ return in;
}
n = ngx_ssl_write(c, buf->pos, size);
@@ -1106,8 +1119,7 @@
}
if (n == NGX_AGAIN) {
- c->buffered |= NGX_SSL_BUFFERED;
- return in;
+ break;
}
buf->pos += n;
@@ -1117,16 +1129,18 @@
break;
}
- if (buf->pos == buf->last) {
- buf->pos = buf->start;
- buf->last = buf->start;
- }
+ flush = 0;
+
+ buf->pos = buf->start;
+ buf->last = buf->start;
if (in == NULL || send == limit) {
break;
}
}
+ buf->flush = flush;
+
if (buf->pos < buf->last) {
c->buffered |= NGX_SSL_BUFFERED;
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/ngx_http_auth_basic_module.c
^
|
@@ -20,8 +20,8 @@
typedef struct {
- ngx_str_t realm;
- ngx_http_complex_value_t user_file;
+ ngx_http_complex_value_t *realm;
+ ngx_http_complex_value_t user_file;
} ngx_http_auth_basic_loc_conf_t;
@@ -35,22 +35,19 @@
static char *ngx_http_auth_basic_merge_loc_conf(ngx_conf_t *cf,
void *parent, void *child);
static ngx_int_t ngx_http_auth_basic_init(ngx_conf_t *cf);
-static char *ngx_http_auth_basic(ngx_conf_t *cf, void *post, void *data);
static char *ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
-static ngx_conf_post_handler_pt ngx_http_auth_basic_p = ngx_http_auth_basic;
-
static ngx_command_t ngx_http_auth_basic_commands[] = {
{ ngx_string("auth_basic"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF
|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
+ ngx_http_set_complex_value_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_auth_basic_loc_conf_t, realm),
- &ngx_http_auth_basic_p },
+ NULL },
{ ngx_string("auth_basic_user_file"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF
@@ -103,7 +100,7 @@
ngx_fd_t fd;
ngx_int_t rc;
ngx_err_t err;
- ngx_str_t pwd, user_file;
+ ngx_str_t pwd, realm, user_file;
ngx_uint_t i, level, login, left, passwd;
ngx_file_t file;
ngx_http_auth_basic_ctx_t *ctx;
@@ -117,7 +114,15 @@
alcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_basic_module);
- if (alcf->realm.len == 0 || alcf->user_file.value.len == 0) {
+ if (alcf->realm == NULL || alcf->user_file.value.data == NULL) {
+ return NGX_DECLINED;
+ }
+
+ if (ngx_http_complex_value(r, alcf->realm, &realm) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ if (realm.len == 3 && ngx_strncmp(realm.data, "off", 3) == 0) {
return NGX_DECLINED;
}
@@ -125,7 +130,7 @@
if (ctx) {
return ngx_http_auth_basic_crypt_handler(r, ctx, &ctx->passwd,
- &alcf->realm);
+ &realm);
}
rc = ngx_http_auth_basic_user(r);
@@ -135,7 +140,7 @@
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"no user/password was provided for basic authentication");
- return ngx_http_auth_basic_set_realm(r, &alcf->realm);
+ return ngx_http_auth_basic_set_realm(r, &realm);
}
if (rc == NGX_ERROR) {
@@ -233,7 +238,7 @@
pwd.data = &buf[passwd];
return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd,
- &alcf->realm);
+ &realm);
}
break;
@@ -271,14 +276,14 @@
ngx_cpystrn(pwd.data, &buf[passwd], pwd.len + 1);
- return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd, &alcf->realm);
+ return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd, &realm);
}
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"user \"%V\" was not found in \"%V\"",
&r->headers_in.user, &user_file);
- return ngx_http_auth_basic_set_realm(r, &alcf->realm);
+ return ngx_http_auth_basic_set_realm(r, &realm);
}
@@ -344,14 +349,29 @@
static ngx_int_t
ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm)
{
+ size_t len;
+ u_char *basic, *p;
+
r->headers_out.www_authenticate = ngx_list_push(&r->headers_out.headers);
if (r->headers_out.www_authenticate == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
+ len = sizeof("Basic realm=\"\"") - 1 + realm->len;
+
+ basic = ngx_pnalloc(r->pool, len);
+ if (basic == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ p = ngx_cpymem(basic, "Basic realm=\"", sizeof("Basic realm=\"") - 1);
+ p = ngx_cpymem(p, realm->data, realm->len);
+ *p = '"';
+
r->headers_out.www_authenticate->hash = 1;
ngx_str_set(&r->headers_out.www_authenticate->key, "WWW-Authenticate");
- r->headers_out.www_authenticate->value = *realm;
+ r->headers_out.www_authenticate->value.data = basic;
+ r->headers_out.www_authenticate->value.len = len;
return NGX_HTTP_UNAUTHORIZED;
}
@@ -386,11 +406,11 @@
ngx_http_auth_basic_loc_conf_t *prev = parent;
ngx_http_auth_basic_loc_conf_t *conf = child;
- if (conf->realm.data == NULL) {
+ if (conf->realm == NULL) {
conf->realm = prev->realm;
}
- if (conf->user_file.value.len == 0) {
+ if (conf->user_file.value.data == NULL) {
conf->user_file = prev->user_file;
}
@@ -418,37 +438,6 @@
static char *
-ngx_http_auth_basic(ngx_conf_t *cf, void *post, void *data)
-{
- ngx_str_t *realm = data;
-
- size_t len;
- u_char *basic, *p;
-
- if (ngx_strcmp(realm->data, "off") == 0) {
- ngx_str_set(realm, "");
- return NGX_CONF_OK;
- }
-
- len = sizeof("Basic realm=\"") - 1 + realm->len + 1;
-
- basic = ngx_pnalloc(cf->pool, len);
- if (basic == NULL) {
- return NGX_CONF_ERROR;
- }
-
- p = ngx_cpymem(basic, "Basic realm=\"", sizeof("Basic realm=\"") - 1);
- p = ngx_cpymem(p, realm->data, realm->len);
- *p = '"';
-
- realm->len = len;
- realm->data = basic;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_auth_basic_loc_conf_t *alcf = conf;
@@ -456,7 +445,7 @@
ngx_str_t *value;
ngx_http_compile_complex_value_t ccv;
- if (alcf->user_file.value.len) {
+ if (alcf->user_file.value.data) {
return "is duplicate";
}
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/ngx_http_fastcgi_module.c
^
|
@@ -1356,11 +1356,7 @@
}
} else {
- if (f->padding) {
- f->state = ngx_http_fastcgi_st_padding;
- } else {
- f->state = ngx_http_fastcgi_st_version;
- }
+ f->state = ngx_http_fastcgi_st_padding;
}
continue;
@@ -1597,11 +1593,7 @@
f->length -= u->buffer.pos - start;
if (f->length == 0) {
- if (f->padding) {
- f->state = ngx_http_fastcgi_st_padding;
- } else {
- f->state = ngx_http_fastcgi_st_version;
- }
+ f->state = ngx_http_fastcgi_st_padding;
}
if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
@@ -1696,12 +1688,7 @@
}
if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) {
-
- if (f->padding) {
- f->state = ngx_http_fastcgi_st_padding;
- } else {
- f->state = ngx_http_fastcgi_st_version;
- }
+ f->state = ngx_http_fastcgi_st_padding;
if (!flcf->keep_conn) {
p->upstream_done = 1;
@@ -1715,27 +1702,38 @@
if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
- if (f->padding) {
- f->state = ngx_http_fastcgi_st_padding;
- } else {
- f->state = ngx_http_fastcgi_st_version;
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
+ "http fastcgi sent end request");
+
+ if (!flcf->keep_conn) {
+ p->upstream_done = 1;
+ break;
}
- p->upstream_done = 1;
+ continue;
+ }
+ }
+
+
+ if (f->state == ngx_http_fastcgi_st_padding) {
+
+ if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
- if (flcf->keep_conn) {
+ if (f->pos + f->padding < f->last) {
+ p->upstream_done = 1;
+ break;
+ }
+
+ if (f->pos + f->padding == f->last) {
+ p->upstream_done = 1;
r->upstream->keepalive = 1;
+ break;
}
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
- "http fastcgi sent end request");
+ f->padding -= f->last - f->pos;
break;
}
- }
-
-
- if (f->state == ngx_http_fastcgi_st_padding) {
if (f->pos + f->padding < f->last) {
f->state = ngx_http_fastcgi_st_version;
@@ -1788,21 +1786,27 @@
"FastCGI sent in stderr: \"%*s\"",
m + 1 - msg, msg);
- if (f->pos == f->last) {
- break;
- }
-
} else {
- if (f->padding) {
- f->state = ngx_http_fastcgi_st_padding;
- } else {
- f->state = ngx_http_fastcgi_st_version;
- }
+ f->state = ngx_http_fastcgi_st_padding;
}
continue;
}
+ if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
+
+ if (f->pos + f->length <= f->last) {
+ f->state = ngx_http_fastcgi_st_padding;
+ f->pos += f->length;
+
+ continue;
+ }
+
+ f->length -= f->last - f->pos;
+
+ break;
+ }
+
/* f->type == NGX_HTTP_FASTCGI_STDOUT */
@@ -1856,33 +1860,14 @@
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0,
"input buf #%d %p", b->num, b->pos);
- if (f->pos + f->length < f->last) {
-
- if (f->padding) {
- f->state = ngx_http_fastcgi_st_padding;
- } else {
- f->state = ngx_http_fastcgi_st_version;
- }
-
+ if (f->pos + f->length <= f->last) {
+ f->state = ngx_http_fastcgi_st_padding;
f->pos += f->length;
b->last = f->pos;
continue;
}
- if (f->pos + f->length == f->last) {
-
- if (f->padding) {
- f->state = ngx_http_fastcgi_st_padding;
- } else {
- f->state = ngx_http_fastcgi_st_version;
- }
-
- b->last = f->last;
-
- break;
- }
-
f->length -= f->last - f->pos;
b->last = f->last;
@@ -3014,7 +2999,7 @@
value = cf->args->elts;
- if (flcf->cache_key.value.len) {
+ if (flcf->cache_key.value.data) {
return "is duplicate";
}
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/ngx_http_geo_module.c
^
|
@@ -18,6 +18,14 @@
typedef struct {
+ ngx_radix_tree_t *tree;
+#if (NGX_HAVE_INET6)
+ ngx_radix_tree_t *tree6;
+#endif
+} ngx_http_geo_trees_t;
+
+
+typedef struct {
ngx_http_geo_range_t **low;
ngx_http_variable_value_t *default_value;
} ngx_http_geo_high_ranges_t;
@@ -35,6 +43,9 @@
ngx_str_t *net;
ngx_http_geo_high_ranges_t high;
ngx_radix_tree_t *tree;
+#if (NGX_HAVE_INET6)
+ ngx_radix_tree_t *tree6;
+#endif
ngx_rbtree_t rbtree;
ngx_rbtree_node_t sentinel;
ngx_array_t *proxies;
@@ -57,7 +68,7 @@
typedef struct {
union {
- ngx_radix_tree_t *tree;
+ ngx_http_geo_trees_t trees;
ngx_http_geo_high_ranges_t high;
} u;
@@ -68,8 +79,8 @@
} ngx_http_geo_ctx_t;
-static in_addr_t ngx_http_geo_addr(ngx_http_request_t *r,
- ngx_http_geo_ctx_t *ctx);
+static ngx_int_t ngx_http_geo_addr(ngx_http_request_t *r,
+ ngx_http_geo_ctx_t *ctx, ngx_addr_t *addr);
static ngx_int_t ngx_http_geo_real_addr(ngx_http_request_t *r,
ngx_http_geo_ctx_t *ctx, ngx_addr_t *addr);
static char *ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
@@ -82,6 +93,8 @@
ngx_http_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end);
static char *ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
ngx_str_t *value);
+static char *ngx_http_geo_cidr_add(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
+ ngx_cidr_t *cidr, ngx_str_t *value, ngx_str_t *net);
static ngx_http_variable_value_t *ngx_http_geo_value(ngx_conf_t *cf,
ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value);
static char *ngx_http_geo_add_proxy(ngx_conf_t *cf,
@@ -155,7 +168,7 @@
};
-/* AF_INET only */
+/* geo range is AF_INET only */
static ngx_int_t
ngx_http_geo_cidr_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
@@ -163,10 +176,56 @@
{
ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data;
+ in_addr_t inaddr;
+ ngx_addr_t addr;
+ struct sockaddr_in *sin;
ngx_http_variable_value_t *vv;
+#if (NGX_HAVE_INET6)
+ u_char *p;
+ struct in6_addr *inaddr6;
+#endif
+
+ if (ngx_http_geo_addr(r, ctx, &addr) != NGX_OK) {
+ vv = (ngx_http_variable_value_t *)
+ ngx_radix32tree_find(ctx->u.trees.tree, INADDR_NONE);
+ goto done;
+ }
+
+ switch (addr.sockaddr->sa_family) {
+
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
+ p = inaddr6->s6_addr;
+
+ if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
+ inaddr = p[12] << 24;
+ inaddr += p[13] << 16;
+ inaddr += p[14] << 8;
+ inaddr += p[15];
+
+ vv = (ngx_http_variable_value_t *)
+ ngx_radix32tree_find(ctx->u.trees.tree, inaddr);
- vv = (ngx_http_variable_value_t *)
- ngx_radix32tree_find(ctx->u.tree, ngx_http_geo_addr(r, ctx));
+ } else {
+ vv = (ngx_http_variable_value_t *)
+ ngx_radix128tree_find(ctx->u.trees.tree6, p);
+ }
+
+ break;
+#endif
+
+ default: /* AF_INET */
+ sin = (struct sockaddr_in *) addr.sockaddr;
+ inaddr = ntohl(sin->sin_addr.s_addr);
+
+ vv = (ngx_http_variable_value_t *)
+ ngx_radix32tree_find(ctx->u.trees.tree, inaddr);
+
+ break;
+ }
+
+done:
*v = *vv;
@@ -183,25 +242,65 @@
{
ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data;
- in_addr_t addr;
+ in_addr_t inaddr;
+ ngx_addr_t addr;
ngx_uint_t n;
+ struct sockaddr_in *sin;
ngx_http_geo_range_t *range;
+#if (NGX_HAVE_INET6)
+ u_char *p;
+ struct in6_addr *inaddr6;
+#endif
*v = *ctx->u.high.default_value;
- addr = ngx_http_geo_addr(r, ctx);
+ if (ngx_http_geo_addr(r, ctx, &addr) == NGX_OK) {
- range = ctx->u.high.low[addr >> 16];
+ switch (addr.sockaddr->sa_family) {
- if (range) {
- n = addr & 0xffff;
- do {
- if (n >= (ngx_uint_t) range->start && n <= (ngx_uint_t) range->end)
- {
- *v = *range->value;
- break;
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
+
+ if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
+ p = inaddr6->s6_addr;
+
+ inaddr = p[12] << 24;
+ inaddr += p[13] << 16;
+ inaddr += p[14] << 8;
+ inaddr += p[15];
+
+ } else {
+ inaddr = INADDR_NONE;
}
- } while ((++range)->value);
+
+ break;
+#endif
+
+ default: /* AF_INET */
+ sin = (struct sockaddr_in *) addr.sockaddr;
+ inaddr = ntohl(sin->sin_addr.s_addr);
+ break;
+ }
+
+ } else {
+ inaddr = INADDR_NONE;
+ }
+
+ if (ctx->u.high.low) {
+ range = ctx->u.high.low[inaddr >> 16];
+
+ if (range) {
+ n = inaddr & 0xffff;
+ do {
+ if (n >= (ngx_uint_t) range->start
+ && n <= (ngx_uint_t) range->end)
+ {
+ *v = *range->value;
+ break;
+ }
+ } while ((++range)->value);
+ }
}
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -211,54 +310,25 @@
}
-static in_addr_t
-ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx)
+static ngx_int_t
+ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx,
+ ngx_addr_t *addr)
{
- ngx_addr_t addr;
- ngx_table_elt_t *xfwd;
- struct sockaddr_in *sin;
+ ngx_table_elt_t *xfwd;
- if (ngx_http_geo_real_addr(r, ctx, &addr) != NGX_OK) {
- return INADDR_NONE;
+ if (ngx_http_geo_real_addr(r, ctx, addr) != NGX_OK) {
+ return NGX_ERROR;
}
xfwd = r->headers_in.x_forwarded_for;
if (xfwd != NULL && ctx->proxies != NULL) {
- (void) ngx_http_get_forwarded_addr(r, &addr, xfwd->value.data,
+ (void) ngx_http_get_forwarded_addr(r, addr, xfwd->value.data,
xfwd->value.len, ctx->proxies,
ctx->proxy_recursive);
}
-#if (NGX_HAVE_INET6)
-
- if (addr.sockaddr->sa_family == AF_INET6) {
- u_char *p;
- in_addr_t inaddr;
- struct in6_addr *inaddr6;
-
- inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
-
- if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
- p = inaddr6->s6_addr;
-
- inaddr = p[12] << 24;
- inaddr += p[13] << 16;
- inaddr += p[14] << 8;
- inaddr += p[15];
-
- return inaddr;
- }
- }
-
-#endif
-
- if (addr.sockaddr->sa_family != AF_INET) {
- return INADDR_NONE;
- }
-
- sin = (struct sockaddr_in *) addr.sockaddr;
- return ntohl(sin->sin_addr.s_addr);
+ return NGX_OK;
}
@@ -303,7 +373,6 @@
ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
char *rv;
- void **p;
size_t len;
ngx_str_t *value, name;
ngx_uint_t i;
@@ -313,6 +382,9 @@
ngx_http_variable_t *var;
ngx_http_geo_ctx_t *geo;
ngx_http_geo_conf_ctx_t ctx;
+#if (NGX_HAVE_INET6)
+ static struct in6_addr zero;
+#endif
value = cf->args->elts;
@@ -322,6 +394,13 @@
}
name = value[1];
+
+ if (name.data[0] != '$') {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid variable name \"%V\"", &name);
+ return NGX_CONF_ERROR;
+ }
+
name.len--;
name.data++;
@@ -333,6 +412,13 @@
}
name = value[2];
+
+ if (name.data[0] != '$') {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid variable name \"%V\"", &name);
+ return NGX_CONF_ERROR;
+ }
+
name.len--;
name.data++;
@@ -378,9 +464,9 @@
geo->proxies = ctx.proxies;
geo->proxy_recursive = ctx.proxy_recursive;
- if (ctx.high.low) {
+ if (ctx.ranges) {
- if (!ctx.binary_include) {
+ if (ctx.high.low && !ctx.binary_include) {
for (i = 0; i < 0x10000; i++) {
a = (ngx_array_t *) ctx.high.low[i];
@@ -395,8 +481,8 @@
return NGX_CONF_ERROR;
}
- p = (void **) ngx_cpymem(ctx.high.low[i], a->elts, len);
- *p = NULL;
+ ngx_memcpy(ctx.high.low[i], a->elts, len);
+ ctx.high.low[i][a->nelts].value = NULL;
ctx.data_size += len + sizeof(void *);
}
@@ -429,7 +515,18 @@
}
}
- geo->u.tree = ctx.tree;
+ geo->u.trees.tree = ctx.tree;
+
+#if (NGX_HAVE_INET6)
+ if (ctx.tree6 == NULL) {
+ ctx.tree6 = ngx_radix_tree_create(cf->pool, -1);
+ if (ctx.tree6 == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ geo->u.trees.tree6 = ctx.tree6;
+#endif
var->get_handler = ngx_http_geo_cidr_variable;
var->data = (uintptr_t) geo;
@@ -437,16 +534,23 @@
ngx_destroy_pool(ctx.temp_pool);
ngx_destroy_pool(pool);
- if (ngx_radix32tree_find(ctx.tree, 0) != NGX_RADIX_NO_VALUE) {
- return rv;
- }
-
if (ngx_radix32tree_insert(ctx.tree, 0, 0,
(uintptr_t) &ngx_http_variable_null_value)
== NGX_ERROR)
{
return NGX_CONF_ERROR;
}
+
+ /* NGX_BUSY is okay (default was set explicitly) */
+
+#if (NGX_HAVE_INET6)
+ if (ngx_radix128tree_insert(ctx.tree6, zero.s6_addr, zero.s6_addr,
+ (uintptr_t) &ngx_http_variable_null_value)
+ == NGX_ERROR)
+ {
+ return NGX_CONF_ERROR;
+ }
+#endif
}
return rv;
@@ -469,7 +573,12 @@
if (ngx_strcmp(value[0].data, "ranges") == 0) {
- if (ctx->tree) {
+ if (ctx->tree
+#if (NGX_HAVE_INET6)
+ || ctx->tree6
+#endif
+ )
+ {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"the \"ranges\" directive must be "
"the first directive inside \"geo\" block");
@@ -907,11 +1016,10 @@
ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
ngx_str_t *value)
{
- ngx_int_t rc, del;
- ngx_str_t *net;
- ngx_uint_t i;
- ngx_cidr_t cidr;
- ngx_http_variable_value_t *val, *old;
+ char *rv;
+ ngx_int_t rc, del;
+ ngx_str_t *net;
+ ngx_cidr_t cidr;
if (ctx->tree == NULL) {
ctx->tree = ngx_radix_tree_create(ctx->pool, -1);
@@ -920,57 +1028,108 @@
}
}
+#if (NGX_HAVE_INET6)
+ if (ctx->tree6 == NULL) {
+ ctx->tree6 = ngx_radix_tree_create(ctx->pool, -1);
+ if (ctx->tree6 == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+#endif
+
if (ngx_strcmp(value[0].data, "default") == 0) {
- /* cidr.family = AF_INET; */
+ cidr.family = AF_INET;
cidr.u.in.addr = 0;
cidr.u.in.mask = 0;
- net = &value[0];
- } else {
- if (ngx_strcmp(value[0].data, "delete") == 0) {
- net = &value[1];
- del = 1;
+ rv = ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]);
- } else {
- net = &value[0];
- del = 0;
+ if (rv != NGX_CONF_OK) {
+ return rv;
}
- if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
+#if (NGX_HAVE_INET6)
+ cidr.family = AF_INET6;
+ ngx_memzero(&cidr.u.in6, sizeof(ngx_in6_cidr_t));
- if (cidr.family != AF_INET) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"geo\" supports IPv4 only");
- return NGX_CONF_ERROR;
+ rv = ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]);
+
+ if (rv != NGX_CONF_OK) {
+ return rv;
}
+#endif
+
+ return NGX_CONF_OK;
+ }
+
+ if (ngx_strcmp(value[0].data, "delete") == 0) {
+ net = &value[1];
+ del = 1;
+
+ } else {
+ net = &value[0];
+ del = 0;
+ }
+ if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (cidr.family == AF_INET) {
cidr.u.in.addr = ntohl(cidr.u.in.addr);
cidr.u.in.mask = ntohl(cidr.u.in.mask);
+ }
- if (del) {
- if (ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr,
- cidr.u.in.mask)
- != NGX_OK)
- {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "no network \"%V\" to delete", net);
- }
+ if (del) {
+ switch (cidr.family) {
- return NGX_CONF_OK;
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ rc = ngx_radix128tree_delete(ctx->tree6,
+ cidr.u.in6.addr.s6_addr,
+ cidr.u.in6.mask.s6_addr);
+ break;
+#endif
+
+ default: /* AF_INET */
+ rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr,
+ cidr.u.in.mask);
+ break;
}
+
+ if (rc != NGX_OK) {
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "no network \"%V\" to delete", net);
+ }
+
+ return NGX_CONF_OK;
}
- val = ngx_http_geo_value(cf, ctx, &value[1]);
+ return ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], net);
+}
+
+
+static char *
+ngx_http_geo_cidr_add(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
+ ngx_cidr_t *cidr, ngx_str_t *value, ngx_str_t *net)
+{
+ ngx_int_t rc;
+ ngx_http_variable_value_t *val, *old;
+
+ val = ngx_http_geo_value(cf, ctx, value);
if (val == NULL) {
return NGX_CONF_ERROR;
}
- for (i = 2; i; i--) {
- rc = ngx_radix32tree_insert(ctx->tree, cidr.u.in.addr, cidr.u.in.mask,
- (uintptr_t) val);
+ switch (cidr->family) {
+
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr,
+ cidr->u.in6.mask.s6_addr,
+ (uintptr_t) val);
+
if (rc == NGX_OK) {
return NGX_CONF_OK;
}
@@ -982,18 +1141,66 @@
/* rc == NGX_BUSY */
old = (ngx_http_variable_value_t *)
- ngx_radix32tree_find(ctx->tree, cidr.u.in.addr & cidr.u.in.mask);
+ ngx_radix128tree_find(ctx->tree6,
+ cidr->u.in6.addr.s6_addr);
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
- net, val, old);
+ "duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
+ net, val, old);
- rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr, cidr.u.in.mask);
+ rc = ngx_radix128tree_delete(ctx->tree6,
+ cidr->u.in6.addr.s6_addr,
+ cidr->u.in6.mask.s6_addr);
if (rc == NGX_ERROR) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree");
return NGX_CONF_ERROR;
}
+
+ rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr,
+ cidr->u.in6.mask.s6_addr,
+ (uintptr_t) val);
+
+ break;
+#endif
+
+ default: /* AF_INET */
+ rc = ngx_radix32tree_insert(ctx->tree, cidr->u.in.addr,
+ cidr->u.in.mask, (uintptr_t) val);
+
+ if (rc == NGX_OK) {
+ return NGX_CONF_OK;
+ }
+
+ if (rc == NGX_ERROR) {
+ return NGX_CONF_ERROR;
+ }
+
+ /* rc == NGX_BUSY */
+
+ old = (ngx_http_variable_value_t *)
+ ngx_radix32tree_find(ctx->tree, cidr->u.in.addr);
+
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
+ net, val, old);
+
+ rc = ngx_radix32tree_delete(ctx->tree,
+ cidr->u.in.addr, cidr->u.in.mask);
+
+ if (rc == NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree");
+ return NGX_CONF_ERROR;
+ }
+
+ rc = ngx_radix32tree_insert(ctx->tree, cidr->u.in.addr,
+ cidr->u.in.mask, (uintptr_t) val);
+
+ break;
+ }
+
+ if (rc == NGX_OK) {
+ return NGX_CONF_OK;
}
return NGX_CONF_ERROR;
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/ngx_http_geoip_module.c
^
|
@@ -13,12 +13,22 @@
#include <GeoIPCity.h>
+#define NGX_GEOIP_COUNTRY_CODE 0
+#define NGX_GEOIP_COUNTRY_CODE3 1
+#define NGX_GEOIP_COUNTRY_NAME 2
+
+
typedef struct {
GeoIP *country;
GeoIP *org;
GeoIP *city;
ngx_array_t *proxies; /* array of ngx_cidr_t */
ngx_flag_t proxy_recursive;
+#if (NGX_HAVE_GEOIP_V6)
+ unsigned country_v6:1;
+ unsigned org_v6:1;
+ unsigned city_v6:1;
+#endif
} ngx_http_geoip_conf_t;
@@ -28,10 +38,32 @@
} ngx_http_geoip_var_t;
-typedef char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *, u_long addr);
+typedef const char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *,
+ u_long addr);
+
+
+ngx_http_geoip_variable_handler_pt ngx_http_geoip_country_functions[] = {
+ GeoIP_country_code_by_ipnum,
+ GeoIP_country_code3_by_ipnum,
+ GeoIP_country_name_by_ipnum,
+};
+
+
+#if (NGX_HAVE_GEOIP_V6)
+
+typedef const char *(*ngx_http_geoip_variable_handler_v6_pt)(GeoIP *,
+ geoipv6_t addr);
+
+
+ngx_http_geoip_variable_handler_v6_pt ngx_http_geoip_country_v6_functions[] = {
+ GeoIP_country_code_by_ipnum_v6,
+ GeoIP_country_code3_by_ipnum_v6,
+ GeoIP_country_name_by_ipnum_v6,
+};
+
+#endif
+
-static u_long ngx_http_geoip_addr(ngx_http_request_t *r,
- ngx_http_geoip_conf_t *gcf);
static ngx_int_t ngx_http_geoip_country_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_geoip_org_variable(ngx_http_request_t *r,
@@ -138,19 +170,19 @@
{ ngx_string("geoip_country_code"), NULL,
ngx_http_geoip_country_variable,
- (uintptr_t) GeoIP_country_code_by_ipnum, 0, 0 },
+ NGX_GEOIP_COUNTRY_CODE, 0, 0 },
{ ngx_string("geoip_country_code3"), NULL,
ngx_http_geoip_country_variable,
- (uintptr_t) GeoIP_country_code3_by_ipnum, 0, 0 },
+ NGX_GEOIP_COUNTRY_CODE3, 0, 0 },
{ ngx_string("geoip_country_name"), NULL,
ngx_http_geoip_country_variable,
- (uintptr_t) GeoIP_country_name_by_ipnum, 0, 0 },
+ NGX_GEOIP_COUNTRY_NAME, 0, 0 },
{ ngx_string("geoip_org"), NULL,
ngx_http_geoip_org_variable,
- (uintptr_t) GeoIP_name_by_ipnum, 0, 0 },
+ 0, 0, 0 },
{ ngx_string("geoip_city_continent_code"), NULL,
ngx_http_geoip_city_variable,
@@ -255,12 +287,68 @@
}
+#if (NGX_HAVE_GEOIP_V6)
+
+static geoipv6_t
+ngx_http_geoip_addr_v6(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
+{
+ ngx_addr_t addr;
+ ngx_table_elt_t *xfwd;
+ in_addr_t addr4;
+ struct in6_addr addr6;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+
+ addr.sockaddr = r->connection->sockaddr;
+ addr.socklen = r->connection->socklen;
+ /* addr.name = r->connection->addr_text; */
+
+ xfwd = r->headers_in.x_forwarded_for;
+
+ if (xfwd != NULL && gcf->proxies != NULL) {
+ (void) ngx_http_get_forwarded_addr(r, &addr, xfwd->value.data,
+ xfwd->value.len, gcf->proxies,
+ gcf->proxy_recursive);
+ }
+
+ switch (addr.sockaddr->sa_family) {
+
+ case AF_INET:
+ /* Produce IPv4-mapped IPv6 address. */
+ sin = (struct sockaddr_in *) addr.sockaddr;
+ addr4 = ntohl(sin->sin_addr.s_addr);
+
+ ngx_memzero(&addr6, sizeof(struct in6_addr));
+ addr6.s6_addr[10] = 0xff;
+ addr6.s6_addr[11] = 0xff;
+ addr6.s6_addr[12] = addr4 >> 24;
+ addr6.s6_addr[13] = addr4 >> 16;
+ addr6.s6_addr[14] = addr4 >> 8;
+ addr6.s6_addr[15] = addr4;
+ return addr6;
+
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *) addr.sockaddr;
+ return sin6->sin6_addr;
+
+ default:
+ return in6addr_any;
+ }
+}
+
+#endif
+
+
static ngx_int_t
ngx_http_geoip_country_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
- ngx_http_geoip_variable_handler_pt handler =
- (ngx_http_geoip_variable_handler_pt) data;
+ ngx_http_geoip_variable_handler_pt handler =
+ ngx_http_geoip_country_functions[data];
+#if (NGX_HAVE_GEOIP_V6)
+ ngx_http_geoip_variable_handler_v6_pt handler_v6 =
+ ngx_http_geoip_country_v6_functions[data];
+#endif
const char *val;
ngx_http_geoip_conf_t *gcf;
@@ -271,7 +359,13 @@
goto not_found;
}
+#if (NGX_HAVE_GEOIP_V6)
+ val = gcf->country_v6
+ ? handler_v6(gcf->country, ngx_http_geoip_addr_v6(r, gcf))
+ : handler(gcf->country, ngx_http_geoip_addr(r, gcf));
+#else
val = handler(gcf->country, ngx_http_geoip_addr(r, gcf));
+#endif
if (val == NULL) {
goto not_found;
@@ -297,9 +391,6 @@
ngx_http_geoip_org_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
- ngx_http_geoip_variable_handler_pt handler =
- (ngx_http_geoip_variable_handler_pt) data;
-
size_t len;
char *val;
ngx_http_geoip_conf_t *gcf;
@@ -310,7 +401,15 @@
goto not_found;
}
- val = handler(gcf->org, ngx_http_geoip_addr(r, gcf));
+#if (NGX_HAVE_GEOIP_V6)
+ val = gcf->org_v6
+ ? GeoIP_name_by_ipnum_v6(gcf->org,
+ ngx_http_geoip_addr_v6(r, gcf))
+ : GeoIP_name_by_ipnum(gcf->org,
+ ngx_http_geoip_addr(r, gcf));
+#else
+ val = GeoIP_name_by_ipnum(gcf->org, ngx_http_geoip_addr(r, gcf));
+#endif
if (val == NULL) {
goto not_found;
@@ -500,7 +599,15 @@
gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
if (gcf->city) {
+#if (NGX_HAVE_GEOIP_V6)
+ return gcf->city_v6
+ ? GeoIP_record_by_ipnum_v6(gcf->city,
+ ngx_http_geoip_addr_v6(r, gcf))
+ : GeoIP_record_by_ipnum(gcf->city,
+ ngx_http_geoip_addr(r, gcf));
+#else
return GeoIP_record_by_ipnum(gcf->city, ngx_http_geoip_addr(r, gcf));
+#endif
}
return NULL;
@@ -598,11 +705,16 @@
switch (gcf->country->databaseType) {
case GEOIP_COUNTRY_EDITION:
- case GEOIP_PROXY_EDITION:
- case GEOIP_NETSPEED_EDITION:
return NGX_CONF_OK;
+#if (NGX_HAVE_GEOIP_V6)
+ case GEOIP_COUNTRY_EDITION_V6:
+
+ gcf->country_v6 = 1;
+ return NGX_CONF_OK;
+#endif
+
default:
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid GeoIP database \"%V\" type:%d",
@@ -654,6 +766,16 @@
return NGX_CONF_OK;
+#if (NGX_HAVE_GEOIP_V6)
+ case GEOIP_ISP_EDITION_V6:
+ case GEOIP_ORG_EDITION_V6:
+ case GEOIP_DOMAIN_EDITION_V6:
+ case GEOIP_ASNUM_EDITION_V6:
+
+ gcf->org_v6 = 1;
+ return NGX_CONF_OK;
+#endif
+
default:
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid GeoIP database \"%V\" type:%d",
@@ -703,6 +825,14 @@
return NGX_CONF_OK;
+#if (NGX_HAVE_GEOIP_V6)
+ case GEOIP_CITY_EDITION_REV0_V6:
+ case GEOIP_CITY_EDITION_REV1_V6:
+
+ gcf->city_v6 = 1;
+ return NGX_CONF_OK;
+#endif
+
default:
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid GeoIP City database \"%V\" type:%d",
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/ngx_http_gzip_filter_module.c
^
|
@@ -320,7 +320,7 @@
ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module);
- if (ctx == NULL || ctx->done) {
+ if (ctx == NULL || ctx->done || r->header_only) {
return ngx_http_next_body_filter(r, in);
}
@@ -497,6 +497,10 @@
wbits--;
memlevel--;
}
+
+ if (memlevel < 1) {
+ memlevel = 1;
+ }
}
ctx->wbits = wbits;
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/ngx_http_image_filter_module.c
^
|
@@ -1169,10 +1169,22 @@
return NULL;
}
+ /*
+ * set by ngx_pcalloc():
+ *
+ * conf->width = 0;
+ * conf->height = 0;
+ * conf->angle = 0;
+ * conf->wcv = NULL;
+ * conf->hcv = NULL;
+ * conf->acv = NULL;
+ * conf->jqcv = NULL;
+ * conf->shcv = NULL;
+ */
+
conf->filter = NGX_CONF_UNSET_UINT;
conf->jpeg_quality = NGX_CONF_UNSET_UINT;
conf->sharpen = NGX_CONF_UNSET_UINT;
- conf->angle = NGX_CONF_UNSET_UINT;
conf->transparency = NGX_CONF_UNSET;
conf->buffer_size = NGX_CONF_UNSET_SIZE;
@@ -1195,27 +1207,29 @@
conf->filter = prev->filter;
conf->width = prev->width;
conf->height = prev->height;
+ conf->angle = prev->angle;
conf->wcv = prev->wcv;
conf->hcv = prev->hcv;
+ conf->acv = prev->acv;
}
}
- /* 75 is libjpeg default quality */
- ngx_conf_merge_uint_value(conf->jpeg_quality, prev->jpeg_quality, 75);
-
- if (conf->jqcv == NULL) {
- conf->jqcv = prev->jqcv;
- }
+ if (conf->jpeg_quality == NGX_CONF_UNSET_UINT) {
- ngx_conf_merge_uint_value(conf->sharpen, prev->sharpen, 0);
+ /* 75 is libjpeg default quality */
+ ngx_conf_merge_uint_value(conf->jpeg_quality, prev->jpeg_quality, 75);
- if (conf->shcv == NULL) {
- conf->shcv = prev->shcv;
+ if (conf->jqcv == NULL) {
+ conf->jqcv = prev->jqcv;
+ }
}
- ngx_conf_merge_uint_value(conf->angle, prev->angle, 0);
- if (conf->acv == NULL) {
- conf->acv = prev->acv;
+ if (conf->sharpen == NGX_CONF_UNSET_UINT) {
+ ngx_conf_merge_uint_value(conf->sharpen, prev->sharpen, 0);
+
+ if (conf->shcv == NULL) {
+ conf->shcv = prev->shcv;
+ }
}
ngx_conf_merge_value(conf->transparency, prev->transparency, 1);
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/ngx_http_log_module.c
^
|
@@ -9,6 +9,10 @@
#include <ngx_core.h>
#include <ngx_http.h>
+#if (NGX_ZLIB)
+#include <zlib.h>
+#endif
+
typedef struct ngx_http_log_op_s ngx_http_log_op_t;
@@ -41,6 +45,17 @@
typedef struct {
+ u_char *start;
+ u_char *pos;
+ u_char *last;
+
+ ngx_event_t *event;
+ ngx_msec_t flush;
+ ngx_int_t gzip;
+} ngx_http_log_buf_t;
+
+
+typedef struct {
ngx_array_t *lengths;
ngx_array_t *values;
} ngx_http_log_script_t;
@@ -78,6 +93,17 @@
static ssize_t ngx_http_log_script_write(ngx_http_request_t *r,
ngx_http_log_script_t *script, u_char **name, u_char *buf, size_t len);
+#if (NGX_ZLIB)
+static ssize_t ngx_http_log_gzip(ngx_fd_t fd, u_char *buf, size_t len,
+ ngx_int_t level, ngx_log_t *log);
+
+static void *ngx_http_log_gzip_alloc(void *opaque, u_int items, u_int size);
+static void ngx_http_log_gzip_free(void *opaque, void *address);
+#endif
+
+static void ngx_http_log_flush(ngx_open_file_t *file, ngx_log_t *log);
+static void ngx_http_log_flush_handler(ngx_event_t *ev);
+
static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf,
ngx_http_log_op_t *op);
static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf,
@@ -132,7 +158,7 @@
{ ngx_string("access_log"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
- |NGX_HTTP_LMT_CONF|NGX_CONF_TAKE123,
+ |NGX_HTTP_LMT_CONF|NGX_CONF_1MORE,
ngx_http_log_set_log,
NGX_HTTP_LOC_CONF_OFFSET,
0,
@@ -216,8 +242,8 @@
size_t len;
ngx_uint_t i, l;
ngx_http_log_t *log;
- ngx_open_file_t *file;
ngx_http_log_op_t *op;
+ ngx_http_log_buf_t *buffer;
ngx_http_log_loc_conf_t *lcf;
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -258,21 +284,25 @@
len += NGX_LINEFEED_SIZE;
- file = log[l].file;
+ buffer = log[l].file ? log[l].file->data : NULL;
- if (file && file->buffer) {
+ if (buffer) {
- if (len > (size_t) (file->last - file->pos)) {
+ if (len > (size_t) (buffer->last - buffer->pos)) {
- ngx_http_log_write(r, &log[l], file->buffer,
- file->pos - file->buffer);
+ ngx_http_log_write(r, &log[l], buffer->start,
+ buffer->pos - buffer->start);
- file->pos = file->buffer;
+ buffer->pos = buffer->start;
}
- if (len <= (size_t) (file->last - file->pos)) {
+ if (len <= (size_t) (buffer->last - buffer->pos)) {
+
+ p = buffer->pos;
- p = file->pos;
+ if (buffer->event && p == buffer->start) {
+ ngx_add_timer(buffer->event, buffer->flush);
+ }
for (i = 0; i < log[l].format->ops->nelts; i++) {
p = op[i].run(r, p, &op[i]);
@@ -280,10 +310,14 @@
ngx_linefeed(p);
- file->pos = p;
+ buffer->pos = p;
continue;
}
+
+ if (buffer->event && buffer->event->timer_set) {
+ ngx_del_timer(buffer->event);
+ }
}
line = ngx_pnalloc(r->pool, len);
@@ -310,14 +344,29 @@
ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log, u_char *buf,
size_t len)
{
- u_char *name;
- time_t now;
- ssize_t n;
- ngx_err_t err;
+ u_char *name;
+ time_t now;
+ ssize_t n;
+ ngx_err_t err;
+#if (NGX_ZLIB)
+ ngx_http_log_buf_t *buffer;
+#endif
if (log->script == NULL) {
name = log->file->name.data;
+
+#if (NGX_ZLIB)
+ buffer = log->file->data;
+
+ if (buffer && buffer->gzip) {
+ n = ngx_http_log_gzip(log->file->fd, buf, len, buffer->gzip,
+ r->connection->log);
+ } else {
+ n = ngx_write_fd(log->file->fd, buf, len);
+ }
+#else
n = ngx_write_fd(log->file->fd, buf, len);
+#endif
} else {
name = NULL;
@@ -465,6 +514,194 @@
}
+#if (NGX_ZLIB)
+
+static ssize_t
+ngx_http_log_gzip(ngx_fd_t fd, u_char *buf, size_t len, ngx_int_t level,
+ ngx_log_t *log)
+{
+ int rc, wbits, memlevel;
+ u_char *out;
+ size_t size;
+ ssize_t n;
+ z_stream zstream;
+ ngx_err_t err;
+ ngx_pool_t *pool;
+
+ wbits = MAX_WBITS;
+ memlevel = MAX_MEM_LEVEL - 1;
+
+ while ((ssize_t) len < ((1 << (wbits - 1)) - 262)) {
+ wbits--;
+ memlevel--;
+ }
+
+ /*
+ * This is a formula from deflateBound() for conservative upper bound of
+ * compressed data plus 18 bytes of gzip wrapper.
+ */
+
+ size = len + ((len + 7) >> 3) + ((len + 63) >> 6) + 5 + 18;
+
+ ngx_memzero(&zstream, sizeof(z_stream));
+
+ pool = ngx_create_pool(256, log);
+ if (pool == NULL) {
+ /* simulate successful logging */
+ return len;
+ }
+
+ pool->log = log;
+
+ zstream.zalloc = ngx_http_log_gzip_alloc;
+ zstream.zfree = ngx_http_log_gzip_free;
+ zstream.opaque = pool;
+
+ out = ngx_pnalloc(pool, size);
+ if (out == NULL) {
+ goto done;
+ }
+
+ zstream.next_in = buf;
+ zstream.avail_in = len;
+ zstream.next_out = out;
+ zstream.avail_out = size;
+
+ rc = deflateInit2(&zstream, (int) level, Z_DEFLATED, wbits + 16, memlevel,
+ Z_DEFAULT_STRATEGY);
+
+ if (rc != Z_OK) {
+ ngx_log_error(NGX_LOG_ALERT, log, 0, "deflateInit2() failed: %d", rc);
+ goto done;
+ }
+
+ ngx_log_debug4(NGX_LOG_DEBUG_HTTP, log, 0,
+ "deflate in: ni:%p no:%p ai:%ud ao:%ud",
+ zstream.next_in, zstream.next_out,
+ zstream.avail_in, zstream.avail_out);
+
+ rc = deflate(&zstream, Z_FINISH);
+
+ if (rc != Z_STREAM_END) {
+ ngx_log_error(NGX_LOG_ALERT, log, 0,
+ "deflate(Z_FINISH) failed: %d", rc);
+ goto done;
+ }
+
+ ngx_log_debug5(NGX_LOG_DEBUG_HTTP, log, 0,
+ "deflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d",
+ zstream.next_in, zstream.next_out,
+ zstream.avail_in, zstream.avail_out,
+ rc);
+
+ size -= zstream.avail_out;
+
+ rc = deflateEnd(&zstream);
+
+ if (rc != Z_OK) {
+ ngx_log_error(NGX_LOG_ALERT, log, 0, "deflateEnd() failed: %d", rc);
+ goto done;
+ }
+
+ n = ngx_write_fd(fd, out, size);
+
+ if (n != (ssize_t) size) {
+ err = (n == -1) ? ngx_errno : 0;
+
+ ngx_destroy_pool(pool);
+
+ ngx_set_errno(err);
+ return -1;
+ }
+
+done:
+
+ ngx_destroy_pool(pool);
+
+ /* simulate successful logging */
+ return len;
+}
+
+
+static void *
+ngx_http_log_gzip_alloc(void *opaque, u_int items, u_int size)
+{
+ ngx_pool_t *pool = opaque;
+
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pool->log, 0,
+ "gzip alloc: n:%ud s:%ud", items, size);
+
+ return ngx_palloc(pool, items * size);
+}
+
+
+static void
+ngx_http_log_gzip_free(void *opaque, void *address)
+{
+#if 0
+ ngx_pool_t *pool = opaque;
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pool->log, 0, "gzip free: %p", address);
+#endif
+}
+
+#endif
+
+
+static void
+ngx_http_log_flush(ngx_open_file_t *file, ngx_log_t *log)
+{
+ size_t len;
+ ssize_t n;
+ ngx_http_log_buf_t *buffer;
+
+ buffer = file->data;
+
+ len = buffer->pos - buffer->start;
+
+ if (len == 0) {
+ return;
+ }
+
+#if (NGX_ZLIB)
+ if (buffer->gzip) {
+ n = ngx_http_log_gzip(file->fd, buffer->start, len, buffer->gzip, log);
+ } else {
+ n = ngx_write_fd(file->fd, buffer->start, len);
+ }
+#else
+ n = ngx_write_fd(file->fd, buffer->start, len);
+#endif
+
+ if (n == -1) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ ngx_write_fd_n " to \"%s\" failed",
+ file->name.data);
+
+ } else if ((size_t) n != len) {
+ ngx_log_error(NGX_LOG_ALERT, log, 0,
+ ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz",
+ file->name.data, n, len);
+ }
+
+ buffer->pos = buffer->start;
+
+ if (buffer->event && buffer->event->timer_set) {
+ ngx_del_timer(buffer->event);
+ }
+}
+
+
+static void
+ngx_http_log_flush_handler(ngx_event_t *ev)
+{
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0,
+ "http log buffer flush handler");
+
+ ngx_http_log_flush(ev->data, ev->log);
+}
+
+
static u_char *
ngx_http_log_copy_short(ngx_http_request_t *r, u_char *buf,
ngx_http_log_op_t *op)
@@ -848,10 +1085,13 @@
{
ngx_http_log_loc_conf_t *llcf = conf;
- ssize_t buf;
+ ssize_t size;
+ ngx_int_t gzip;
ngx_uint_t i, n;
- ngx_str_t *value, name;
+ ngx_msec_t flush;
+ ngx_str_t *value, name, s;
ngx_http_log_t *log;
+ ngx_http_log_buf_t *buffer;
ngx_http_log_fmt_t *fmt;
ngx_http_log_main_conf_t *lmcf;
ngx_http_script_compile_t sc;
@@ -936,54 +1176,152 @@
&& ngx_strcasecmp(fmt[i].name.data, name.data) == 0)
{
log->format = &fmt[i];
- goto buffer;
+ break;
}
}
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unknown log format \"%V\"", &name);
- return NGX_CONF_ERROR;
+ if (log->format == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "unknown log format \"%V\"", &name);
+ return NGX_CONF_ERROR;
+ }
+
+ size = 0;
+ flush = 0;
+ gzip = 0;
+
+ for (i = 3; i < cf->args->nelts; i++) {
+
+ if (ngx_strncmp(value[i].data, "buffer=", 7) == 0) {
+ s.len = value[i].len - 7;
+ s.data = value[i].data + 7;
+
+ size = ngx_parse_size(&s);
+
+ if (size == NGX_ERROR || size == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid buffer size \"%V\"", &s);
+ return NGX_CONF_ERROR;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "flush=", 6) == 0) {
+ s.len = value[i].len - 6;
+ s.data = value[i].data + 6;
+
+ flush = ngx_parse_time(&s, 0);
+
+ if (flush == (ngx_msec_t) NGX_ERROR || flush == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid flush time \"%V\"", &s);
+ return NGX_CONF_ERROR;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "gzip", 4) == 0
+ && (value[i].len == 4 || value[i].data[4] == '='))
+ {
+#if (NGX_ZLIB)
+ if (size == 0) {
+ size = 64 * 1024;
+ }
+
+ if (value[i].len == 4) {
+ gzip = Z_BEST_SPEED;
+ continue;
+ }
+
+ s.len = value[i].len - 5;
+ s.data = value[i].data + 5;
+
+ gzip = ngx_atoi(s.data, s.len);
-buffer:
+ if (gzip < 1 || gzip > 9) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid compression level \"%V\"", &s);
+ return NGX_CONF_ERROR;
+ }
+
+ continue;
- if (cf->args->nelts == 4) {
- if (ngx_strncmp(value[3].data, "buffer=", 7) != 0) {
+#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[3]);
+ "nginx was built without zlib support");
return NGX_CONF_ERROR;
+#endif
}
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid parameter \"%V\"", &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (flush && size == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "no buffer is defined for access_log \"%V\"",
+ &value[1]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (size) {
+
if (log->script) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"buffered logs cannot have variables in name");
return NGX_CONF_ERROR;
}
- name.len = value[3].len - 7;
- name.data = value[3].data + 7;
+ if (log->file->data) {
+ buffer = log->file->data;
- buf = ngx_parse_size(&name);
+ if (buffer->last - buffer->start != size
+ || buffer->flush != flush
+ || buffer->gzip != gzip)
+ {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "access_log \"%V\" already defined "
+ "with conflicting parameters",
+ &value[1]);
+ return NGX_CONF_ERROR;
+ }
- if (buf == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid buffer value \"%V\"", &name);
- return NGX_CONF_ERROR;
+ return NGX_CONF_OK;
}
- if (log->file->buffer && log->file->last - log->file->pos != buf) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "access_log \"%V\" already defined "
- "with different buffer size", &value[1]);
+ buffer = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_buf_t));
+ if (buffer == NULL) {
return NGX_CONF_ERROR;
}
- log->file->buffer = ngx_palloc(cf->pool, buf);
- if (log->file->buffer == NULL) {
+ buffer->start = ngx_pnalloc(cf->pool, size);
+ if (buffer->start == NULL) {
return NGX_CONF_ERROR;
}
- log->file->pos = log->file->buffer;
- log->file->last = log->file->buffer + buf;
+ buffer->pos = buffer->start;
+ buffer->last = buffer->start + size;
+
+ if (flush) {
+ buffer->event = ngx_pcalloc(cf->pool, sizeof(ngx_event_t));
+ if (buffer->event == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ buffer->event->data = log->file;
+ buffer->event->handler = ngx_http_log_flush_handler;
+ buffer->event->log = &cf->cycle->new_log;
+
+ buffer->flush = flush;
+ }
+
+ buffer->gzip = gzip;
+
+ log->file->flush = ngx_http_log_flush;
+ log->file->data = buffer;
}
return NGX_CONF_OK;
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/ngx_http_map_module.c
^
|
@@ -209,6 +209,13 @@
}
name = value[2];
+
+ if (name.data[0] != '$') {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid variable name \"%V\"", &name);
+ return NGX_CONF_ERROR;
+ }
+
name.len--;
name.data++;
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/ngx_http_proxy_module.c
^
|
@@ -836,7 +836,7 @@
return NGX_ERROR;
}
- if (plcf->cache_key.value.len) {
+ if (plcf->cache_key.value.data) {
if (ngx_http_complex_value(r, &plcf->cache_key, key) != NGX_OK) {
return NGX_ERROR;
@@ -1610,7 +1610,8 @@
p->upstream_done = 1;
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
- "upstream sent too much data");
+ "upstream sent more data than specified in "
+ "\"Content-Length\" header");
}
return NGX_OK;
@@ -2607,7 +2608,7 @@
* conf->upstream.store_lengths = NULL;
* conf->upstream.store_values = NULL;
*
- * conf->method = NULL;
+ * conf->method = { 0, NULL };
* conf->headers_source = NULL;
* conf->headers_set_len = NULL;
* conf->headers_set = NULL;
@@ -2906,10 +2907,11 @@
#endif
- if (conf->method.len == 0) {
- conf->method = prev->method;
+ ngx_conf_merge_str_value(conf->method, prev->method, "");
- } else {
+ if (conf->method.len
+ && conf->method.data[conf->method.len - 1] != ' ')
+ {
conf->method.data[conf->method.len] = ' ';
conf->method.len++;
}
@@ -3918,7 +3920,7 @@
value = cf->args->elts;
- if (plcf->cache_key.value.len) {
+ if (plcf->cache_key.value.data) {
return "is duplicate";
}
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/ngx_http_scgi_module.c
^
|
@@ -1765,7 +1765,7 @@
value = cf->args->elts;
- if (scf->cache_key.value.len) {
+ if (scf->cache_key.value.data) {
return "is duplicate";
}
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/ngx_http_secure_link_module.c
^
|
@@ -111,7 +111,7 @@
conf = ngx_http_get_module_loc_conf(r, ngx_http_secure_link_module);
- if (conf->secret.len) {
+ if (conf->secret.data) {
return ngx_http_secure_link_old_variable(r, conf, v, data);
}
@@ -318,7 +318,16 @@
ngx_http_secure_link_conf_t *prev = parent;
ngx_http_secure_link_conf_t *conf = child;
- ngx_conf_merge_str_value(conf->secret, prev->secret, "");
+ if (conf->secret.data) {
+ if (conf->variable || conf->md5) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "\"secure_link_secret\" cannot be mixed with "
+ "\"secure_link\" and \"secure_link_md5\"");
+ return NGX_CONF_ERROR;
+ }
+
+ return NGX_CONF_OK;
+ }
if (conf->variable == NULL) {
conf->variable = prev->variable;
@@ -328,6 +337,10 @@
conf->md5 = prev->md5;
}
+ if (conf->variable == NULL && conf->md5 == NULL) {
+ conf->secret = prev->secret;
+ }
+
return NGX_CONF_OK;
}
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/ngx_http_split_clients_module.c
^
|
@@ -139,7 +139,7 @@
name = value[2];
- if (name.len < 2 || name.data[0] != '$') {
+ if (name.data[0] != '$') {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid variable name \"%V\"", &name);
return NGX_CONF_ERROR;
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/ngx_http_sub_filter_module.c
^
|
@@ -627,7 +627,7 @@
ngx_str_t *value;
ngx_http_compile_complex_value_t ccv;
- if (slcf->match.len) {
+ if (slcf->match.data) {
return "is duplicate";
}
@@ -687,7 +687,7 @@
ngx_conf_merge_value(conf->once, prev->once, 1);
ngx_conf_merge_str_value(conf->match, prev->match, "");
- if (conf->value.value.len == 0) {
+ if (conf->value.value.data == NULL) {
conf->value = prev->value;
}
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/ngx_http_upstream_keepalive_module.c
^
|
@@ -502,6 +502,10 @@
kcf = ngx_http_conf_upstream_srv_conf(uscf,
ngx_http_upstream_keepalive_module);
+ if (kcf->original_init_upstream) {
+ return "is duplicate";
+ }
+
kcf->original_init_upstream = uscf->peer.init_upstream
? uscf->peer.init_upstream
: ngx_http_upstream_init_round_robin;
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/ngx_http_upstream_least_conn_module.c
^
|
@@ -313,7 +313,9 @@
lcp->rrp.peers = peers->next;
pc->tries = lcp->rrp.peers->number;
- n = lcp->rrp.peers->number / (8 * sizeof(uintptr_t)) + 1;
+ n = (lcp->rrp.peers->number + (8 * sizeof(uintptr_t) - 1))
+ / (8 * sizeof(uintptr_t));
+
for (i = 0; i < n; i++) {
lcp->rrp.tried[i] = 0;
}
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/ngx_http_uwsgi_module.c
^
|
@@ -1807,7 +1807,7 @@
value = cf->args->elts;
- if (uwcf->cache_key.value.len) {
+ if (uwcf->cache_key.value.data) {
return "is duplicate";
}
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/ngx_http_xslt_filter_module.c
^
|
@@ -307,7 +307,7 @@
ctx->done = 1;
if (b == NULL) {
- return ngx_http_filter_finalize_request(r, NULL,
+ return ngx_http_filter_finalize_request(r, &ngx_http_xslt_filter_module,
NGX_HTTP_INTERNAL_SERVER_ERROR);
}
@@ -315,7 +315,7 @@
if (cln == NULL) {
ngx_free(b->pos);
- return ngx_http_filter_finalize_request(r, NULL,
+ return ngx_http_filter_finalize_request(r, &ngx_http_xslt_filter_module,
NGX_HTTP_INTERNAL_SERVER_ERROR);
}
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/perl/Makefile.PL
^
|
@@ -16,20 +16,9 @@
CCFLAGS => "$ENV{NGX_PM_CFLAGS}",
OPTIMIZE => '-O',
- INC => "-I ../../../../../src/core " .
- "-I ../../../../../src/event " .
- "-I ../../../../../src/os/unix " .
- "-I ../../../../../src/http " .
- "-I ../../../../../src/http/modules " .
- "-I ../../../../../src/http/modules/perl " .
- "-I ../../../../../$ENV{NGX_OBJS} " .
- ($ENV{NGX_PCRE} =~ /^(YES|NO)/ ? "" :
- ($ENV{NGX_PCRE} =~ m#^/# ? "-I $ENV{NGX_PCRE} " :
- "-I ../../../../../$ENV{NGX_PCRE} ")) .
- ($ENV{NGX_OPENSSL} =~ /^(YES|NO)/ ? "" :
- ($ENV{NGX_OPENSSL} =~ m#^/# ?
- "-I $ENV{NGX_OPENSSL}/.openssl/include " :
- "-I ../../../../../$ENV{NGX_OPENSSL}/.openssl/include ")),
+ INC => join(" ", map {
+ m#^/# ? "-I $_" : "-I ../../../../../$_"
+ } (split /\s+/, $ENV{NGX_INCS})),
depend => {
'nginx.c' =>
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/modules/perl/nginx.pm
^
|
@@ -50,7 +50,7 @@
HTTP_INSUFFICIENT_STORAGE
);
-our $VERSION = '1.2.6';
+our $VERSION = '1.2.7';
require XSLoader;
XSLoader::load('nginx', $VERSION);
@@ -123,7 +123,7 @@
=head1 SEE ALSO
-http://sysoev.ru/nginx/docs/http/ngx_http_perl_module.html
+http://nginx.org/en/docs/http/ngx_http_perl_module.html
=head1 AUTHOR
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/ngx_http_core_module.c
^
|
@@ -993,6 +993,7 @@
"client intended to send too large body: %O bytes",
r->headers_in.content_length_n);
+ r->expect_tested = 1;
(void) ngx_http_discard_request_body(r);
ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
return NGX_OK;
@@ -4544,7 +4545,7 @@
ngx_str_null(&args);
- if (cv.lengths == NULL && uri.data[0] == '/') {
+ if (cv.lengths == NULL && uri.len && uri.data[0] == '/') {
p = (u_char *) ngx_strchr(uri.data, '?');
if (p) {
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/ngx_http_script.c
^
|
@@ -114,11 +114,6 @@
v = ccv->value;
- if (v->len == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, ccv->cf, 0, "empty parameter");
- return NGX_ERROR;
- }
-
nv = 0;
nc = 0;
@@ -133,8 +128,9 @@
}
}
- if (v->data[0] != '$' && (ccv->conf_prefix || ccv->root_prefix)) {
-
+ if ((v->len == 0 || v->data[0] != '$')
+ && (ccv->conf_prefix || ccv->root_prefix))
+ {
if (ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix) != NGX_OK) {
return NGX_ERROR;
}
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/ngx_http_upstream.c
^
|
@@ -636,6 +636,14 @@
found:
+ if (uscf == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+ "no upstream configuration");
+ ngx_http_upstream_finalize_request(r, u,
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
if (uscf->peer.init(r, uscf) != NGX_OK) {
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -3091,6 +3099,7 @@
r->connection->log->action = "sending to client";
if (rc == 0
+ && !r->header_only
#if (NGX_HTTP_CACHE)
&& !r->cached
#endif
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/ngx_http_upstream_round_robin.c
^
|
@@ -474,7 +474,9 @@
rrp->peers = peers->next;
pc->tries = rrp->peers->number;
- n = rrp->peers->number / (8 * sizeof(uintptr_t)) + 1;
+ n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1))
+ / (8 * sizeof(uintptr_t));
+
for (i = 0; i < n; i++) {
rrp->tried[i] = 0;
}
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/ngx_http_variables.c
^
|
@@ -73,12 +73,16 @@
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_body_bytes_sent(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_pipe(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_request_completion(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_request_body(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_request_body_file(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_request_length(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_request_time(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_status(ngx_http_request_t *r,
@@ -112,6 +116,10 @@
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_msec(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_time_iso8601(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_time_local(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
/*
* TODO:
@@ -229,6 +237,9 @@
{ ngx_string("body_bytes_sent"), NULL, ngx_http_variable_body_bytes_sent,
0, 0, 0 },
+ { ngx_string("pipe"), NULL, ngx_http_variable_pipe,
+ 0, 0, 0 },
+
{ ngx_string("request_completion"), NULL,
ngx_http_variable_request_completion,
0, 0, 0 },
@@ -241,6 +252,9 @@
ngx_http_variable_request_body_file,
0, 0, 0 },
+ { ngx_string("request_length"), NULL, ngx_http_variable_request_length,
+ 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
+
{ ngx_string("request_time"), NULL, ngx_http_variable_request_time,
0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
@@ -295,6 +309,12 @@
{ ngx_string("msec"), NULL, ngx_http_variable_msec,
0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
+ { ngx_string("time_iso8601"), NULL, ngx_http_variable_time_iso8601,
+ 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
+
+ { ngx_string("time_local"), NULL, ngx_http_variable_time_local,
+ 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
+
#if (NGX_HAVE_TCP_INFO)
{ ngx_string("tcpinfo_rtt"), NULL, ngx_http_variable_tcpinfo,
0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
@@ -328,6 +348,12 @@
ngx_http_variable_t *v;
ngx_http_core_main_conf_t *cmcf;
+ if (name->len == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid variable name \"$\"");
+ return NULL;
+ }
+
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
key = cmcf->variables_keys->keys.elts;
@@ -391,6 +417,12 @@
ngx_http_variable_t *v;
ngx_http_core_main_conf_t *cmcf;
+ if (name->len == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid variable name \"$\"");
+ return NGX_ERROR;
+ }
+
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
v = cmcf->variables.elts;
@@ -1509,6 +1541,20 @@
static ngx_int_t
+ngx_http_variable_pipe(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+{
+ v->data = (u_char *) (r->pipeline ? "p" : ".");
+ v->len = 1;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
ngx_http_variable_status(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
@@ -1843,6 +1889,27 @@
static ngx_int_t
+ngx_http_variable_request_length(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+{
+ u_char *p;
+
+ p = ngx_pnalloc(r->pool, NGX_OFF_T_LEN);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ v->len = ngx_sprintf(p, "%O", r->request_length) - p;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = p;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
ngx_http_variable_request_time(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
@@ -1980,6 +2047,53 @@
v->valid = 1;
v->no_cacheable = 0;
v->not_found = 0;
+ v->data = p;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_variable_time_iso8601(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+{
+ u_char *p;
+
+ p = ngx_pnalloc(r->pool, ngx_cached_http_log_iso8601.len);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(p, ngx_cached_http_log_iso8601.data,
+ ngx_cached_http_log_iso8601.len);
+
+ v->len = ngx_cached_http_log_iso8601.len;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = p;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_variable_time_local(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+{
+ u_char *p;
+
+ p = ngx_pnalloc(r->pool, ngx_cached_http_log_time.len);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(p, ngx_cached_http_log_time.data, ngx_cached_http_log_time.len);
+
+ v->len = ngx_cached_http_log_time.len;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
v->data = p;
return NGX_OK;
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/http/ngx_http_write_filter_module.c
^
|
@@ -207,7 +207,7 @@
}
if (r->limit_rate) {
- limit = r->limit_rate * (ngx_time() - r->start_sec + 1)
+ limit = (off_t) r->limit_rate * (ngx_time() - r->start_sec + 1)
- (c->sent - clcf->limit_rate_after);
if (limit <= 0) {
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/os/unix/ngx_files.c
^
|
@@ -363,7 +363,7 @@
{
int n;
- n = glob((char *) gl->pattern, GLOB_NOSORT, NULL, &gl->pglob);
+ n = glob((char *) gl->pattern, 0, NULL, &gl->pglob);
if (n == 0) {
return NGX_OK;
|
[-]
[+]
|
Changed |
nginx-1.2.7.tar.bz2/src/os/unix/ngx_user.c
^
|
@@ -28,30 +28,27 @@
{
char *value;
size_t len;
- ngx_err_t err;
struct crypt_data cd;
- ngx_set_errno(0);
-
cd.initialized = 0;
/* work around the glibc bug */
cd.current_salt[0] = ~salt[0];
value = crypt_r((char *) key, (char *) salt, &cd);
- err = ngx_errno;
-
- if (err == 0) {
+ if (value) {
len = ngx_strlen(value) + 1;
*encrypted = ngx_pnalloc(pool, len);
- if (*encrypted) {
- ngx_memcpy(*encrypted, value, len);
- return NGX_OK;
+ if (*encrypted == NULL) {
+ return NGX_ERROR;
}
+
+ ngx_memcpy(*encrypted, value, len);
+ return NGX_OK;
}
- ngx_log_error(NGX_LOG_CRIT, pool->log, err, "crypt_r() failed");
+ ngx_log_error(NGX_LOG_CRIT, pool->log, ngx_errno, "crypt_r() failed");
return NGX_ERROR;
}
@@ -75,18 +72,20 @@
#endif
- ngx_set_errno(0);
-
value = crypt((char *) key, (char *) salt);
if (value) {
len = ngx_strlen(value) + 1;
*encrypted = ngx_pnalloc(pool, len);
- if (*encrypted) {
- ngx_memcpy(*encrypted, value, len);
+ if (*encrypted == NULL) {
+#if (NGX_THREADS && NGX_NONREENTRANT_CRYPT)
+ ngx_mutex_unlock(ngx_crypt_mutex);
+#endif
+ return NGX_ERROR;
}
+ ngx_memcpy(*encrypted, value, len);
#if (NGX_THREADS && NGX_NONREENTRANT_CRYPT)
ngx_mutex_unlock(ngx_crypt_mutex);
#endif
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/README.md
^
|
@@ -143,7 +143,7 @@
#
# Multiple exec lines can be specified.
- exec /usr/bin/ffmpeg -re -i rtmp://localhost:1935/$app/$name -vcodec flv -acodec copy -s 32x32 -f flv rtmp://localhost:1935/small/${name};
+ exec ffmpeg -re -i rtmp://localhost:1935/$app/$name -vcodec flv -acodec copy -s 32x32 -f flv rtmp://localhost:1935/small/${name};
}
application small {
@@ -151,6 +151,13 @@
# Video with reduced resolution comes here from ffmpeg
}
+ application webcam {
+ live on;
+
+ # Stream from local webcam
+ exec_static ffmpeg -f video4linux2 -i /dev/video0 -c:v libx264 -an -f flv rtmp://localhost:1935/webcam/mystream;
+ }
+
application mypush {
live on;
@@ -168,6 +175,13 @@
# and play locally
pull rtmp://rtmp3.example.com pageUrl=www.example.com/index.html;
}
+
+ application mystaticpull {
+ live on;
+
+ # Static pull is started at nginx start
+ pull rtmp://rtmp4.example.com pageUrl=www.example.com/index.html name=mystream static;
+ }
# video on demand
application vod {
@@ -275,7 +289,11 @@
location /hls {
# Serve HLS fragments
+ types {
+ application/vnd.apple.mpegurl m3u8;
+ }
alias /tmp/app;
+ expires -1;
}
}
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/TODO
^
|
@@ -1,12 +1,9 @@
-- multiple tracks in vod/mp4
-
-- HLS problem on publish restart
+- HLS monotonical dts
+- total client counter
- improve session epoch variable
-- exec_init
-
- fix auto-pushing to cache manager
- HDS
@@ -16,5 +13,3 @@
- multiple streams per connection
- VOD HLS
-
-- sync exec
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/hls/ngx_rtmp_hls_module.c
^
|
@@ -431,6 +431,7 @@
p = ngx_snprintf(buffer, sizeof(buffer),
"#EXTM3U\r\n"
"#EXT-X-TARGETDURATION:%i\r\n"
+ "#EXT-X-ALLOW-CACHE:NO\r\n"
"#EXT-X-MEDIA-SEQUENCE:%i\r\n\r\n",
/*TODO: float*/(ngx_int_t)(hacf->fraglen / 1000), ffrag);
n = write(fd, buffer, p - buffer);
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/ngx_rtmp.h
^
|
@@ -188,6 +188,7 @@
/* connection parameters */
ngx_str_t app;
+ ngx_str_t args;
ngx_str_t flashver;
ngx_str_t swf_url;
ngx_str_t tc_url;
@@ -214,6 +215,7 @@
/* auto-pushed? */
unsigned auto_pushed:1;
unsigned relay:1;
+ unsigned static_relay:1;
/* input stream 0 (reserved by RTMP spec)
* is used as free chain link */
@@ -573,6 +575,9 @@
extern ngx_rtmp_bandwidth_t ngx_rtmp_bw_in;
+extern ngx_uint_t ngx_rtmp_naccepted;
+
+
extern ngx_uint_t ngx_rtmp_max_module;
extern ngx_module_t ngx_rtmp_core_module;
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/ngx_rtmp_auto_push_module.c
^
|
@@ -401,7 +401,7 @@
ngx_rtmp_auto_push_conf_t *apcf;
ngx_rtmp_auto_push_ctx_t *ctx;
- if (s->auto_pushed || s->relay) {
+ if (s->auto_pushed || (s->relay && !s->static_relay)) {
goto next;
}
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/ngx_rtmp_cmd_module.c
^
|
@@ -10,21 +10,53 @@
#define NGX_RTMP_CAPABILITIES 31
-ngx_rtmp_connect_pt ngx_rtmp_connect;
-ngx_rtmp_create_stream_pt ngx_rtmp_create_stream;
-ngx_rtmp_close_stream_pt ngx_rtmp_close_stream;
-ngx_rtmp_delete_stream_pt ngx_rtmp_delete_stream;
-ngx_rtmp_publish_pt ngx_rtmp_publish;
-ngx_rtmp_play_pt ngx_rtmp_play;
-ngx_rtmp_seek_pt ngx_rtmp_seek;
-ngx_rtmp_pause_pt ngx_rtmp_pause;
-
-
-ngx_rtmp_stream_begin_pt ngx_rtmp_stream_begin;
-ngx_rtmp_stream_eof_pt ngx_rtmp_stream_eof;
-ngx_rtmp_stream_dry_pt ngx_rtmp_stream_dry;
-ngx_rtmp_recorded_pt ngx_rtmp_recorded;
-ngx_rtmp_set_buflen_pt ngx_rtmp_set_buflen;
+static ngx_int_t ngx_rtmp_cmd_connect(ngx_rtmp_session_t *s,
+ ngx_rtmp_connect_t *v);
+static ngx_int_t ngx_rtmp_cmd_disconnect(ngx_rtmp_session_t *s);
+static ngx_int_t ngx_rtmp_cmd_create_stream(ngx_rtmp_session_t *s,
+ ngx_rtmp_create_stream_t *v);
+static ngx_int_t ngx_rtmp_cmd_close_stream(ngx_rtmp_session_t *s,
+ ngx_rtmp_close_stream_t *v);
+static ngx_int_t ngx_rtmp_cmd_delete_stream(ngx_rtmp_session_t *s,
+ ngx_rtmp_delete_stream_t *v);
+static ngx_int_t ngx_rtmp_cmd_publish(ngx_rtmp_session_t *s,
+ ngx_rtmp_publish_t *v);
+static ngx_int_t ngx_rtmp_cmd_play(ngx_rtmp_session_t *s,
+ ngx_rtmp_play_t *v);
+static ngx_int_t ngx_rtmp_cmd_seek(ngx_rtmp_session_t *s,
+ ngx_rtmp_seek_t *v);
+static ngx_int_t ngx_rtmp_cmd_pause(ngx_rtmp_session_t *s,
+ ngx_rtmp_pause_t *v);
+
+
+static ngx_int_t ngx_rtmp_cmd_stream_begin(ngx_rtmp_session_t *s,
+ ngx_rtmp_stream_begin_t *v);
+static ngx_int_t ngx_rtmp_cmd_stream_eof(ngx_rtmp_session_t *s,
+ ngx_rtmp_stream_eof_t *v);
+static ngx_int_t ngx_rtmp_cmd_stream_dry(ngx_rtmp_session_t *s,
+ ngx_rtmp_stream_dry_t *v);
+static ngx_int_t ngx_rtmp_cmd_recorded(ngx_rtmp_session_t *s,
+ ngx_rtmp_recorded_t *v);
+static ngx_int_t ngx_rtmp_cmd_set_buflen(ngx_rtmp_session_t *s,
+ ngx_rtmp_set_buflen_t *v);
+
+
+ngx_rtmp_connect_pt ngx_rtmp_connect = ngx_rtmp_cmd_connect;
+ngx_rtmp_disconnect_pt ngx_rtmp_disconnect = ngx_rtmp_cmd_disconnect;
+ngx_rtmp_create_stream_pt ngx_rtmp_create_stream = ngx_rtmp_cmd_create_stream;
+ngx_rtmp_close_stream_pt ngx_rtmp_close_stream = ngx_rtmp_cmd_close_stream;
+ngx_rtmp_delete_stream_pt ngx_rtmp_delete_stream = ngx_rtmp_cmd_delete_stream;
+ngx_rtmp_publish_pt ngx_rtmp_publish = ngx_rtmp_cmd_publish;
+ngx_rtmp_play_pt ngx_rtmp_play = ngx_rtmp_cmd_play;
+ngx_rtmp_seek_pt ngx_rtmp_seek = ngx_rtmp_cmd_seek;
+ngx_rtmp_pause_pt ngx_rtmp_pause = ngx_rtmp_cmd_pause;
+
+
+ngx_rtmp_stream_begin_pt ngx_rtmp_stream_begin = ngx_rtmp_cmd_stream_begin;
+ngx_rtmp_stream_eof_pt ngx_rtmp_stream_eof = ngx_rtmp_cmd_stream_eof;
+ngx_rtmp_stream_dry_pt ngx_rtmp_stream_dry = ngx_rtmp_cmd_stream_dry;
+ngx_rtmp_recorded_pt ngx_rtmp_recorded = ngx_rtmp_cmd_recorded;
+ngx_rtmp_set_buflen_pt ngx_rtmp_set_buflen = ngx_rtmp_cmd_set_buflen;
static ngx_int_t ngx_rtmp_cmd_postconfiguration(ngx_conf_t *cf);
@@ -58,6 +90,22 @@
};
+static void
+ngx_rtmp_cmd_fill_args(u_char name[NGX_RTMP_MAX_NAME],
+ u_char args[NGX_RTMP_MAX_ARGS])
+{
+ u_char *p;
+
+ p = (u_char *)ngx_strchr(name, '?');
+ if (p == NULL) {
+ return;
+ }
+
+ *p++ = 0;
+ ngx_cpystrn(args, p, NGX_RTMP_MAX_ARGS);
+}
+
+
static ngx_int_t
ngx_rtmp_cmd_connect_init(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
ngx_chain_t *in)
@@ -124,6 +172,16 @@
v.app[len - 1] = 0;
}
+ ngx_rtmp_cmd_fill_args(v.app, v.args);
+
+ ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
+ "connect: app='%s' args='%s' flashver='%s' swf_url='%s' "
+ "tc_url='%s' page_url='%s' acodecs=%uD vcodecs=%uD "
+ "object_encoding=%ui",
+ v.app, v.args, v.flashver, v.swf_url, v.tc_url, v.page_url,
+ (uint32_t)v.acodecs, (uint32_t)v.vcodecs,
+ (ngx_int_t)v.object_encoding);
+
return ngx_rtmp_connect(s, &v);
}
@@ -198,14 +256,6 @@
cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);
- ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
- "connect: app='%s' flashver='%s' swf_url='%s' "
- "tc_url='%s' page_url='%s' acodecs=%uD vcodecs=%uD "
- "object_encoding=%ui",
- v->app, v->flashver, v->swf_url, v->tc_url, v->page_url,
- (uint32_t)v->acodecs, (uint32_t)v->vcodecs,
- (ngx_int_t)v->object_encoding);
-
trans = v->trans;
/* fill session parameters */
@@ -222,6 +272,7 @@
ngx_memcpy(s->name.data, v->name, s->name.len)
NGX_RTMP_SET_STRPAR(app);
+ NGX_RTMP_SET_STRPAR(args);
NGX_RTMP_SET_STRPAR(flashver);
NGX_RTMP_SET_STRPAR(swf_url);
NGX_RTMP_SET_STRPAR(tc_url);
@@ -409,22 +460,6 @@
}
-static void
-ngx_rtmp_cmd_fill_args(u_char name[NGX_RTMP_MAX_NAME],
- u_char args[NGX_RTMP_MAX_ARGS])
-{
- u_char *p;
-
- p = (u_char *)ngx_strchr(name, '?');
- if (p == NULL) {
- return;
- }
-
- *p++ = 0;
- ngx_cpystrn(args, p, NGX_RTMP_MAX_ARGS);
-}
-
-
static ngx_int_t
ngx_rtmp_cmd_publish_init(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
ngx_chain_t *in)
@@ -586,11 +621,18 @@
static ngx_int_t
-ngx_rtmp_cmd_disconnect(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
+ngx_rtmp_cmd_disconnect_init(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
ngx_chain_t *in)
{
ngx_log_error(NGX_LOG_INFO, s->connection->log, 0, "disconnect");
+ return ngx_rtmp_disconnect(s);
+}
+
+
+static ngx_int_t
+ngx_rtmp_cmd_disconnect(ngx_rtmp_session_t *s)
+{
return ngx_rtmp_delete_stream(s, NULL);
}
@@ -707,7 +749,7 @@
return NGX_ERROR;
}
- *h = ngx_rtmp_cmd_disconnect;
+ *h = ngx_rtmp_cmd_disconnect_init;
/* register AMF callbacks */
@@ -724,22 +766,5 @@
*ch = *bh;
}
- /* set initial handlers */
-
- ngx_rtmp_connect = ngx_rtmp_cmd_connect;
- ngx_rtmp_create_stream = ngx_rtmp_cmd_create_stream;
- ngx_rtmp_close_stream = ngx_rtmp_cmd_close_stream;
- ngx_rtmp_delete_stream = ngx_rtmp_cmd_delete_stream;
- ngx_rtmp_publish = ngx_rtmp_cmd_publish;
- ngx_rtmp_play = ngx_rtmp_cmd_play;
- ngx_rtmp_seek = ngx_rtmp_cmd_seek;
- ngx_rtmp_pause = ngx_rtmp_cmd_pause;
-
- ngx_rtmp_stream_begin = ngx_rtmp_cmd_stream_begin;
- ngx_rtmp_stream_eof = ngx_rtmp_cmd_stream_eof;
- ngx_rtmp_stream_dry = ngx_rtmp_cmd_stream_dry;
- ngx_rtmp_recorded = ngx_rtmp_cmd_recorded;
- ngx_rtmp_set_buflen = ngx_rtmp_cmd_set_buflen;
-
return NGX_OK;
}
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/ngx_rtmp_cmd_module.h
^
|
@@ -13,7 +13,6 @@
#include "ngx_rtmp.h"
-#define NGX_RTMP_MAX_APP 128
#define NGX_RTMP_MAX_NAME 256
#define NGX_RTMP_MAX_URL 256
#define NGX_RTMP_MAX_ARGS NGX_RTMP_MAX_NAME
@@ -23,7 +22,8 @@
typedef struct {
double trans;
- u_char app[NGX_RTMP_MAX_APP];
+ u_char app[NGX_RTMP_MAX_NAME];
+ u_char args[NGX_RTMP_MAX_ARGS];
u_char flashver[32];
u_char swf_url[NGX_RTMP_MAX_URL];
u_char tc_url[NGX_RTMP_MAX_URL];
@@ -98,6 +98,7 @@
typedef ngx_int_t (*ngx_rtmp_connect_pt)(ngx_rtmp_session_t *s,
ngx_rtmp_connect_t *v);
+typedef ngx_int_t (*ngx_rtmp_disconnect_pt)(ngx_rtmp_session_t *s);
typedef ngx_int_t (*ngx_rtmp_create_stream_pt)(ngx_rtmp_session_t *s,
ngx_rtmp_create_stream_t *v);
typedef ngx_int_t (*ngx_rtmp_close_stream_pt)(ngx_rtmp_session_t *s,
@@ -126,6 +127,7 @@
extern ngx_rtmp_connect_pt ngx_rtmp_connect;
+extern ngx_rtmp_disconnect_pt ngx_rtmp_disconnect;
extern ngx_rtmp_create_stream_pt ngx_rtmp_create_stream;
extern ngx_rtmp_close_stream_pt ngx_rtmp_close_stream;
extern ngx_rtmp_delete_stream_pt ngx_rtmp_delete_stream;
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/ngx_rtmp_exec_module.c
^
|
@@ -16,12 +16,18 @@
static ngx_rtmp_close_stream_pt next_close_stream;
+static ngx_int_t ngx_rtmp_exec_init_process(ngx_cycle_t *cycle);
static ngx_int_t ngx_rtmp_exec_postconfiguration(ngx_conf_t *cf);
+static void * ngx_rtmp_exec_create_main_conf(ngx_conf_t *cf);
+static char * ngx_rtmp_exec_init_main_conf(ngx_conf_t *cf, void *conf);
static void * ngx_rtmp_exec_create_app_conf(ngx_conf_t *cf);
static char * ngx_rtmp_exec_merge_app_conf(ngx_conf_t *cf,
- void *parent, void *child);
+ void *parent, void *child);
static char * ngx_rtmp_exec_exec(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
+ void *conf);
+static char * ngx_rtmp_exec_exec_static(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static void ngx_rtmp_exec_respawn(ngx_event_t *ev);
#define NGX_RTMP_EXEC_RESPAWN 0x01
@@ -30,41 +36,50 @@
typedef struct {
ngx_str_t cmd;
- ngx_array_t args; /* ngx_str_t */
+ ngx_array_t args; /* ngx_str_t */
} ngx_rtmp_exec_conf_t;
typedef struct {
- ngx_array_t execs; /* ngx_rtmp_exec_conf_t */
- ngx_msec_t respawn_timeout;
- ngx_flag_t respawn;
- ngx_int_t kill_signal;
-} ngx_rtmp_exec_app_conf_t;
-
-
-typedef struct {
- ngx_rtmp_session_t *session;
- size_t index;
+ ngx_rtmp_exec_conf_t *conf;
+ ngx_log_t *log;
+ ngx_rtmp_session_t *session; /* NULL for init execs */
unsigned active:1;
- int pid;
+ ngx_pid_t pid;
+ ngx_pid_t *save_pid;
int pipefd;
ngx_connection_t dummy_conn; /*needed by ngx_xxx_event*/
ngx_event_t read_evt, write_evt;
ngx_event_t respawn_evt;
+ ngx_msec_t respawn_timeout;
+ ngx_int_t kill_signal;
} ngx_rtmp_exec_t;
typedef struct {
+ ngx_array_t confs; /* ngx_rtmp_exec_conf_t */
+ ngx_array_t execs; /* ngx_rtmp_exec_t */
+ ngx_msec_t respawn_timeout;
+ ngx_int_t kill_signal;
+} ngx_rtmp_exec_main_conf_t;
+
+
+typedef struct {
+ ngx_array_t confs; /* ngx_rtmp_exec_conf_t */
+ ngx_flag_t respawn;
+} ngx_rtmp_exec_app_conf_t;
+
+
+typedef struct {
u_char name[NGX_RTMP_MAX_NAME];
- ngx_rtmp_exec_t *execs;
+ ngx_array_t execs;
} ngx_rtmp_exec_ctx_t;
static char *ngx_rtmp_exec_kill_signal(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
-static ngx_int_t ngx_rtmp_exec_kill(ngx_rtmp_session_t *s, ngx_rtmp_exec_t *e,
- ngx_int_t term);
-static ngx_int_t ngx_rtmp_exec_run(ngx_rtmp_session_t *s, size_t n);
+static ngx_int_t ngx_rtmp_exec_kill(ngx_rtmp_exec_t *e, ngx_int_t kill_signal);
+static ngx_int_t ngx_rtmp_exec_run(ngx_rtmp_exec_t *e);
static ngx_command_t ngx_rtmp_exec_commands[] = {
@@ -75,6 +90,13 @@
NGX_RTMP_APP_CONF_OFFSET,
0,
NULL },
+
+ { ngx_string("exec_static"),
+ NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_1MORE,
+ ngx_rtmp_exec_exec_static,
+ NGX_RTMP_MAIN_CONF_OFFSET,
+ 0,
+ NULL },
{ ngx_string("respawn"),
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
@@ -86,14 +108,14 @@
{ ngx_string("respawn_timeout"),
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
- NGX_RTMP_APP_CONF_OFFSET,
- offsetof(ngx_rtmp_exec_app_conf_t, respawn_timeout),
+ NGX_RTMP_MAIN_CONF_OFFSET,
+ offsetof(ngx_rtmp_exec_main_conf_t, respawn_timeout),
NULL },
{ ngx_string("exec_kill_signal"),
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
ngx_rtmp_exec_kill_signal,
- NGX_RTMP_APP_CONF_OFFSET,
+ NGX_RTMP_MAIN_CONF_OFFSET,
0,
NULL },
@@ -104,8 +126,8 @@
static ngx_rtmp_module_t ngx_rtmp_exec_module_ctx = {
NULL, /* preconfiguration */
ngx_rtmp_exec_postconfiguration, /* postconfiguration */
- NULL, /* create main configuration */
- NULL, /* init main configuration */
+ ngx_rtmp_exec_create_main_conf, /* create main configuration */
+ ngx_rtmp_exec_init_main_conf, /* init main configuration */
NULL, /* create server configuration */
NULL, /* merge server configuration */
ngx_rtmp_exec_create_app_conf, /* create app configuration */
@@ -120,7 +142,7 @@
NGX_RTMP_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
- NULL, /* init process */
+ ngx_rtmp_exec_init_process, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
@@ -164,6 +186,70 @@
static void *
+ngx_rtmp_exec_create_main_conf(ngx_conf_t *cf)
+{
+ ngx_rtmp_exec_main_conf_t *emcf;
+
+ emcf = ngx_pcalloc(cf->pool, sizeof(ngx_rtmp_exec_main_conf_t));
+ if (emcf == NULL) {
+ return NULL;
+ }
+
+ emcf->respawn_timeout = NGX_CONF_UNSET_MSEC;
+ emcf->kill_signal = NGX_CONF_UNSET;
+
+ if (ngx_array_init(&emcf->confs, cf->pool, 1,
+ sizeof(ngx_rtmp_exec_conf_t)) != NGX_OK)
+ {
+ return NULL;
+ }
+
+ return emcf;
+}
+
+
+static char *
+ngx_rtmp_exec_init_main_conf(ngx_conf_t *cf, void *conf)
+{
+ ngx_rtmp_exec_main_conf_t *emcf = conf;
+ ngx_rtmp_exec_conf_t *ec;
+ ngx_rtmp_exec_t *e;
+ ngx_uint_t n;
+
+ if (emcf->respawn_timeout == NGX_CONF_UNSET_MSEC) {
+ emcf->respawn_timeout = 5000;
+ }
+
+ if (emcf->kill_signal == NGX_CONF_UNSET) {
+ emcf->kill_signal = SIGKILL;
+ }
+
+ if (ngx_array_init(&emcf->execs, cf->pool, emcf->confs.nelts,
+ sizeof(ngx_rtmp_exec_t)) != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
+ }
+
+ e = ngx_array_push_n(&emcf->execs, emcf->confs.nelts);
+ if (e == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ec = emcf->confs.elts;
+
+ for (n = 0; n < emcf->confs.nelts; ++n, ++e, ++ec) {
+ ngx_memzero(e, sizeof(*e));
+ e->conf = ec;
+ e->log = &cf->cycle->new_log;
+ e->respawn_timeout = emcf->respawn_timeout;
+ e->kill_signal = emcf->kill_signal;
+ }
+
+ return NGX_CONF_OK;
+}
+
+
+static void *
ngx_rtmp_exec_create_app_conf(ngx_conf_t *cf)
{
ngx_rtmp_exec_app_conf_t *eacf;
@@ -174,11 +260,9 @@
}
eacf->respawn = NGX_CONF_UNSET;
- eacf->respawn_timeout = NGX_CONF_UNSET;
- eacf->kill_signal = NGX_CONF_UNSET;
- if (ngx_array_init(&eacf->execs, cf->pool, 1,
- sizeof(ngx_rtmp_exec_conf_t)) != NGX_OK)
+ if (ngx_array_init(&eacf->confs, cf->pool, 1,
+ sizeof(ngx_rtmp_exec_conf_t)) != NGX_OK)
{
return NULL;
}
@@ -196,17 +280,14 @@
ngx_rtmp_exec_conf_t *ec, *pec;
ngx_conf_merge_value(conf->respawn, prev->respawn, 1);
- ngx_conf_merge_msec_value(conf->respawn_timeout, prev->respawn_timeout,
- 5000);
- ngx_conf_merge_value(conf->kill_signal, prev->kill_signal, SIGKILL);
- if (prev->execs.nelts) {
- ec = ngx_array_push_n(&conf->execs, prev->execs.nelts);
+ if (prev->confs.nelts) {
+ ec = ngx_array_push_n(&conf->confs, prev->confs.nelts);
if (ec == NULL) {
return NGX_CONF_ERROR;
}
- pec = prev->execs.elts;
- for (n = 0; n < prev->execs.nelts; ++n, ++ec, ++pec) {
+ pec = prev->confs.elts;
+ for (n = 0; n < prev->confs.nelts; ++n, ++ec, ++pec) {
*ec = *pec;
}
}
@@ -215,61 +296,97 @@
}
+static ngx_int_t
+ngx_rtmp_exec_init_process(ngx_cycle_t *cycle)
+{
+ ngx_rtmp_core_main_conf_t *cmcf = ngx_rtmp_core_main_conf;
+ ngx_rtmp_core_srv_conf_t **cscf;
+ ngx_rtmp_conf_ctx_t *cctx;
+ ngx_rtmp_exec_main_conf_t *emcf;
+ ngx_rtmp_exec_t *e;
+ ngx_uint_t n;
+
+ if (cmcf == NULL || cmcf->servers.nelts == 0) {
+ return NGX_OK;
+ }
+
+ /* execs are always started by the first worker */
+ if (ngx_process_slot) {
+ return NGX_OK;
+ }
+
+ cscf = cmcf->servers.elts;
+ cctx = (*cscf)->ctx;
+ emcf = cctx->main_conf[ngx_rtmp_exec_module.ctx_index];
+
+ /* FreeBSD note:
+ * When worker is restarted, child process (ffmpeg) will
+ * not be terminated if it's connected to another
+ * (still alive) worker. That leads to starting
+ * another instance of exec_static process.
+ * Need to kill previously started processes.
+ *
+ * On Linux "prctl" syscall is used to kill child
+ * when nginx worker is terminated.
+ */
+
+ e = emcf->execs.elts;
+ for (n = 0; n < emcf->execs.nelts; ++n, ++e) {
+ e->respawn_evt.data = e;
+ e->respawn_evt.log = e->log;
+ e->respawn_evt.handler = ngx_rtmp_exec_respawn;
+ ngx_post_event((&e->respawn_evt), &ngx_posted_events);
+ }
+
+ return NGX_OK;
+}
+
+
static void
ngx_rtmp_exec_respawn(ngx_event_t *ev)
{
- ngx_rtmp_exec_t *e;
-
- e = ev->data;
- ngx_rtmp_exec_run(e->session, e->index);
+ ngx_rtmp_exec_run((ngx_rtmp_exec_t *) ev->data);
}
static void
ngx_rtmp_exec_child_dead(ngx_event_t *ev)
{
- ngx_connection_t *dummy_conn;
- ngx_rtmp_exec_t *e;
- ngx_rtmp_session_t *s;
- ngx_rtmp_exec_app_conf_t *eacf;
+ ngx_connection_t *dummy_conn = ev->data;
+ ngx_rtmp_exec_t *e;
- dummy_conn = ev->data;
e = dummy_conn->data;
- s = e->session;
- eacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_exec_module);
- ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
- "exec: child %ui exited; %s",
- (ngx_int_t)e->pid,
- eacf->respawn ? "respawning" : "ignoring");
+ ngx_log_debug2(NGX_LOG_DEBUG_RTMP, e->log, 0,
+ "exec: child %ui exited; %s", (ngx_int_t) e->pid,
+ e->respawn_timeout == NGX_CONF_UNSET_MSEC ? "respawning" :
+ "ignoring");
- ngx_rtmp_exec_kill(s, e, 0);
+ ngx_rtmp_exec_kill(e, 0);
- if (!eacf->respawn) {
+ if (e->respawn_timeout == NGX_CONF_UNSET_MSEC) {
return;
}
- if (eacf->respawn_timeout == 0) {
- ngx_rtmp_exec_run(s, e->index);
+ if (e->respawn_timeout == 0) {
+ ngx_rtmp_exec_run(e);
return;
}
- ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
- "exec: shedule respawn %Mmsec", eacf->respawn_timeout);
+ ngx_log_debug1(NGX_LOG_DEBUG_RTMP, e->log, 0,
+ "exec: shedule respawn %Mmsec", e->respawn_timeout);
+
e->respawn_evt.data = e;
- e->respawn_evt.log = s->connection->log;
+ e->respawn_evt.log = e->log;
e->respawn_evt.handler = ngx_rtmp_exec_respawn;
- ngx_add_timer(&e->respawn_evt, eacf->respawn_timeout);
+
+ ngx_add_timer(&e->respawn_evt, e->respawn_timeout);
}
static ngx_int_t
-ngx_rtmp_exec_kill(ngx_rtmp_session_t *s, ngx_rtmp_exec_t *e, ngx_int_t term)
+ngx_rtmp_exec_kill(ngx_rtmp_exec_t *e, ngx_int_t kill_signal)
{
- ngx_rtmp_exec_app_conf_t *eacf;
-
- eacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_exec_module);
-
if (e->respawn_evt.timer_set) {
ngx_del_timer(&e->respawn_evt);
}
@@ -282,23 +399,26 @@
return NGX_OK;
}
- ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
- "exec: terminating child %ui",
- (ngx_int_t)e->pid);
+ ngx_log_debug1(NGX_LOG_DEBUG_RTMP, e->log, 0,
+ "exec: terminating child %ui",
+ (ngx_int_t) e->pid);
e->active = 0;
close(e->pipefd);
+ if (e->save_pid) {
+ *e->save_pid = NGX_INVALID_PID;
+ }
- if (!term) {
+ if (kill_signal == 0) {
return NGX_OK;
}
- if (kill(e->pid, eacf->kill_signal) == -1) {
- ngx_log_error(NGX_LOG_INFO, s->connection->log, ngx_errno,
- "exec: kill failed pid=%i", (ngx_int_t)e->pid);
+ if (kill(e->pid, kill_signal) == -1) {
+ ngx_log_error(NGX_LOG_INFO, e->log, ngx_errno,
+ "exec: kill failed pid=%i", (ngx_int_t) e->pid);
} else {
- ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
- "exec: killed pid=%i", (ngx_int_t)e->pid);
+ ngx_log_debug1(NGX_LOG_DEBUG_RTMP, e->log, 0,
+ "exec: killed pid=%i", (ngx_int_t) e->pid);
}
return NGX_OK;
@@ -306,34 +426,32 @@
static ngx_int_t
-ngx_rtmp_exec_run(ngx_rtmp_session_t *s, size_t n)
+ngx_rtmp_exec_run(ngx_rtmp_exec_t *e)
{
#if !(NGX_WIN32)
- ngx_rtmp_exec_app_conf_t *eacf;
- ngx_rtmp_exec_ctx_t *ctx;
- int pid, fd, maxfd;
+ ngx_pid_t pid;
+ int fd, maxfd;
int pipefd[2];
int ret;
ngx_rtmp_exec_conf_t *ec;
- ngx_rtmp_exec_t *e;
ngx_str_t *arg, a;
char **args;
+ ngx_uint_t n;
- eacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_exec_module);
- ec = (ngx_rtmp_exec_conf_t *)eacf->execs.elts + n;
-
- ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_exec_module);
- e = ctx->execs + n;
+ ec = e->conf;
- ngx_memzero(e, sizeof(*e));
+ ngx_log_debug1(NGX_LOG_DEBUG_RTMP, e->log, 0,
+ "exec: starting child '%V'", &ec->cmd);
- ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
- "exec: starting child '%V'",
- &ec->cmd);
+ if (e->active) {
+ ngx_log_debug1(NGX_LOG_DEBUG_RTMP, e->log, 0,
+ "exec: already active '%V'", &ec->cmd);
+ return NGX_OK;
+ }
if (pipe(pipefd) == -1) {
- ngx_log_error(NGX_LOG_INFO, s->connection->log, ngx_errno,
- "exec: pipe failed");
+ ngx_log_error(NGX_LOG_INFO, e->log, ngx_errno,
+ "exec: pipe failed");
return NGX_ERROR;
}
@@ -346,8 +464,8 @@
if (ret == -1) {
close(pipefd[0]);
close(pipefd[1]);
- ngx_log_error(NGX_LOG_INFO, s->connection->log, ngx_errno,
- "exec: fcntl failed");
+ ngx_log_error(NGX_LOG_INFO, e->log, ngx_errno,
+ "exec: fcntl failed");
return NGX_ERROR;
}
@@ -356,13 +474,17 @@
case -1:
close(pipefd[0]);
close(pipefd[1]);
- ngx_log_error(NGX_LOG_INFO, s->connection->log, ngx_errno,
- "exec: fork failed");
+ ngx_log_error(NGX_LOG_INFO, e->log, ngx_errno,
+ "exec: fork failed");
return NGX_ERROR;
case 0:
/* child */
+#if (NGX_LINUX)
+ prctl(PR_SET_PDEATHSIG, e->kill_signal, 0, 0, 0);
+#endif
+
/* close all descriptors but pipe write end */
maxfd = sysconf(_SC_OPEN_MAX);
for (fd = 0; fd < maxfd; ++fd) {
@@ -379,19 +501,22 @@
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
- args = ngx_palloc(s->connection->pool,
- (ec->args.nelts + 2) * sizeof(char *));
+ args = ngx_alloc((ec->args.nelts + 2) * sizeof(char *), e->log);
if (args == NULL) {
exit(1);
}
arg = ec->args.elts;
- args[0] = (char *)ec->cmd.data;
+ args[0] = (char *) ec->cmd.data;
for (n = 0; n < ec->args.nelts; ++n, ++arg) {
- ngx_rtmp_eval(s, arg, ngx_rtmp_exec_eval_p, &a);
+ if (e->session == NULL) {
+ a = *arg;
+ } else {
+ ngx_rtmp_eval(e->session, arg, ngx_rtmp_exec_eval_p, &a);
+ }
args[n + 1] = (char *) a.data;
}
args[n + 1] = NULL;
- if (execvp((char *)ec->cmd.data, args) == -1) {
+ if (execvp((char *) ec->cmd.data, args) == -1) {
exit(1);
}
break;
@@ -399,11 +524,12 @@
default:
/* parent */
close(pipefd[1]);
- e->session = s;
- e->index = n;
e->active = 1;
e->pid = pid;
e->pipefd = pipefd[0];
+ if (e->save_pid) {
+ *e->save_pid = pid;
+ }
e->dummy_conn.fd = e->pipefd;
e->dummy_conn.data = e;
@@ -412,17 +538,17 @@
e->read_evt.data = &e->dummy_conn;
e->write_evt.data = &e->dummy_conn;
- e->read_evt.log = s->connection->log;
+ e->read_evt.log = e->log;
e->read_evt.handler = ngx_rtmp_exec_child_dead;
if (ngx_add_event(&e->read_evt, NGX_READ_EVENT, 0) != NGX_OK) {
- ngx_log_error(NGX_LOG_INFO, s->connection->log, ngx_errno,
- "exec: failed to add child control event");
+ ngx_log_error(NGX_LOG_INFO, e->log, ngx_errno,
+ "exec: failed to add child control event");
}
- ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
- "exec: child '%V' started pid=%ui",
- &ec->cmd, (ngx_uint_t)pid);
+ ngx_log_debug2(NGX_LOG_DEBUG_RTMP, e->log, 0,
+ "exec: child '%V' started pid=%i",
+ &ec->cmd, (ngx_int_t) pid);
break;
}
#endif /* NGX_WIN32 */
@@ -444,16 +570,16 @@
}
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_exec_module);
- if (ctx == NULL || ctx->execs == NULL) {
+ if (ctx == NULL || ctx->execs.nelts == 0) {
goto next;
}
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
- "exec: delete %uz command(s)", eacf->execs.nelts);
+ "exec: delete %uz command(s)", ctx->execs.nelts);
- e = ctx->execs;
- for (n = 0; n < eacf->execs.nelts; ++n, ++e) {
- ngx_rtmp_exec_kill(s, e, 1);
+ e = ctx->execs.elts;
+ for (n = 0; n < ctx->execs.nelts; ++n, ++e) {
+ ngx_rtmp_exec_kill(e, e->kill_signal);
}
next:
@@ -464,13 +590,16 @@
static ngx_int_t
ngx_rtmp_exec_publish(ngx_rtmp_session_t *s, ngx_rtmp_publish_t *v)
{
+ ngx_rtmp_exec_main_conf_t *emcf;
ngx_rtmp_exec_app_conf_t *eacf;
+ ngx_rtmp_exec_t *e;
ngx_rtmp_exec_conf_t *ec;
ngx_rtmp_exec_ctx_t *ctx;
size_t n;
+ emcf = ngx_rtmp_get_module_main_conf(s, ngx_rtmp_exec_module);
eacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_exec_module);
- if (eacf == NULL || eacf->execs.nelts == 0) {
+ if (eacf == NULL || eacf->confs.nelts == 0) {
goto next;
}
@@ -479,23 +608,46 @@
}
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_exec_module);
+
if (ctx == NULL) {
ctx = ngx_pcalloc(s->connection->pool, sizeof(ngx_rtmp_exec_ctx_t));
if (ctx == NULL) {
return NGX_ERROR;
}
+
ngx_rtmp_set_ctx(s, ctx, ngx_rtmp_exec_module);
- ctx->execs = ngx_pcalloc(s->connection->pool, eacf->execs.nelts
- * sizeof(ngx_rtmp_exec_t));
+
+ if (ngx_array_init(&ctx->execs, s->connection->pool, eacf->confs.nelts,
+ sizeof(ngx_rtmp_exec_t)) != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ e = ngx_array_push_n(&ctx->execs, eacf->confs.nelts);
+ if (e == NULL) {
+ return NGX_ERROR;
+ }
+
+ ec = eacf->confs.elts;
+ for (n = 0; n < eacf->confs.nelts; ++n, ++e, ++ec) {
+ ngx_memzero(e, sizeof(*e));
+ e->conf = ec;
+ e->log = s->connection->log;
+ e->session = s;
+ e->kill_signal = emcf->kill_signal;
+ e->respawn_timeout = (eacf->respawn ? emcf->respawn_timeout :
+ NGX_CONF_UNSET_MSEC);
+ }
}
+
ngx_memcpy(ctx->name, v->name, NGX_RTMP_MAX_NAME);
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
- "exec: run %uz command(s)", eacf->execs.nelts);
+ "exec: run %uz command(s)", ctx->execs.nelts);
- ec = eacf->execs.elts;
- for (n = 0; n < eacf->execs.nelts; ++n, ++ec) {
- ngx_rtmp_exec_run(s, n);
+ e = ctx->execs.elts;
+ for (n = 0; n < ctx->execs.nelts; ++n, ++e) {
+ ngx_rtmp_exec_run(e);
}
next:
@@ -515,7 +667,46 @@
eacf = ngx_rtmp_conf_get_module_app_conf(cf, ngx_rtmp_exec_module);
value = cf->args->elts;
- ec = ngx_array_push(&eacf->execs);
+ ec = ngx_array_push(&eacf->confs);
+ if (ec == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ec->cmd = value[1];
+
+ if (cf->args->nelts == 2) {
+ return NGX_CONF_OK;
+ }
+
+ nargs = cf->args->nelts - 2;
+ if (ngx_array_init(&ec->args, cf->pool, nargs,
+ sizeof(ngx_str_t)) != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
+ }
+
+ s = ngx_array_push_n(&ec->args, nargs);
+ for (n = 2; n < cf->args->nelts; ++n, ++s) {
+ *s = value[n];
+ }
+
+ return NGX_CONF_OK;
+}
+
+
+static char *
+ngx_rtmp_exec_exec_static(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_rtmp_exec_main_conf_t *emcf = conf;
+
+ ngx_str_t *value;
+ size_t n, nargs;
+ ngx_str_t *s;
+ ngx_rtmp_exec_conf_t *ec;
+
+ value = cf->args->elts;
+
+ ec = ngx_array_push(&emcf->confs);
if (ec == NULL) {
return NGX_CONF_ERROR;
}
@@ -528,7 +719,7 @@
nargs = cf->args->nelts - 2;
if (ngx_array_init(&ec->args, cf->pool, nargs,
- sizeof(ngx_str_t)) != NGX_OK)
+ sizeof(ngx_str_t)) != NGX_OK)
{
return NGX_CONF_ERROR;
}
@@ -545,15 +736,14 @@
static char *
ngx_rtmp_exec_kill_signal(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
- ngx_rtmp_exec_app_conf_t *eacf;
+ ngx_rtmp_exec_main_conf_t *emcf = conf;
ngx_str_t *value;
- eacf = ngx_rtmp_conf_get_module_app_conf(cf, ngx_rtmp_exec_module);
value = cf->args->elts;
value++;
- eacf->kill_signal = ngx_atoi(value->data, value->len);
- if (eacf->kill_signal != NGX_ERROR) {
+ emcf->kill_signal = ngx_atoi(value->data, value->len);
+ if (emcf->kill_signal != NGX_ERROR) {
return NGX_CONF_OK;
}
@@ -561,7 +751,7 @@
if (value->len == sizeof(#name) - 1 && \
ngx_strncasecmp(value->data, (u_char *) #name, value->len) == 0) \
{ \
- eacf->kill_signal = SIG##name; \
+ emcf->kill_signal = SIG##name; \
return NGX_CONF_OK; \
}
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/ngx_rtmp_flv_module.c
^
|
@@ -12,7 +12,8 @@
static void ngx_rtmp_flv_read_meta(ngx_rtmp_session_t *s, ngx_file_t *f);
static ngx_int_t ngx_rtmp_flv_timestamp_to_offset(ngx_rtmp_session_t *s,
ngx_file_t *f, ngx_int_t timestamp);
-static ngx_int_t ngx_rtmp_flv_init(ngx_rtmp_session_t *s, ngx_file_t *f);
+static ngx_int_t ngx_rtmp_flv_init(ngx_rtmp_session_t *s, ngx_file_t *f,
+ ngx_int_t aindex, ngx_int_t vindex);
static ngx_int_t ngx_rtmp_flv_start(ngx_rtmp_session_t *s, ngx_file_t *f);
static ngx_int_t ngx_rtmp_flv_seek(ngx_rtmp_session_t *s, ngx_file_t *f,
ngx_uint_t offset);
@@ -548,7 +549,8 @@
static ngx_int_t
-ngx_rtmp_flv_init(ngx_rtmp_session_t *s, ngx_file_t *f)
+ngx_rtmp_flv_init(ngx_rtmp_session_t *s, ngx_file_t *f, ngx_int_t aindex,
+ ngx_int_t vindex)
{
ngx_rtmp_flv_ctx_t *ctx;
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/ngx_rtmp_handler.c
^
|
@@ -13,6 +13,9 @@
static ngx_int_t ngx_rtmp_finalize_set_chunk_size(ngx_rtmp_session_t *s);
+ngx_uint_t ngx_rtmp_naccepted;
+
+
ngx_rtmp_bandwidth_t ngx_rtmp_bw_out;
ngx_rtmp_bandwidth_t ngx_rtmp_bw_in;
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/ngx_rtmp_init.c
^
|
@@ -26,6 +26,7 @@
ngx_rtmp_in6_addr_t *addr6;
#endif
+ ++ngx_rtmp_naccepted;
/* find the server configuration for the address:port */
@@ -239,6 +240,10 @@
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, c->log, 0, "close connection");
+#if (NGX_STAT_STUB)
+ (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
+#endif
+
pool = c->pool;
ngx_close_connection(c);
ngx_destroy_pool(pool);
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/ngx_rtmp_live_module.c
^
|
@@ -176,10 +176,10 @@
ngx_conf_merge_msec_value(conf->sync, prev->sync, 300);
ngx_conf_merge_msec_value(conf->idle_timeout, prev->idle_timeout, 0);
ngx_conf_merge_value(conf->interleave, prev->interleave, 0);
- ngx_conf_merge_value(conf->wait_key, prev->wait_key, 0);
+ ngx_conf_merge_value(conf->wait_key, prev->wait_key, 1);
ngx_conf_merge_value(conf->wait_video, prev->wait_video, 0);
ngx_conf_merge_value(conf->publish_notify, prev->publish_notify, 0);
- ngx_conf_merge_value(conf->play_restart, prev->play_restart, 1);
+ ngx_conf_merge_value(conf->play_restart, prev->play_restart, 0);
conf->pool = ngx_create_pool(4096, &cf->cycle->new_log);
if (conf->pool == NULL) {
@@ -377,10 +377,9 @@
if (lacf->play_restart) {
status[nstatus++] = ngx_rtmp_create_status(s, "NetStream.Play.Start",
"status", "Start live");
+ status[nstatus++] = ngx_rtmp_create_sample_access(s);
}
- status[nstatus++] = ngx_rtmp_create_sample_access(s);
-
if (lacf->publish_notify) {
status[nstatus++] = ngx_rtmp_create_status(s,
"NetStream.Play.PublishNotify",
@@ -541,8 +540,8 @@
s->out_buffer = 1;
}
- ctx->cs[0].csid = NGX_RTMP_CSID_AUDIO;
- ctx->cs[1].csid = NGX_RTMP_CSID_VIDEO;
+ ctx->cs[0].csid = NGX_RTMP_CSID_VIDEO;
+ ctx->cs[1].csid = NGX_RTMP_CSID_AUDIO;
if (!ctx->publishing && ctx->stream->active) {
ngx_rtmp_live_start(s);
@@ -670,7 +669,7 @@
ngx_rtmp_live_ctx_t *ctx, *pctx;
ngx_rtmp_codec_ctx_t *codec_ctx;
ngx_chain_t *header, *coheader, *meta,
- *apkt, *acopkt, *rpkt;
+ *apkt, *aapkt, *acopkt, *rpkt;
ngx_rtmp_core_srv_conf_t *cscf;
ngx_rtmp_live_app_conf_t *lacf;
ngx_rtmp_session_t *ss;
@@ -722,6 +721,7 @@
peers = 0;
apkt = NULL;
+ aapkt = NULL;
acopkt = NULL;
header = NULL;
coheader = NULL;
@@ -870,6 +870,13 @@
continue;
}
+ if (lacf->wait_video && h->type == NGX_RTMP_MSG_VIDEO &&
+ aapkt == NULL)
+ {
+ aapkt = ngx_rtmp_alloc_shared_buf(cscf);
+ ngx_rtmp_prepare_message(s, &clh, NULL, aapkt);
+ }
+
if (header || coheader) {
/* send absolute codec header */
@@ -900,6 +907,9 @@
if (rc != NGX_OK) {
continue;
}
+
+ } else if (aapkt) {
+ ngx_rtmp_send_message(ss, aapkt, 0);
}
cs->timestamp = lh.timestamp;
@@ -928,6 +938,10 @@
++peers;
+ if (aapkt) {
+ ngx_rtmp_send_message(ss, aapkt, 0);
+ }
+
continue;
}
}
@@ -964,6 +978,10 @@
ngx_rtmp_free_shared_chain(cscf, apkt);
}
+ if (aapkt) {
+ ngx_rtmp_free_shared_chain(cscf, aapkt);
+ }
+
if (acopkt) {
ngx_rtmp_free_shared_chain(cscf, acopkt);
}
@@ -1043,6 +1061,7 @@
if (!ctx->silent && !lacf->play_restart) {
ngx_rtmp_send_status(s, "NetStream.Play.Start",
"status", "Start live");
+ ngx_rtmp_send_sample_access(s);
}
next:
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/ngx_rtmp_mp4_module.c
^
|
@@ -9,7 +9,8 @@
static ngx_int_t ngx_rtmp_mp4_postconfiguration(ngx_conf_t *cf);
-static ngx_int_t ngx_rtmp_mp4_init(ngx_rtmp_session_t *s, ngx_file_t *f);
+static ngx_int_t ngx_rtmp_mp4_init(ngx_rtmp_session_t *s, ngx_file_t *f,
+ ngx_int_t aindex, ngx_int_t vindex);
static ngx_int_t ngx_rtmp_mp4_done(ngx_rtmp_session_t *s, ngx_file_t *f);
static ngx_int_t ngx_rtmp_mp4_start(ngx_rtmp_session_t *s, ngx_file_t *f);
static ngx_int_t ngx_rtmp_mp4_seek(ngx_rtmp_session_t *s, ngx_file_t *f,
@@ -173,6 +174,9 @@
ngx_uint_t sample_size;
ngx_uint_t sample_rate;
+ ngx_int_t atracks, vtracks;
+ ngx_int_t aindex, vindex;
+
uint32_t start_timestamp, epoch;
} ngx_rtmp_mp4_ctx_t;
@@ -368,6 +372,26 @@
{
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"mp4: adding track %ui", ctx->ntracks);
+
+ if (ctx->track->type == NGX_RTMP_MSG_AUDIO) {
+ if (ctx->atracks++ != ctx->aindex) {
+ ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
+ "mp4: skipping audio track %ui!=%ui",
+ ctx->atracks - 1, ctx->aindex);
+ ctx->track = NULL;
+ return NGX_OK;
+ }
+
+ } else {
+ if (ctx->vtracks++ != ctx->vindex) {
+ ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
+ "mp4: skipping video track %i!=%i",
+ ctx->vtracks - 1, ctx->vindex);
+ ctx->track = NULL;
+ return NGX_OK;
+ }
+ }
+
++ctx->ntracks;
} else {
@@ -2168,12 +2192,14 @@
static ngx_int_t
-ngx_rtmp_mp4_init(ngx_rtmp_session_t *s, ngx_file_t *f)
+ngx_rtmp_mp4_init(ngx_rtmp_session_t *s, ngx_file_t *f, ngx_int_t aindex,
+ ngx_int_t vindex)
{
ngx_rtmp_mp4_ctx_t *ctx;
uint32_t hdr[2];
ssize_t n;
- size_t offset, page_offset, size;
+ size_t offset, page_offset, size, shift;
+ uint64_t extended_size;
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_mp4_module);
@@ -2189,6 +2215,9 @@
ngx_memzero(ctx, sizeof(*ctx));
+ ctx->aindex = aindex;
+ ctx->vindex = vindex;
+
offset = 0;
size = 0;
@@ -2203,6 +2232,22 @@
}
size = ngx_rtmp_r32(hdr[0]);
+ shift = sizeof(hdr);
+
+ if (size == 1) {
+ n = ngx_read_file(f, (u_char *) &extended_size,
+ sizeof(extended_size), offset + sizeof(hdr));
+
+ if (n != sizeof(extended_size)) {
+ ngx_log_error(NGX_LOG_ERR, s->connection->log, ngx_errno,
+ "mp4: error reading file at offset=%uz "
+ "while searching for moov box", offset + 8);
+ return NGX_ERROR;
+ }
+
+ size = ngx_rtmp_r64(extended_size);
+ shift += sizeof(extended_size);
+ }
if (hdr[1] == ngx_rtmp_mp4_make_tag('m','o','o','v')) {
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
@@ -2216,12 +2261,12 @@
offset += size;
}
- if (size < 8) {
+ if (size < shift) {
return NGX_ERROR;
}
- size -= 8;
- offset += 8;
+ size -= shift;
+ offset += shift;
page_offset = offset & (ngx_pagesize - 1);
ctx->mmaped_size = page_offset + size;
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/ngx_rtmp_netcall_module.c
^
|
@@ -9,9 +9,9 @@
static ngx_int_t ngx_rtmp_netcall_postconfiguration(ngx_conf_t *cf);
-static void * ngx_rtmp_netcall_create_app_conf(ngx_conf_t *cf);
-static char * ngx_rtmp_netcall_merge_app_conf(ngx_conf_t *cf,
- void *parent, void *child);
+static void * ngx_rtmp_netcall_create_srv_conf(ngx_conf_t *cf);
+static char * ngx_rtmp_netcall_merge_srv_conf(ngx_conf_t *cf,
+ void *parent, void *child);
static void ngx_rtmp_netcall_close(ngx_connection_t *cc);
static void ngx_rtmp_netcall_detach(ngx_connection_t *cc);
@@ -24,7 +24,7 @@
ngx_msec_t timeout;
size_t bufsize;
ngx_log_t *log;
-} ngx_rtmp_netcall_app_conf_t;
+} ngx_rtmp_netcall_srv_conf_t;
typedef struct ngx_rtmp_netcall_session_s {
@@ -55,15 +55,15 @@
{ ngx_string("netcall_timeout"),
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
- NGX_RTMP_APP_CONF_OFFSET,
- offsetof(ngx_rtmp_netcall_app_conf_t, timeout),
+ NGX_RTMP_SRV_CONF_OFFSET,
+ offsetof(ngx_rtmp_netcall_srv_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_APP_CONF_OFFSET,
- offsetof(ngx_rtmp_netcall_app_conf_t, bufsize),
+ NGX_RTMP_SRV_CONF_OFFSET,
+ offsetof(ngx_rtmp_netcall_srv_conf_t, bufsize),
NULL },
ngx_null_command
@@ -75,10 +75,10 @@
ngx_rtmp_netcall_postconfiguration, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
- ngx_rtmp_netcall_create_app_conf, /* create app configuration */
- ngx_rtmp_netcall_merge_app_conf /* merge app configuration */
+ ngx_rtmp_netcall_create_srv_conf, /* create server configuration */
+ ngx_rtmp_netcall_merge_srv_conf, /* merge server configuration */
+ NULL, /* create app configuration */
+ NULL /* merge app configuration */
};
@@ -99,29 +99,29 @@
static void *
-ngx_rtmp_netcall_create_app_conf(ngx_conf_t *cf)
+ngx_rtmp_netcall_create_srv_conf(ngx_conf_t *cf)
{
- ngx_rtmp_netcall_app_conf_t *nacf;
+ ngx_rtmp_netcall_srv_conf_t *nscf;
- nacf = ngx_pcalloc(cf->pool, sizeof(ngx_rtmp_netcall_app_conf_t));
- if (nacf == NULL) {
+ nscf = ngx_pcalloc(cf->pool, sizeof(ngx_rtmp_netcall_srv_conf_t));
+ if (nscf == NULL) {
return NULL;
}
- nacf->timeout = NGX_CONF_UNSET_MSEC;
- nacf->bufsize = NGX_CONF_UNSET_SIZE;
+ nscf->timeout = NGX_CONF_UNSET_MSEC;
+ nscf->bufsize = NGX_CONF_UNSET_SIZE;
- nacf->log = &cf->cycle->new_log;
+ nscf->log = &cf->cycle->new_log;
- return nacf;
+ return nscf;
}
static char *
-ngx_rtmp_netcall_merge_app_conf(ngx_conf_t *cf, void *parent, void *child)
+ngx_rtmp_netcall_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
{
- ngx_rtmp_netcall_app_conf_t *prev = parent;
- ngx_rtmp_netcall_app_conf_t *conf = child;
+ ngx_rtmp_netcall_srv_conf_t *prev = parent;
+ ngx_rtmp_netcall_srv_conf_t *conf = child;
ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 10000);
ngx_conf_merge_size_value(conf->bufsize, prev->bufsize, 1024);
@@ -175,7 +175,7 @@
ngx_rtmp_netcall_ctx_t *ctx;
ngx_peer_connection_t *pc;
ngx_rtmp_netcall_session_t *cs;
- ngx_rtmp_netcall_app_conf_t *cacf;
+ ngx_rtmp_netcall_srv_conf_t *nscf;
ngx_connection_t *c, *cc;
ngx_pool_t *pool;
ngx_int_t rc;
@@ -183,8 +183,8 @@
pool = NULL;
c = s->connection;
- cacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_netcall_module);
- if (cacf == NULL) {
+ nscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_netcall_module);
+ if (nscf == NULL) {
goto error;
}
@@ -203,7 +203,7 @@
* Note we use shared (app-wide) log because
* s->connection->log might be unavailable
* in detached netcall when it's being closed */
- pool = ngx_create_pool(4096, cacf->log);
+ pool = ngx_create_pool(4096, nscf->log);
if (pool == NULL) {
goto error;
}
@@ -227,8 +227,8 @@
ngx_memcpy(cs->arg, ci->arg, ci->argsize);
}
- cs->timeout = cacf->timeout;
- cs->bufsize = cacf->bufsize;
+ cs->timeout = nscf->timeout;
+ cs->bufsize = nscf->bufsize;
cs->url = ci->url;
cs->session = s;
cs->filter = ci->filter;
@@ -238,7 +238,7 @@
cs->detached = 1;
}
- pc->log = cacf->log;
+ pc->log = nscf->log;
pc->get = ngx_rtmp_netcall_get_peer;
pc->free = ngx_rtmp_netcall_free_peer;
pc->data = cs;
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/ngx_rtmp_notify_module.c
^
|
@@ -12,13 +12,17 @@
#include "ngx_rtmp_record_module.h"
+static ngx_rtmp_connect_pt next_connect;
+static ngx_rtmp_disconnect_pt next_disconnect;
static ngx_rtmp_publish_pt next_publish;
static ngx_rtmp_play_pt next_play;
static ngx_rtmp_close_stream_pt next_close_stream;
static ngx_rtmp_record_done_pt next_record_done;
-static char *ngx_rtmp_notify_on_event(ngx_conf_t *cf, ngx_command_t *cmd,
+static char *ngx_rtmp_notify_on_srv_event(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+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);
@@ -26,6 +30,9 @@
static void * ngx_rtmp_notify_create_app_conf(ngx_conf_t *cf);
static char * ngx_rtmp_notify_merge_app_conf(ngx_conf_t *cf,
void *parent, void *child);
+static void *ngx_rtmp_notify_create_srv_conf(ngx_conf_t *cf);
+static char *ngx_rtmp_notify_merge_srv_conf(ngx_conf_t *cf, void *parent,
+ void *child);
static ngx_int_t ngx_rtmp_notify_done(ngx_rtmp_session_t *s, char *cbname,
ngx_uint_t url_idx);
@@ -46,12 +53,19 @@
NGX_RTMP_NOTIFY_DONE,
NGX_RTMP_NOTIFY_RECORD_DONE,
NGX_RTMP_NOTIFY_UPDATE,
- NGX_RTMP_NOTIFY_MAX
+ NGX_RTMP_NOTIFY_APP_MAX
+};
+
+
+enum {
+ NGX_RTMP_NOTIFY_CONNECT,
+ NGX_RTMP_NOTIFY_DISCONNECT,
+ NGX_RTMP_NOTIFY_SRV_MAX
};
typedef struct {
- ngx_url_t *url[NGX_RTMP_NOTIFY_MAX];
+ ngx_url_t *url[NGX_RTMP_NOTIFY_APP_MAX];
ngx_flag_t active;
ngx_uint_t method;
ngx_msec_t update_timeout;
@@ -60,6 +74,12 @@
typedef struct {
+ ngx_url_t *url[NGX_RTMP_NOTIFY_SRV_MAX];
+ ngx_uint_t method;
+} ngx_rtmp_notify_srv_conf_t;
+
+
+typedef struct {
ngx_uint_t flags;
u_char name[NGX_RTMP_MAX_NAME];
u_char args[NGX_RTMP_MAX_ARGS];
@@ -75,37 +95,51 @@
static ngx_command_t ngx_rtmp_notify_commands[] = {
+ { ngx_string("on_connect"),
+ NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_rtmp_notify_on_srv_event,
+ NGX_RTMP_SRV_CONF_OFFSET,
+ 0,
+ NULL },
+
+ { ngx_string("on_disconnect"),
+ NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_rtmp_notify_on_srv_event,
+ NGX_RTMP_SRV_CONF_OFFSET,
+ 0,
+ NULL },
+
{ ngx_string("on_publish"),
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
- ngx_rtmp_notify_on_event,
+ ngx_rtmp_notify_on_app_event,
NGX_RTMP_APP_CONF_OFFSET,
0,
NULL },
{ ngx_string("on_play"),
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
- ngx_rtmp_notify_on_event,
+ ngx_rtmp_notify_on_app_event,
NGX_RTMP_APP_CONF_OFFSET,
0,
NULL },
{ ngx_string("on_publish_done"),
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
- ngx_rtmp_notify_on_event,
+ ngx_rtmp_notify_on_app_event,
NGX_RTMP_APP_CONF_OFFSET,
0,
NULL },
{ ngx_string("on_play_done"),
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
- ngx_rtmp_notify_on_event,
+ ngx_rtmp_notify_on_app_event,
NGX_RTMP_APP_CONF_OFFSET,
0,
NULL },
{ ngx_string("on_done"),
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
- ngx_rtmp_notify_on_event,
+ ngx_rtmp_notify_on_app_event,
NGX_RTMP_APP_CONF_OFFSET,
0,
NULL },
@@ -113,14 +147,14 @@
{ ngx_string("on_record_done"),
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_RTMP_REC_CONF|
NGX_CONF_TAKE1,
- ngx_rtmp_notify_on_event,
+ ngx_rtmp_notify_on_app_event,
NGX_RTMP_APP_CONF_OFFSET,
0,
NULL },
{ ngx_string("on_update"),
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
- ngx_rtmp_notify_on_event,
+ ngx_rtmp_notify_on_app_event,
NGX_RTMP_APP_CONF_OFFSET,
0,
NULL },
@@ -155,8 +189,8 @@
ngx_rtmp_notify_postconfiguration, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
+ ngx_rtmp_notify_create_srv_conf, /* create server configuration */
+ ngx_rtmp_notify_merge_srv_conf, /* merge server configuration */
ngx_rtmp_notify_create_app_conf, /* create app configuration */
ngx_rtmp_notify_merge_app_conf /* merge app configuration */
};
@@ -189,7 +223,7 @@
return NULL;
}
- for (n = 0; n < NGX_RTMP_NOTIFY_MAX; ++n) {
+ for (n = 0; n < NGX_RTMP_NOTIFY_APP_MAX; ++n) {
nacf->url[n] = NGX_CONF_UNSET_PTR;
}
@@ -208,7 +242,7 @@
ngx_rtmp_notify_app_conf_t *conf = child;
ngx_uint_t n;
- for (n = 0; n < NGX_RTMP_NOTIFY_MAX; ++n) {
+ for (n = 0; n < NGX_RTMP_NOTIFY_APP_MAX; ++n) {
ngx_conf_merge_ptr_value(conf->url[n], prev->url[n], NULL);
if (conf->url[n]) {
conf->active = 1;
@@ -229,9 +263,48 @@
}
+static void *
+ngx_rtmp_notify_create_srv_conf(ngx_conf_t *cf)
+{
+ ngx_rtmp_notify_srv_conf_t *nscf;
+ ngx_uint_t n;
+
+ nscf = ngx_pcalloc(cf->pool, sizeof(ngx_rtmp_notify_srv_conf_t));
+ if (nscf == NULL) {
+ return NULL;
+ }
+
+ for (n = 0; n < NGX_RTMP_NOTIFY_SRV_MAX; ++n) {
+ nscf->url[n] = NGX_CONF_UNSET_PTR;
+ }
+
+ nscf->method = NGX_CONF_UNSET;
+
+ return nscf;
+}
+
+
+static char *
+ngx_rtmp_notify_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
+{
+ ngx_rtmp_notify_srv_conf_t *prev = parent;
+ ngx_rtmp_notify_srv_conf_t *conf = child;
+ ngx_uint_t n;
+
+ for (n = 0; n < NGX_RTMP_NOTIFY_SRV_MAX; ++n) {
+ ngx_conf_merge_ptr_value(conf->url[n], prev->url[n], NULL);
+ }
+
+ ngx_conf_merge_uint_value(conf->method, prev->method,
+ NGX_RTMP_NETCALL_HTTP_POST);
+
+ return NGX_CONF_OK;
+}
+
+
static ngx_chain_t *
ngx_rtmp_notify_create_request(ngx_rtmp_session_t *s, ngx_pool_t *pool,
- ngx_uint_t url_idx, ngx_chain_t *args)
+ ngx_uint_t url_idx, ngx_chain_t *args)
{
ngx_rtmp_notify_app_conf_t *nacf;
ngx_chain_t *al, *bl, *cl;
@@ -263,6 +336,170 @@
static ngx_chain_t *
+ngx_rtmp_notify_connect_create(ngx_rtmp_session_t *s, void *arg,
+ ngx_pool_t *pool)
+{
+ ngx_rtmp_connect_t *v = arg;
+
+ ngx_rtmp_notify_srv_conf_t *nscf;
+ ngx_url_t *url;
+ ngx_chain_t *al, *bl;
+ ngx_buf_t *b;
+ ngx_str_t *addr_text;
+ size_t app_len, args_len, flashver_len,
+ swf_url_len, tc_url_len, page_url_len;
+
+ nscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_notify_module);
+
+ al = ngx_alloc_chain_link(pool);
+ if (al == NULL) {
+ return NULL;
+ }
+
+ /* these values are still missing in session
+ * so we have to construct the request from
+ * connection struct */
+
+ app_len = ngx_strlen(v->app);
+ args_len = ngx_strlen(v->args);
+ flashver_len = ngx_strlen(v->flashver);
+ swf_url_len = ngx_strlen(v->swf_url);
+ tc_url_len = ngx_strlen(v->tc_url);
+ page_url_len = ngx_strlen(v->page_url);
+
+ addr_text = &s->connection->addr_text;
+
+ b = ngx_create_temp_buf(pool,
+ sizeof("call=connect") - 1 +
+ sizeof("&app=") - 1 + app_len * 3 +
+ sizeof("&flashver=") - 1 + flashver_len * 3 +
+ sizeof("&swfurl=") - 1 + swf_url_len * 3 +
+ sizeof("&tcurl=") - 1 + tc_url_len * 3 +
+ sizeof("&pageurl=") - 1 + page_url_len * 3 +
+ sizeof("&addr=") - 1 + addr_text->len * 3 +
+ 1 + args_len
+ );
+
+ if (b == NULL) {
+ return NULL;
+ }
+
+ al->buf = b;
+ al->next = NULL;
+
+ b->last = ngx_cpymem(b->last, (u_char*) "app=", sizeof("app=") - 1);
+ b->last = (u_char*) ngx_escape_uri(b->last, v->app, app_len,
+ NGX_ESCAPE_ARGS);
+
+ b->last = ngx_cpymem(b->last, (u_char*) "&flashver=",
+ sizeof("&flashver=") - 1);
+ b->last = (u_char*) ngx_escape_uri(b->last, v->flashver, flashver_len,
+ NGX_ESCAPE_ARGS);
+
+ b->last = ngx_cpymem(b->last, (u_char*) "&swfurl=",
+ sizeof("&swfurl=") - 1);
+ b->last = (u_char*) ngx_escape_uri(b->last, v->swf_url, swf_url_len,
+ NGX_ESCAPE_ARGS);
+
+ b->last = ngx_cpymem(b->last, (u_char*) "&tcurl=",
+ sizeof("&tcurl=") - 1);
+ b->last = (u_char*) ngx_escape_uri(b->last, v->tc_url, tc_url_len,
+ NGX_ESCAPE_ARGS);
+
+ b->last = ngx_cpymem(b->last, (u_char*) "&pageurl=",
+ sizeof("&pageurl=") - 1);
+ b->last = (u_char*) ngx_escape_uri(b->last, v->page_url, page_url_len,
+ NGX_ESCAPE_ARGS);
+
+ b->last = ngx_cpymem(b->last, (u_char*) "&addr=", sizeof("&addr=") -1);
+ b->last = (u_char*) ngx_escape_uri(b->last, addr_text->data,
+ addr_text->len, NGX_ESCAPE_ARGS);
+
+ b->last = ngx_cpymem(b->last, (u_char*) "&call=connect",
+ sizeof("&call=connect") - 1);
+
+ if (args_len) {
+ *b->last++ = '&';
+ b->last = (u_char *) ngx_cpymem(b->last, v->args, args_len);
+ }
+
+ url = nscf->url[NGX_RTMP_NOTIFY_CONNECT];
+
+ bl = NULL;
+
+ if (nscf->method == NGX_RTMP_NETCALL_HTTP_POST) {
+ bl = al;
+ al = NULL;
+ }
+
+ return ngx_rtmp_netcall_http_format_request(nscf->method, &url->host,
+ &url->uri, al, bl, pool,
+ &ngx_rtmp_notify_urlencoded);
+}
+
+
+static ngx_chain_t *
+ngx_rtmp_notify_disconnect_create(ngx_rtmp_session_t *s, void *arg,
+ ngx_pool_t *pool)
+{
+ ngx_rtmp_notify_srv_conf_t *nscf;
+ ngx_url_t *url;
+ ngx_chain_t *al, *bl, *pl;
+ ngx_buf_t *b;
+
+ nscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_notify_module);
+
+ pl = ngx_alloc_chain_link(pool);
+ if (pl == NULL) {
+ return NULL;
+ }
+
+ b = ngx_create_temp_buf(pool,
+ sizeof("&call=disconnect") +
+ sizeof("&app=") + s->app.len * 3 +
+ 1 + s->args.len);
+ if (b == NULL) {
+ return NULL;
+ }
+
+ pl->buf = b;
+ pl->next = NULL;
+
+ b->last = ngx_cpymem(b->last, (u_char*) "&call=disconnect",
+ sizeof("&call=disconnect") - 1);
+
+ b->last = ngx_cpymem(b->last, (u_char*) "&app=", sizeof("&app=") - 1);
+ b->last = (u_char*) ngx_escape_uri(b->last, s->app.data, s->app.len,
+ NGX_ESCAPE_ARGS);
+
+ if (s->args.len) {
+ *b->last++ = '&';
+ b->last = (u_char *) ngx_cpymem(b->last, s->args.data, s->args.len);
+ }
+
+ url = nscf->url[NGX_RTMP_NOTIFY_DISCONNECT];
+
+ al = ngx_rtmp_netcall_http_format_session(s, pool);
+ if (al == NULL) {
+ return NULL;
+ }
+
+ al->next = pl;
+
+ bl = NULL;
+
+ if (nscf->method == NGX_RTMP_NETCALL_HTTP_POST) {
+ bl = al;
+ al = NULL;
+ }
+
+ return ngx_rtmp_netcall_http_format_request(nscf->method, &url->host,
+ &url->uri, al, bl, pool,
+ &ngx_rtmp_notify_urlencoded);
+}
+
+
+static ngx_chain_t *
ngx_rtmp_notify_publish_create(ngx_rtmp_session_t *s, void *arg,
ngx_pool_t *pool)
{
@@ -577,6 +814,18 @@
static ngx_int_t
+ngx_rtmp_notify_connect_handle(ngx_rtmp_session_t *s,
+ void *arg, ngx_chain_t *in)
+{
+ if (ngx_rtmp_notify_parse_http_retcode(s, in) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ return next_connect(s, (ngx_rtmp_connect_t *)arg);
+}
+
+
+static ngx_int_t
ngx_rtmp_notify_publish_handle(ngx_rtmp_session_t *s,
void *arg, ngx_chain_t *in)
{
@@ -723,6 +972,75 @@
static ngx_int_t
+ngx_rtmp_notify_connect(ngx_rtmp_session_t *s, ngx_rtmp_connect_t *v)
+{
+ ngx_rtmp_notify_srv_conf_t *nscf;
+ ngx_rtmp_netcall_init_t ci;
+ ngx_url_t *url;
+
+ if (s->auto_pushed || s->relay) {
+ goto next;
+ }
+
+ nscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_notify_module);
+
+ url = nscf->url[NGX_RTMP_NOTIFY_CONNECT];
+ if (url == NULL) {
+ goto next;
+ }
+
+ ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
+ "notify: connect '%V'", &url->url);
+
+ ngx_memzero(&ci, sizeof(ci));
+
+ ci.url = url;
+ ci.create = ngx_rtmp_notify_connect_create;
+ ci.handle = ngx_rtmp_notify_connect_handle;
+ ci.arg = v;
+ ci.argsize = sizeof(*v);
+
+ return ngx_rtmp_netcall_create(s, &ci);
+
+next:
+ return next_connect(s, v);
+}
+
+
+static ngx_int_t
+ngx_rtmp_notify_disconnect(ngx_rtmp_session_t *s)
+{
+ ngx_rtmp_notify_srv_conf_t *nscf;
+ ngx_rtmp_netcall_init_t ci;
+ ngx_url_t *url;
+
+ if (s->auto_pushed || s->relay) {
+ goto next;
+ }
+
+ nscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_notify_module);
+
+ url = nscf->url[NGX_RTMP_NOTIFY_DISCONNECT];
+ if (url == NULL) {
+ goto next;
+ }
+
+ ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
+ "notify: disconnect '%V'", &url->url);
+
+ ngx_memzero(&ci, sizeof(ci));
+
+ ci.url = url;
+ ci.create = ngx_rtmp_notify_disconnect_create;
+
+ ngx_rtmp_netcall_create(s, &ci);
+
+next:
+ return next_disconnect(s);
+}
+
+
+static ngx_int_t
ngx_rtmp_notify_publish(ngx_rtmp_session_t *s, ngx_rtmp_publish_t *v)
{
ngx_rtmp_notify_app_conf_t *nacf;
@@ -916,26 +1234,17 @@
}
-static char *
-ngx_rtmp_notify_on_event(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+static ngx_url_t *
+ngx_rtmp_notify_parse_url(ngx_conf_t *cf, ngx_str_t *url)
{
- ngx_rtmp_notify_app_conf_t *nacf = conf;
-
- ngx_str_t *url, *name;
- ngx_url_t *u;
- size_t add;
- ngx_str_t *value;
- ngx_uint_t n;
-
- value = cf->args->elts;
- name = &value[0];
- url = &value[1];
+ ngx_url_t *u;
+ size_t add;
add = 0;
u = ngx_pcalloc(cf->pool, sizeof(ngx_url_t));
if (u == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
if (ngx_strncasecmp(url->data, (u_char *) "http://", 7) == 0) {
@@ -952,9 +1261,67 @@
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"%s in url \"%V\"", u->err, &u->url);
}
+ return NULL;
+ }
+
+ return u;
+}
+
+
+static char *
+ngx_rtmp_notify_on_srv_event(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_rtmp_notify_srv_conf_t *nscf = conf;
+
+ ngx_str_t *name, *value;
+ ngx_url_t *u;
+ ngx_uint_t n;
+
+ value = cf->args->elts;
+
+ u = ngx_rtmp_notify_parse_url(cf, &value[1]);
+ if (u == NULL) {
return NGX_CONF_ERROR;
}
+ name = &value[0];
+
+ n = 0;
+
+ switch (name->len) {
+ case sizeof("on_connect") - 1:
+ n = NGX_RTMP_NOTIFY_CONNECT;
+ break;
+
+ case sizeof("on_disconnect") - 1:
+ n = NGX_RTMP_NOTIFY_DISCONNECT;
+ break;
+ }
+
+ nscf->url[n] = u;
+
+ return NGX_CONF_OK;
+}
+
+
+static char *
+ngx_rtmp_notify_on_app_event(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_rtmp_notify_app_conf_t *nacf = conf;
+
+ ngx_str_t *name, *value;
+ ngx_url_t *u;
+ ngx_uint_t n;
+
+ value = cf->args->elts;
+
+ u = ngx_rtmp_notify_parse_url(cf, &value[1]);
+ if (u == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ name = &value[0];
+
n = 0;
switch (name->len) {
@@ -998,6 +1365,7 @@
{
ngx_rtmp_notify_app_conf_t *nacf = conf;
+ ngx_rtmp_notify_srv_conf_t *nscf;
ngx_str_t *value;
value = cf->args->elts;
@@ -1017,6 +1385,9 @@
return "got unexpected method";
}
+ nscf = ngx_rtmp_conf_get_module_srv_conf(cf, ngx_rtmp_notify_module);
+ nscf->method = nacf->method;
+
return NGX_CONF_OK;
}
@@ -1024,6 +1395,12 @@
static ngx_int_t
ngx_rtmp_notify_postconfiguration(ngx_conf_t *cf)
{
+ next_connect = ngx_rtmp_connect;
+ ngx_rtmp_connect = ngx_rtmp_notify_connect;
+
+ next_disconnect = ngx_rtmp_disconnect;
+ ngx_rtmp_disconnect = ngx_rtmp_notify_disconnect;
+
next_publish = ngx_rtmp_publish;
ngx_rtmp_publish = ngx_rtmp_notify_publish;
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/ngx_rtmp_play_module.c
^
|
@@ -208,7 +208,7 @@
}
if (ctx->fmt && ctx->fmt->init &&
- ctx->fmt->init(s, &ctx->file) != NGX_OK)
+ ctx->fmt->init(s, &ctx->file, ctx->aindex, ctx->vindex) != NGX_OK)
{
return NGX_ERROR;
}
@@ -434,6 +434,33 @@
static ngx_int_t
+ngx_rtmp_play_parse_index(char type, u_char *args)
+{
+ u_char *p, c;
+ static u_char name[] = "xindex=";
+
+ name[0] = (u_char) type;
+
+ for ( ;; ) {
+ p = (u_char *) ngx_strstr(args, name);
+ if (p == NULL) {
+ return 0;
+ }
+
+ if (p != args) {
+ c = *(p - 1);
+ if (c != '?' && c != '&') {
+ args = p + 1;
+ continue;
+ }
+ }
+
+ return atoi((char *) p + (sizeof(name) - 1));
+ }
+}
+
+
+static ngx_int_t
ngx_rtmp_play_play(ngx_rtmp_session_t *s, ngx_rtmp_play_t *v)
{
ngx_rtmp_play_main_conf_t *pmcf;
@@ -487,6 +514,9 @@
ngx_memzero(ctx, sizeof(*ctx));
+ ctx->aindex = ngx_rtmp_play_parse_index('a', v->args);
+ ctx->vindex = ngx_rtmp_play_parse_index('v', v->args);
+
ctx->file.log = s->connection->log;
name.len = ngx_strlen(v->name);
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/ngx_rtmp_play_module.h
^
|
@@ -11,7 +11,7 @@
typedef ngx_int_t (*ngx_rtmp_play_init_pt) (ngx_rtmp_session_t *s,
- ngx_file_t *f);
+ ngx_file_t *f, ngx_int_t aindex, ngx_int_t vindex);
typedef ngx_int_t (*ngx_rtmp_play_done_pt) (ngx_rtmp_session_t *s,
ngx_file_t *f);
typedef ngx_int_t (*ngx_rtmp_play_start_pt) (ngx_rtmp_session_t *s,
@@ -45,6 +45,7 @@
unsigned playing:1;
ngx_uint_t ncrs;
ngx_str_t name;
+ ngx_int_t aindex, vindex;
} ngx_rtmp_play_ctx_t;
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/ngx_rtmp_relay_module.c
^
|
@@ -12,14 +12,18 @@
static ngx_rtmp_delete_stream_pt next_delete_stream;
+static ngx_int_t ngx_rtmp_relay_init_process(ngx_cycle_t *cycle);
static ngx_int_t ngx_rtmp_relay_postconfiguration(ngx_conf_t *cf);
static void * ngx_rtmp_relay_create_app_conf(ngx_conf_t *cf);
static char * ngx_rtmp_relay_merge_app_conf(ngx_conf_t *cf,
- void *parent, void *child);
+ void *parent, void *child);
static char * ngx_rtmp_relay_push_pull(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
+ void *conf);
static ngx_int_t ngx_rtmp_relay_publish(ngx_rtmp_session_t *s,
- ngx_rtmp_publish_t *v);
+ ngx_rtmp_publish_t *v);
+static ngx_rtmp_relay_ctx_t * ngx_rtmp_relay_create_connection(
+ ngx_rtmp_conf_ctx_t *cctx, ngx_str_t* name,
+ ngx_rtmp_relay_target_t *target);
/* _____
@@ -37,16 +41,25 @@
typedef struct {
- ngx_array_t pulls; /* ngx_rtmp_relay_target_t * */
- ngx_array_t pushes; /* ngx_rtmp_relay_target_t * */
- ngx_log_t *log;
- ngx_uint_t nbuckets;
- ngx_msec_t buflen;
- ngx_msec_t push_reconnect;
- ngx_rtmp_relay_ctx_t **ctx;
+ ngx_array_t pulls; /* ngx_rtmp_relay_target_t * */
+ ngx_array_t pushes; /* ngx_rtmp_relay_target_t * */
+ ngx_array_t static_pulls; /* ngx_rtmp_relay_target_t * */
+ ngx_array_t static_events; /* ngx_event_t * */
+ ngx_log_t *log;
+ ngx_uint_t nbuckets;
+ ngx_msec_t buflen;
+ ngx_msec_t push_reconnect;
+ ngx_msec_t pull_reconnect;
+ ngx_rtmp_relay_ctx_t **ctx;
} ngx_rtmp_relay_app_conf_t;
+typedef struct {
+ ngx_rtmp_conf_ctx_t cctx;
+ ngx_rtmp_relay_target_t *target;
+} ngx_rtmp_relay_static_t;
+
+
#define NGX_RTMP_RELAY_CONNECT_TRANS 1
#define NGX_RTMP_RELAY_CREATE_STREAM_TRANS 2
@@ -89,6 +102,13 @@
NGX_RTMP_APP_CONF_OFFSET,
offsetof(ngx_rtmp_relay_app_conf_t, push_reconnect),
NULL },
+
+ { ngx_string("pull_reconnect"),
+ NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_msec_slot,
+ NGX_RTMP_APP_CONF_OFFSET,
+ offsetof(ngx_rtmp_relay_app_conf_t, pull_reconnect),
+ NULL },
ngx_null_command
@@ -114,7 +134,7 @@
NGX_RTMP_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
- NULL, /* init process */
+ ngx_rtmp_relay_init_process, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
@@ -133,14 +153,31 @@
return NULL;
}
- ngx_array_init(&racf->pushes, cf->pool, 1,
- sizeof(ngx_rtmp_relay_target_t *));
- ngx_array_init(&racf->pulls, cf->pool, 1,
- sizeof(ngx_rtmp_relay_target_t *));
+ if (ngx_array_init(&racf->pushes, cf->pool, 1, sizeof(void *)) != NGX_OK) {
+ return NULL;
+ }
+
+ if (ngx_array_init(&racf->pulls, cf->pool, 1, sizeof(void *)) != NGX_OK) {
+ return NULL;
+ }
+
+ if (ngx_array_init(&racf->static_pulls, cf->pool, 1, sizeof(void *))
+ != NGX_OK)
+ {
+ return NULL;
+ }
+
+ if (ngx_array_init(&racf->static_events, cf->pool, 1, sizeof(void *))
+ != NGX_OK)
+ {
+ return NULL;
+ }
+
racf->nbuckets = 1024;
racf->log = &cf->cycle->new_log;
racf->buflen = NGX_CONF_UNSET;
racf->push_reconnect = NGX_CONF_UNSET;
+ racf->pull_reconnect = NGX_CONF_UNSET;
return racf;
}
@@ -158,13 +195,40 @@
ngx_conf_merge_msec_value(conf->buflen, prev->buflen, 5000);
ngx_conf_merge_msec_value(conf->push_reconnect, prev->push_reconnect,
3000);
+ ngx_conf_merge_msec_value(conf->pull_reconnect, prev->pull_reconnect,
+ 3000);
return NGX_CONF_OK;
}
static void
-ngx_rtmp_relay_reconnect(ngx_event_t *ev)
+ngx_rtmp_relay_static_pull_reconnect(ngx_event_t *ev)
+{
+ ngx_rtmp_relay_static_t *rs = ev->data;
+
+ ngx_rtmp_relay_ctx_t *ctx;
+ ngx_rtmp_relay_app_conf_t *racf;
+
+ racf = ngx_rtmp_get_module_app_conf(&rs->cctx, ngx_rtmp_relay_module);
+
+ ngx_log_debug0(NGX_LOG_DEBUG_RTMP, racf->log, 0,
+ "relay: reconnecting static pull");
+
+ ctx = ngx_rtmp_relay_create_connection(&rs->cctx, &rs->target->name,
+ rs->target);
+ if (ctx) {
+ ctx->session->static_relay = 1;
+ ctx->static_evt = ev;
+ return;
+ }
+
+ ngx_add_timer(ev, racf->pull_reconnect);
+}
+
+
+static void
+ngx_rtmp_relay_push_reconnect(ngx_event_t *ev)
{
ngx_rtmp_session_t *s = ev->data;
@@ -257,14 +321,14 @@
static ngx_rtmp_relay_ctx_t *
-ngx_rtmp_relay_create_remote_ctx(ngx_rtmp_session_t *s, ngx_str_t* name,
+ngx_rtmp_relay_create_connection(ngx_rtmp_conf_ctx_t *cctx, ngx_str_t* name,
ngx_rtmp_relay_target_t *target)
{
+ ngx_rtmp_relay_app_conf_t *racf;
ngx_rtmp_relay_ctx_t *rctx;
ngx_rtmp_addr_conf_t *addr_conf;
ngx_rtmp_conf_ctx_t *addr_ctx;
ngx_rtmp_session_t *rs;
- ngx_rtmp_relay_app_conf_t *racf;
ngx_peer_connection_t *pc;
ngx_connection_t *c;
ngx_pool_t *pool;
@@ -272,10 +336,10 @@
ngx_str_t v, *uri;
u_char *first, *last, *p;
- ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
- "relay: create remote context");
+ racf = ngx_rtmp_get_module_app_conf(cctx, ngx_rtmp_relay_module);
- racf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_relay_module);
+ ngx_log_debug0(NGX_LOG_DEBUG_RTMP, racf->log, 0,
+ "relay: create remote context");
pool = NULL;
pool = ngx_create_pool(4096, racf->log);
@@ -288,9 +352,11 @@
goto clear;
}
- if (ngx_rtmp_relay_copy_str(pool, &rctx->name, name) != NGX_OK ||
- ngx_rtmp_relay_copy_str(pool, &rctx->url, &target->url.url) != NGX_OK)
- {
+ if (name && ngx_rtmp_relay_copy_str(pool, &rctx->name, name) != NGX_OK) {
+ goto clear;
+ }
+
+ if (ngx_rtmp_relay_copy_str(pool, &rctx->url, &target->url.url) != NGX_OK) {
goto clear;
}
@@ -357,8 +423,6 @@
}
}
- rctx->relay = 1;
-
pc = ngx_pcalloc(pool, sizeof(ngx_peer_connection_t));
if (pc == NULL) {
goto clear;
@@ -395,8 +459,8 @@
goto clear;
}
addr_conf->ctx = addr_ctx;
- addr_ctx->main_conf = s->main_conf;
- addr_ctx->srv_conf = s->srv_conf;
+ addr_ctx->main_conf = cctx->main_conf;
+ addr_ctx->srv_conf = cctx->srv_conf;
ngx_str_set(&addr_conf->addr_text, "ngx-relay");
rs = ngx_rtmp_init_session(c, addr_conf);
@@ -404,12 +468,16 @@
/* no need to destroy pool */
return NULL;
}
- rs->app_conf = s->app_conf;
+ rs->app_conf = cctx->app_conf;
rs->relay = 1;
rctx->session = rs;
ngx_rtmp_set_ctx(rs, rctx, ngx_rtmp_relay_module);
ngx_str_set(&rs->flashver, "ngx-local-relay");
+#if (NGX_STAT_STUB)
+ (void) ngx_atomic_fetch_add(ngx_stat_active, 1);
+#endif
+
ngx_rtmp_client_handshake(rs, 1);
return rctx;
@@ -422,6 +490,20 @@
static ngx_rtmp_relay_ctx_t *
+ngx_rtmp_relay_create_remote_ctx(ngx_rtmp_session_t *s, ngx_str_t* name,
+ ngx_rtmp_relay_target_t *target)
+{
+ ngx_rtmp_conf_ctx_t cctx;
+
+ cctx.app_conf = s->app_conf;
+ cctx.srv_conf = s->srv_conf;
+ cctx.main_conf = s->main_conf;
+
+ return ngx_rtmp_relay_create_connection(&cctx, name, target);
+}
+
+
+static ngx_rtmp_relay_ctx_t *
ngx_rtmp_relay_create_local_ctx(ngx_rtmp_session_t *s, ngx_str_t *name,
ngx_rtmp_relay_target_t *target)
{
@@ -442,7 +524,7 @@
ctx->push_evt.data = s;
ctx->push_evt.log = s->connection->log;
- ctx->push_evt.handler = ngx_rtmp_relay_reconnect;
+ ctx->push_evt.handler = ngx_rtmp_relay_push_reconnect;
if (ctx->publish) {
return NULL;
@@ -554,7 +636,7 @@
}
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_relay_module);
- if (ctx && ctx->relay) {
+ if (ctx && s->relay) {
goto next;
}
@@ -606,7 +688,7 @@
ngx_rtmp_relay_ctx_t *ctx;
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_relay_module);
- if (ctx && ctx->relay) {
+ if (ctx && s->relay) {
goto next;
}
@@ -957,11 +1039,11 @@
}
if (ctx->live) {
- start = -1;
- duration = -1;
+ start = -1000;
+ duration = -1000;
} else {
- start = (ctx->start ? ctx->start : -2);
- duration = (ctx->stop ? ctx->stop - ctx->start : -1);
+ start = (ctx->start ? ctx->start : -2000);
+ duration = (ctx->stop ? ctx->stop - ctx->start : -1000);
}
ngx_memzero(&h, sizeof(h));
@@ -1022,7 +1104,7 @@
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_relay_module);
- if (ctx == NULL || !ctx->relay) {
+ if (ctx == NULL || !s->relay) {
return NGX_OK;
}
@@ -1042,7 +1124,7 @@
return ngx_rtmp_relay_send_create_stream(s);
case NGX_RTMP_RELAY_CREATE_STREAM_TRANS:
- if (ctx->publish != ctx) {
+ if (ctx->publish != ctx && !s->static_relay) {
if (ngx_rtmp_relay_send_publish(s) != NGX_OK) {
return NGX_ERROR;
}
@@ -1105,7 +1187,7 @@
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_relay_module);
- if (ctx == NULL || !ctx->relay) {
+ if (ctx == NULL || !s->relay) {
return NGX_OK;
}
@@ -1175,7 +1257,7 @@
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_relay_module);
- if (ctx == NULL || !ctx->relay) {
+ if (ctx == NULL || !s->relay) {
return NGX_OK;
}
@@ -1200,10 +1282,10 @@
ngx_rtmp_relay_handshake_done(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
ngx_chain_t *in)
{
- ngx_rtmp_relay_ctx_t *ctx;
+ ngx_rtmp_relay_ctx_t *ctx;
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_relay_module);
- if (ctx == NULL || ctx->publish == NULL) {
+ if (ctx == NULL || !s->relay) {
return NGX_OK;
}
@@ -1221,7 +1303,16 @@
racf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_relay_module);
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_relay_module);
- if (ctx == NULL || ctx->publish == NULL) {
+ if (ctx == NULL) {
+ goto next;
+ }
+
+ if (s->static_relay) {
+ ngx_add_timer(ctx->static_evt, racf->pull_reconnect);
+ goto next;
+ }
+
+ if (ctx->publish == NULL) {
goto next;
}
@@ -1239,7 +1330,7 @@
&ctx->app, &ctx->name);
/* push reconnect */
- if (ctx->relay && ctx->tag == &ngx_rtmp_relay_module &&
+ if (s->relay && ctx->tag == &ngx_rtmp_relay_module &&
!ctx->publish->push_evt.timer_set)
{
ngx_add_timer(&ctx->publish->push_evt, racf->push_reconnect);
@@ -1255,7 +1346,7 @@
}
#endif
- if (ctx->publish->play == NULL && ctx->publish->relay) {
+ if (ctx->publish->play == NULL && ctx->publish->session->relay) {
ngx_log_debug2(NGX_LOG_DEBUG_RTMP,
ctx->publish->session->connection->log, 0,
"relay: publish disconnect empty app='%V' name='%V'",
@@ -1306,28 +1397,23 @@
ngx_rtmp_relay_target_t *target, **t;
ngx_url_t *u;
ngx_uint_t i;
+ ngx_int_t is_pull, is_static;
+ ngx_event_t **ee, *e;
+ ngx_rtmp_relay_static_t *rs;
u_char *p;
value = cf->args->elts;
racf = ngx_rtmp_conf_get_module_app_conf(cf, ngx_rtmp_relay_module);
- t = ngx_array_push(value[0].data[3] == 'h'
- ? &racf->pushes /* push */
- : &racf->pulls /* pull */
- );
-
- if (t == NULL) {
- return NGX_CONF_ERROR;
- }
+ is_pull = (value[0].data[3] == 'l');
+ is_static = 0;
target = ngx_pcalloc(cf->pool, sizeof(*target));
if (target == NULL) {
return NGX_CONF_ERROR;
}
- *t = target;
-
target->tag = &ngx_rtmp_relay_module;
target->data = target;
@@ -1352,57 +1438,169 @@
value += 2;
for (i = 2; i < cf->args->nelts; ++i, ++value) {
p = ngx_strlchr(value->data, value->data + value->len, '=');
- if (p == NULL) {
- return "key=value expected";
- }
- if (p == value->data + value->len - 1) {
- continue;
- }
+ if (p == NULL) {
+ n = *value;
+ ngx_str_set(&v, "1");
- n.data = value->data;
- n.len = p - value->data;
+ } else {
+ n.data = value->data;
+ n.len = p - value->data;
- v.data = p + 1;
- v.len = value->data + value->len - p - 1;
+ v.data = p + 1;
+ v.len = value->data + value->len - p - 1;
+ }
#define NGX_RTMP_RELAY_STR_PAR(name, var) \
- if (n.len == sizeof(#name) - 1 \
- && ngx_strncasecmp(n.data, (u_char *)#name, n.len) == 0) \
+ if (n.len == sizeof(name) - 1 \
+ && ngx_strncasecmp(n.data, (u_char *) name, n.len) == 0) \
{ \
target->var = v; \
continue; \
}
#define NGX_RTMP_RELAY_NUM_PAR(name, var) \
- if (n.len == sizeof(#name) - 1 \
- && ngx_strncasecmp(n.data, (u_char *)#name, n.len) == 0) \
+ if (n.len == sizeof(name) - 1 \
+ && ngx_strncasecmp(n.data, (u_char *) name, n.len) == 0) \
{ \
target->var = ngx_atoi(v.data, v.len); \
continue; \
}
- NGX_RTMP_RELAY_STR_PAR(app, app);
- NGX_RTMP_RELAY_STR_PAR(name, name);
- NGX_RTMP_RELAY_STR_PAR(tcUrl, tc_url);
- NGX_RTMP_RELAY_STR_PAR(pageUrl, page_url);
- NGX_RTMP_RELAY_STR_PAR(swfUrl, swf_url);
- NGX_RTMP_RELAY_STR_PAR(flashVer, flash_ver);
- NGX_RTMP_RELAY_STR_PAR(playPath, play_path);
- NGX_RTMP_RELAY_NUM_PAR(live, live);
- NGX_RTMP_RELAY_NUM_PAR(start, start);
- NGX_RTMP_RELAY_NUM_PAR(stop, stop);
+ NGX_RTMP_RELAY_STR_PAR("app", app);
+ NGX_RTMP_RELAY_STR_PAR("name", name);
+ NGX_RTMP_RELAY_STR_PAR("tcUrl", tc_url);
+ NGX_RTMP_RELAY_STR_PAR("pageUrl", page_url);
+ NGX_RTMP_RELAY_STR_PAR("swfUrl", swf_url);
+ NGX_RTMP_RELAY_STR_PAR("flashVer", flash_ver);
+ NGX_RTMP_RELAY_STR_PAR("playPath", play_path);
+ NGX_RTMP_RELAY_NUM_PAR("live", live);
+ NGX_RTMP_RELAY_NUM_PAR("start", start);
+ NGX_RTMP_RELAY_NUM_PAR("stop", stop);
#undef NGX_RTMP_RELAY_STR_PAR
#undef NGX_RTMP_RELAY_NUM_PAR
+ if (n.len == sizeof("static") - 1 &&
+ ngx_strncasecmp(n.data, (u_char *) "static", n.len) == 0 &&
+ ngx_atoi(v.data, v.len))
+ {
+ is_static = 1;
+ continue;
+ }
+
return "unsuppored parameter";
}
+ if (is_static) {
+
+ if (!is_pull) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "static push is not allowed");
+ return NGX_CONF_ERROR;
+ }
+
+ if (target->name.len == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "stream name missing in static pull "
+ "declaration");
+ return NGX_CONF_ERROR;
+ }
+
+ ee = ngx_array_push(&racf->static_events);
+ if (ee == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ e = ngx_pcalloc(cf->pool, sizeof(ngx_event_t));
+ if (e == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *ee = e;
+
+ rs = ngx_pcalloc(cf->pool, sizeof(ngx_rtmp_relay_static_t));
+ if (rs == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ rs->target = target;
+
+ e->data = rs;
+ e->log = &cf->cycle->new_log;
+ e->handler = ngx_rtmp_relay_static_pull_reconnect;
+
+ t = ngx_array_push(&racf->static_pulls);
+
+ } else if (is_pull) {
+ t = ngx_array_push(&racf->pulls);
+
+ } else {
+ t = ngx_array_push(&racf->pushes);
+ }
+
+ if (t == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *t = target;
+
return NGX_CONF_OK;
}
+static ngx_int_t
+ngx_rtmp_relay_init_process(ngx_cycle_t *cycle)
+{
+ ngx_rtmp_core_main_conf_t *cmcf = ngx_rtmp_core_main_conf;
+ ngx_rtmp_core_srv_conf_t **pcscf, *cscf;
+ ngx_rtmp_core_app_conf_t **pcacf, *cacf;
+ ngx_rtmp_relay_app_conf_t *racf;
+ ngx_uint_t n, m, k;
+ ngx_rtmp_relay_static_t *rs;
+ ngx_rtmp_listen_t *lst;
+ ngx_event_t **pevent, *event;
+
+ if (cmcf == NULL || cmcf->listen.nelts == 0) {
+ return NGX_OK;
+ }
+
+ /* only first worker does static pulling */
+
+ if (ngx_process_slot) {
+ return NGX_OK;
+ }
+
+ lst = cmcf->listen.elts;
+
+ pcscf = cmcf->servers.elts;
+ for (n = 0; n < cmcf->servers.nelts; ++n, ++pcscf) {
+
+ cscf = *pcscf;
+ pcacf = cscf->applications.elts;
+
+ for (m = 0; m < cscf->applications.nelts; ++m, ++pcacf) {
+
+ cacf = *pcacf;
+ racf = cacf->app_conf[ngx_rtmp_relay_module.ctx_index];
+ pevent = racf->static_events.elts;
+
+ for (k = 0; k < racf->static_events.nelts; ++k, ++pevent) {
+ event = *pevent;
+
+ rs = event->data;
+ rs->cctx = *lst->ctx;
+ rs->cctx.app_conf = cacf->app_conf;
+
+ ngx_post_event(event, &ngx_posted_events);
+ }
+ }
+ }
+
+ return NGX_OK;
+}
+
+
static ngx_int_t
ngx_rtmp_relay_postconfiguration(ngx_conf_t *cf)
{
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/ngx_rtmp_relay_module.h
^
|
@@ -38,7 +38,6 @@
ngx_rtmp_relay_ctx_t *publish;
ngx_rtmp_relay_ctx_t *play;
ngx_rtmp_relay_ctx_t *next;
- unsigned relay:1;
ngx_str_t app;
ngx_str_t tc_url;
@@ -51,6 +50,7 @@
ngx_int_t stop;
ngx_event_t push_evt;
+ ngx_event_t *static_evt;
void *tag;
void *data;
};
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/ngx_rtmp_stat_module.c
^
|
@@ -96,7 +96,6 @@
};
-
#define NGX_RTMP_STAT_BUFSIZE 256
@@ -563,6 +562,11 @@
"%T", ngx_cached_time->sec - start_time) - tbuf);
NGX_RTMP_STAT_L("</uptime>\r\n");
+ NGX_RTMP_STAT_L("<naccepted>");
+ NGX_RTMP_STAT(nbuf, ngx_snprintf(nbuf, sizeof(nbuf),
+ "%ui", ngx_rtmp_naccepted) - nbuf);
+ NGX_RTMP_STAT_L("</naccepted>\r\n");
+
ngx_rtmp_stat_bw(r, lll, &ngx_rtmp_bw_in, &ngx_rtmp_bw_out);
cscf = cmcf->servers.elts;
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.7.tar.bz2/stat.xsl
^
|
@@ -36,7 +36,8 @@
<th>Time</th>
</tr>
<tr>
- <td colspan="2"/>
+ <td>@<xsl:value-of select="naccepted"/></td>
+ <td/>
<td><xsl:value-of select="in"/></td>
<td><xsl:value-of select="out"/></td>
<td><xsl:value-of select="round(bwin div 1024)"/></td>
|