Changes of Revision 29
[-] | Changed | nginx.spec |
x 1
2 %define nginx_datadir %{_datadir}/nginx 3 %define nginx_webroot %{nginx_datadir}/html 4 %define rtmp_ext nginx-rtmp-module 5 -%define rtmp_ext_version 0.9.1 6 +%define rtmp_ext_version 0.9.7 7 %define rtmp %{rtmp_ext}-%{rtmp_ext_version} 8 %define rtmp_nover %{rtmp_ext} 9 %define with_rtmp_ext 1 10 11 Name: nginx 12 -version: 1.2.6 13 -Release: 4 14 +version: 1.2.7 15 +Release: 1 16 Summary: Robust, small and high performance http and reverse proxy server 17 Group: System Environment/Daemons 18 19
20 21 22 %changelog 23 +* Tue Feb 12 2013 Carsten Schoene <cs@linux-administrator.com> - 1.2.7-1 24 +- update nginx to 1.2.7 25 +- update rtmp module to 0.9.7 26 + 27 * Fri Jan 25 2013 Carsten Schoene <cs@linux-administrator.com> - 1.2.6-4 28 - update rtmp module to 0.9.1 29 30 |
||
[+] | Changed | nginx-1.2.7.tar.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/src/http/modules/ngx_http_headers_filter_module.c ^ |
@@ -149,6 +149,7 @@ if ((conf->expires == NGX_HTTP_EXPIRES_OFF && conf->headers == NULL) || r != r->main || (r->headers_out.status != NGX_HTTP_OK + && r->headers_out.status != NGX_HTTP_CREATED && r->headers_out.status != NGX_HTTP_NO_CONTENT && r->headers_out.status != NGX_HTTP_PARTIAL_CONTENT && r->headers_out.status != NGX_HTTP_MOVED_PERMANENTLY | ||
[+] | Changed | nginx-1.2.7.tar.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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.gz/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> |