--- ../lighttpd-1.4.11/NEWS 2006-03-09 19:34:33.000000000 +0200
-+++ lighttpd-1.4.12/NEWS 2006-07-11 22:07:54.000000000 +0300
++++ lighttpd-1.4.12/NEWS 2006-07-16 00:26:05.000000000 +0300
@@ -3,6 +3,23 @@
NEWS
====
* added ability to specify which ip address spawn-fci listens on
--- ../lighttpd-1.4.11/configure.in 2006-03-04 16:32:38.000000000 +0200
-+++ lighttpd-1.4.12/configure.in 2006-07-15 22:43:22.000000000 +0300
++++ lighttpd-1.4.12/configure.in 2006-07-16 00:26:05.000000000 +0300
@@ -1,7 +1,7 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
$ECHO
--- ../lighttpd-1.4.11/cygwin/lighttpd.README 2006-03-07 14:22:19.000000000 +0200
-+++ lighttpd-1.4.12/cygwin/lighttpd.README 2006-07-11 22:08:04.000000000 +0300
++++ lighttpd-1.4.12/cygwin/lighttpd.README 2006-07-17 22:02:18.000000000 +0300
@@ -1,114 +1,114 @@
-lighttpd\r
-------------------------------------------\r
+Please address all questions to the Cygwin mailing list at <cygwin@cygwin.com>
+
--- ../lighttpd-1.4.11/cygwin/lighttpd.README.in 2005-08-11 01:26:59.000000000 +0300
-+++ lighttpd-1.4.12/cygwin/lighttpd.README.in 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/cygwin/lighttpd.README.in 2006-07-16 00:26:04.000000000 +0300
@@ -1,114 +1,114 @@
-lighttpd\r
-------------------------------------------\r
+Please address all questions to the Cygwin mailing list at <cygwin@cygwin.com>
+
--- ../lighttpd-1.4.11/doc/authentication.txt 2006-01-12 20:34:26.000000000 +0200
-+++ lighttpd-1.4.12/doc/authentication.txt 2006-07-11 22:07:54.000000000 +0300
++++ lighttpd-1.4.12/doc/authentication.txt 2006-07-16 00:26:05.000000000 +0300
@@ -7,8 +7,8 @@
----------------
:abstract:
The auth module provides ...
--- ../lighttpd-1.4.11/doc/compress.txt 2005-08-11 01:26:16.000000000 +0300
-+++ lighttpd-1.4.12/doc/compress.txt 2006-07-11 22:07:54.000000000 +0300
++++ lighttpd-1.4.12/doc/compress.txt 2006-07-16 00:26:05.000000000 +0300
@@ -22,12 +22,38 @@
===========
===========================
--- ../lighttpd-1.4.11/doc/configuration.txt 2006-03-09 02:10:40.000000000 +0200
-+++ lighttpd-1.4.12/doc/configuration.txt 2006-07-11 22:07:54.000000000 +0300
++++ lighttpd-1.4.12/doc/configuration.txt 2006-07-16 00:26:05.000000000 +0300
@@ -7,8 +7,8 @@
------------
+ for developers only
+ default: disabled
--- ../lighttpd-1.4.11/doc/fastcgi.txt 2006-02-16 17:03:52.000000000 +0200
-+++ lighttpd-1.4.12/doc/fastcgi.txt 2006-07-11 22:07:54.000000000 +0300
++++ lighttpd-1.4.12/doc/fastcgi.txt 2006-07-16 00:26:05.000000000 +0300
@@ -144,8 +144,8 @@
PHP can extract PATH_INFO from it (default: disabled)
:"disable-time": time to wait before a disabled backend is checked
If bin-path is set:
--- ../lighttpd-1.4.11/doc/lighttpd.conf 2006-03-04 14:41:12.000000000 +0200
-+++ lighttpd-1.4.12/doc/lighttpd.conf 2006-07-11 22:07:54.000000000 +0300
++++ lighttpd-1.4.12/doc/lighttpd.conf 2006-07-16 00:26:05.000000000 +0300
@@ -172,10 +172,11 @@
#dir-listing.activate = "enable"
### only root can use these options
#
--- ../lighttpd-1.4.11/doc/performance.txt 2006-02-02 13:01:08.000000000 +0200
-+++ lighttpd-1.4.12/doc/performance.txt 2006-07-11 22:07:54.000000000 +0300
++++ lighttpd-1.4.12/doc/performance.txt 2006-07-16 00:26:05.000000000 +0300
@@ -183,6 +183,8 @@
server.stat-cache-engine = "fam" # either fam, simple or disabled
Platform-Specific Notes
=======================
--- ../lighttpd-1.4.11/doc/secdownload.txt 2005-12-20 15:58:58.000000000 +0200
-+++ lighttpd-1.4.12/doc/secdownload.txt 2006-07-11 22:07:54.000000000 +0300
++++ lighttpd-1.4.12/doc/secdownload.txt 2006-07-16 00:26:05.000000000 +0300
@@ -118,7 +118,7 @@
$secret = "verysecret";
$uri_prefix = "/dl/";
# current timestamp
--- ../lighttpd-1.4.11/lighttpd.spec 2006-03-07 14:22:18.000000000 +0200
-+++ lighttpd-1.4.12/lighttpd.spec 2006-07-11 22:07:58.000000000 +0300
++++ lighttpd-1.4.12/lighttpd.spec 2006-07-17 22:02:18.000000000 +0300
@@ -1,6 +1,6 @@
Summary: A fast webserver with minimal memory-footprint (lighttpd)
Name: lighttpd
Source: http://jan.kneschke.de/projects/lighttpd/download/lighttpd-%version.tar.gz
Packager: Jan Kneschke <jan@kneschke.de>
--- ../lighttpd-1.4.11/openwrt/control 2006-03-07 14:22:19.000000000 +0200
-+++ lighttpd-1.4.12/openwrt/control 2006-07-11 22:08:05.000000000 +0300
++++ lighttpd-1.4.12/openwrt/control 2006-07-17 22:02:18.000000000 +0300
@@ -1,8 +1,8 @@
Package: lighttpd
-Version: 1.4.11
Priority: optional
Depends:
--- ../lighttpd-1.4.11/openwrt/lighttpd.mk 2006-03-07 14:22:19.000000000 +0200
-+++ lighttpd-1.4.12/openwrt/lighttpd.mk 2006-07-11 22:08:05.000000000 +0300
++++ lighttpd-1.4.12/openwrt/lighttpd.mk 2006-07-17 22:02:18.000000000 +0300
@@ -10,7 +10,7 @@
# For this example we'll use a fairly simple package that compiles easily
LIGHTTPD_DIR=$(BUILD_DIR)/$(LIGHTTPD)
LIGHTTPD_IPK=$(BUILD_DIR)/$(LIGHTTPD)_mipsel.ipk
--- ../lighttpd-1.4.11/src/Makefile.am 2006-03-07 14:20:20.000000000 +0200
-+++ lighttpd-1.4.12/src/Makefile.am 2006-07-15 23:38:00.000000000 +0300
++++ lighttpd-1.4.12/src/Makefile.am 2006-07-18 13:03:40.000000000 +0300
@@ -16,18 +16,24 @@
else
configparser.y: lemon
common_src=buffer.c log.c \
keyvalue.c chunk.c \
-@@ -46,7 +52,7 @@
+@@ -40,13 +46,13 @@
+ fdevent_solaris_devpoll.c fdevent_freebsd_kqueue.c \
+ data_config.c bitset.c \
+ inet_ntop_cache.c crc32.c \
+- connections-glue.c \
++ connections-glue.c iosocket.c \
+ configfile-glue.c \
+ http-header-glue.c \
network_write.c network_linux_sendfile.c \
network_freebsd_sendfile.c network_writev.c \
network_solaris_sendfilev.c network_openssl.c \
lib_LTLIBRARIES += mod_cgi.la
mod_cgi_la_SOURCES = mod_cgi.c
mod_cgi_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
-@@ -240,7 +251,8 @@
+@@ -158,6 +169,13 @@
+ mod_proxy_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
+ mod_proxy_la_LIBADD = $(common_libadd)
+
++lib_LTLIBRARIES += mod_proxy_core.la
++mod_proxy_core_la_SOURCES = mod_proxy_core.c mod_proxy_core_pool.c \
++ mod_proxy_core_backend.c mod_proxy_core_address.c mod_proxy_core_backlog.c
++mod_proxy_core_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
++mod_proxy_core_la_LIBADD = $(common_libadd)
++
++
+ lib_LTLIBRARIES += mod_ssi.la
+ mod_ssi_la_SOURCES = mod_ssi_exprparser.c mod_ssi_expr.c mod_ssi.c
+ mod_ssi_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
+@@ -240,7 +258,12 @@
mod_ssi.h mod_ssi_expr.h inet_ntop_cache.h \
configparser.h mod_ssi_exprparser.h \
sys-mmap.h sys-socket.h mod_cml.h mod_cml_funcs.h \
- splaytree.h proc_open.h
+ splaytree.h proc_open.h http_resp.h mod_sql_vhost_core.h \
-+ sys-files.h sys-process.h sys-strings.h http_resp_parser.h
++ sys-files.h sys-process.h sys-strings.h http_resp_parser.h \
++ iosocket.h array-static.h \
++ mod_proxy_core_address.h mod_proxy_core_backend.h \
++ mod_proxy_core_backlog.h mod_proxy_core.h \
++ mod_proxy_core_pool.h
DEFS= @DEFS@ -DLIBRARY_DIR="\"$(libdir)\""
-@@ -267,4 +279,4 @@
+@@ -267,4 +290,4 @@
#ajp_SOURCES = ajp.c
noinst_HEADERS = $(hdr)
-EXTRA_DIST = mod_skeleton.c configparser.y mod_ssi_exprparser.y lempar.c
+EXTRA_DIST = mod_skeleton.c configparser.y mod_ssi_exprparser.y lempar.c http_resp_parser.y
+--- ../lighttpd-1.4.11/src/array-static.h 1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/array-static.h 2006-07-18 13:03:40.000000000 +0300
+@@ -0,0 +1,33 @@
++#ifndef _ARRAY_STATIC_H_
++#define _ARRAY_STATIC_H_
++
++/* define a generic array of <type>
++ * */
++
++#define ARRAY_STATIC_DEF(name, type, extra) \
++typedef struct { \
++ type **ptr; \
++ size_t used; \
++ size_t size; \
++ extra\
++} name
++
++/* all append operations need a 'resize' for the +1 */
++
++#define ARRAY_STATIC_PREPARE_APPEND(a) \
++ if (a->size == 0) { \
++ a->size = 16; \
++ a->ptr = malloc(a->size * sizeof(*(a->ptr))); \
++ } else if (a->size == a->used) { \
++ a->size += 16; \
++ a->ptr = realloc(a->ptr, a->size * sizeof(*(a->ptr))); \
++ }
++
++#define FOREACH(array, element, func) \
++do { size_t _i; for (_i = 0; _i < array->used; _i++) { void *element = array->ptr[_i]; func; } } while(0);
++
++#define STRUCT_INIT(type, var) \
++ type *var;\
++ var = calloc(1, sizeof(*var))
++
++#endif
--- ../lighttpd-1.4.11/src/array.c 2005-11-18 13:58:32.000000000 +0200
-+++ lighttpd-1.4.12/src/array.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/array.c 2006-07-16 00:26:03.000000000 +0300
@@ -11,12 +11,12 @@
array *array_init(void) {
}
#endif
--- ../lighttpd-1.4.11/src/array.h 2005-09-23 21:24:18.000000000 +0300
-+++ lighttpd-1.4.12/src/array.h 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/array.h 2006-07-16 00:26:03.000000000 +0300
@@ -16,7 +16,7 @@
#define DATA_UNSET \
data_type_t type; \
int last_used_ndx; /* round robin */
} data_fastcgi;
--- ../lighttpd-1.4.11/src/base.h 2006-01-11 16:51:04.000000000 +0200
-+++ lighttpd-1.4.12/src/base.h 2006-07-15 22:43:21.000000000 +0300
++++ lighttpd-1.4.12/src/base.h 2006-07-18 13:03:40.000000000 +0300
@@ -2,7 +2,6 @@
#define _BASE_H_
#ifdef HAVE_FAM_H
int dir_version;
int dir_ndx;
-@@ -215,8 +198,8 @@
+@@ -215,20 +198,20 @@
} stat_cache_entry;
typedef struct {
buffer *dir_name; /* for building the dirname from the filename */
#ifdef HAVE_FAM_H
splay_tree *dirs; /* the nodes of the tree are fam_dir_entry */
-@@ -228,7 +211,7 @@
+
+ FAMConnection *fam;
+- int fam_fcce_ndx;
++ iosocket *sock;
+ #endif
+ } stat_cache;
typedef struct {
array *mimetypes;
} connection_state_t;
typedef enum { COND_RESULT_UNSET, COND_RESULT_FALSE, COND_RESULT_TRUE } cond_result_t;
-@@ -315,88 +299,88 @@
+@@ -315,91 +299,86 @@
typedef struct {
connection_state_t state;
* this is self-protection
*/
-
+- int fd; /* the FD for this connection */
+- int fde_ndx; /* index for the fdevent-handler */
+
- int fd; /* the FD for this connection */
- int fde_ndx; /* index for the fdevent-handler */
++ iosocket *sock;
int ndx; /* reverse mapping to server->connection[ndx] */
-
+
+
void *srv_socket; /* reference to the server-socket (typecast to server_socket) */
-
-+
- #ifdef USE_OPENSSL
- SSL *ssl;
- #endif
-@@ -439,39 +423,48 @@
+-#ifdef USE_OPENSSL
+- SSL *ssl;
+-#endif
+ } connection;
+
+ typedef struct {
+@@ -439,55 +418,63 @@
size_t size;
} buffer_plugin;
unsigned short port;
buffer *bindhost;
-
-+
- buffer *errorlog_file;
- unsigned short errorlog_use_syslog;
+- buffer *errorlog_file;
+- unsigned short errorlog_use_syslog;
-
+
unsigned short dont_daemonize;
+ STAT_CACHE_ENGINE_FAM
} stat_cache_engine;
unsigned short enable_cores;
++
++ buffer *errorlog_file;
++ unsigned short errorlog_use_syslog;
} server_config;
-@@ -480,14 +473,14 @@
+
+ typedef struct {
sock_addr addr;
- int fd;
- int fde_ndx;
+- int fd;
+- int fde_ndx;
-
++ iosocket *sock;
+
buffer *ssl_pemfile;
buffer *ssl_ca_file;
#ifdef USE_OPENSSL
SSL_CTX *ssl_ctx;
#endif
-@@ -495,37 +488,37 @@
+@@ -495,37 +482,32 @@
typedef struct {
server_socket **ptr;
typedef struct server {
server_socket_array srv_sockets;
-
-+
- /* the errorlog */
- int errorlog_fd;
- enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG } errorlog_mode;
- buffer *errorlog_buf;
+- /* the errorlog */
+- int errorlog_fd;
+- enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG } errorlog_mode;
+- buffer *errorlog_buf;
-
+
fdevents *ev, *ev_ins;
size_t max_conns;
/* buffers */
-@@ -533,13 +526,13 @@
+@@ -533,13 +515,13 @@
buffer *response_header;
buffer *response_range;
buffer *tmp_buf;
/* caches */
#ifdef HAVE_IPV6
inet_ntop_cache_type inet_ntop_cache[INET_NTOP_CACHE_MAX];
-@@ -547,31 +540,31 @@
+@@ -547,31 +529,31 @@
mtime_cache_type mtime_cache[FILE_CACHE_MAX];
array *split_vals;
stat_cache *stat_cache;
/**
-@@ -588,18 +581,20 @@
+@@ -588,18 +570,20 @@
* fastcgi.backend.<key>.disconnects = ...
*/
array *status;
- int (* network_backend_write)(struct server *srv, connection *con, int fd, chunkqueue *cq);
- int (* network_backend_read)(struct server *srv, connection *con, int fd, chunkqueue *cq);
-+ network_status_t (* network_backend_write)(struct server *srv, connection *con, int fd, chunkqueue *cq);
-+ network_status_t (* network_backend_read)(struct server *srv, connection *con, int fd, chunkqueue *cq);
++ network_status_t (* network_backend_write)(struct server *srv, connection *con, iosocket *sock, chunkqueue *cq);
++ network_status_t (* network_backend_read)(struct server *srv, connection *con, iosocket *sock, chunkqueue *cq);
#ifdef USE_OPENSSL
- int (* network_ssl_backend_write)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq);
- int (* network_ssl_backend_read)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq);
-+ network_status_t (* network_ssl_backend_write)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq);
-+ network_status_t (* network_ssl_backend_read)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq);
++ network_status_t (* network_ssl_backend_write)(struct server *srv, connection *con, iosocket *sock, chunkqueue *cq);
++ network_status_t (* network_ssl_backend_read)(struct server *srv, connection *con, iosocket *sock, chunkqueue *cq);
#endif
+#ifdef HAVE_PWD_H
} server;
+--- ../lighttpd-1.4.11/src/bitset.c 2005-08-22 01:54:12.000000000 +0300
++++ lighttpd-1.4.12/src/bitset.c 2006-07-18 13:03:40.000000000 +0300
+@@ -6,6 +6,7 @@
+
+ #include "bitset.h"
+ #include "buffer.h"
++#include "log.h"
+
+ #define BITSET_BITS \
+ ( CHAR_BIT * sizeof(size_t) )
--- ../lighttpd-1.4.11/src/buffer.c 2006-01-13 00:00:45.000000000 +0200
-+++ lighttpd-1.4.12/src/buffer.c 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/buffer.c 2006-07-18 13:03:40.000000000 +0300
@@ -12,20 +12,20 @@
* HISTORY: this function was pretty much optimized, but didn't handled
* alignment properly.
*/
-@@ -522,100 +591,100 @@
+@@ -517,105 +586,105 @@
+ if (a->used != b->used) return 0;
+ if (a->used == 0) return 1;
+
+- return (0 == strcmp(a->ptr, b->ptr));
++ return (0 == strncmp(a->ptr, b->ptr, a->used - 1));
+ }
int buffer_is_equal_string(buffer *a, const char *s, size_t b_len) {
buffer b;
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 70 - 7F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 - 8F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 90 - 9F */
-@@ -734,13 +803,13 @@
+@@ -734,13 +803,12 @@
unsigned char *ds, *d;
size_t d_len, ndx;
const char *map = NULL;
+
if (!s || !b) return -1;
-
-+
- if (b->ptr[b->used - 1] != '\0') {
- SEGFAULT();
- }
+- if (b->ptr[b->used - 1] != '\0') {
+- SEGFAULT();
+- }
-
++ if (b->used == 0) return -1;
++
++ if (b->ptr[b->used - 1] != '\0') return -1;
+
if (s_len == 0) return 0;
switch(encoding) {
-@@ -760,12 +829,12 @@
+@@ -760,12 +828,12 @@
map = encoded_chars_hex;
break;
case ENCODING_UNSET:
for (ds = (unsigned char *)s, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
if (map[*ds]) {
switch(encoding) {
-@@ -787,9 +856,9 @@
+@@ -787,9 +855,9 @@
d_len ++;
}
}
for (ds = (unsigned char *)s, d = (unsigned char *)b->ptr + b->used - 1, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
if (map[*ds]) {
switch(encoding) {
-@@ -820,16 +889,16 @@
+@@ -820,16 +888,16 @@
}
}
* replaces non-printable characters with '_'
*/
-@@ -854,10 +923,10 @@
+@@ -854,10 +922,10 @@
low = hex2int(*(src + 2));
if (low != 0xFF) {
high = (high << 4) | low;
*dst = high;
src += 2;
}
-@@ -891,7 +960,7 @@
+@@ -891,7 +959,7 @@
* /abc/./xyz gets /abc/xyz
* /abc//xyz gets /abc/xyz
*
* the operation is performed in-place.
*/
-@@ -979,7 +1048,7 @@
+@@ -979,7 +1047,7 @@
int light_isxdigit(int c) {
if (light_isdigit(c)) return 1;
c |= 32;
return (c >= 'a' && c <= 'f');
}
-@@ -993,31 +1062,56 @@
+@@ -993,31 +1061,56 @@
return light_isdigit(c) || light_isalpha(c);
}
return 0;
}
--- ../lighttpd-1.4.11/src/buffer.h 2006-01-13 00:00:45.000000000 +0200
-+++ lighttpd-1.4.12/src/buffer.h 2006-07-11 22:07:52.000000000 +0300
-@@ -12,27 +12,44 @@
++++ lighttpd-1.4.12/src/buffer.h 2006-07-18 13:03:40.000000000 +0300
+@@ -12,27 +12,43 @@
typedef struct {
char *ptr;
size_t size;
} buffer;
-+
+typedef void (*buffer_ptr_free_t)(void *p);
+
+typedef struct {
buffer_array* buffer_array_init(void);
void buffer_array_free(buffer_array *b);
void buffer_array_reset(buffer_array *b);
-@@ -43,7 +60,7 @@
+@@ -43,7 +59,7 @@
buffer* buffer_init_string(const char *str);
void buffer_free(buffer *b);
void buffer_reset(buffer *b);
int buffer_prepare_copy(buffer *b, size_t size);
int buffer_prepare_append(buffer *b, size_t size);
-@@ -85,9 +102,9 @@
+@@ -85,9 +101,9 @@
typedef enum {
ENCODING_UNSET,
ENCODING_MINIMAL_XML, /* minimal encoding for xml */
ENCODING_HEX /* encode string as hex */
} buffer_encoding_t;
-@@ -111,19 +128,21 @@
+@@ -111,20 +127,23 @@
int light_isalpha(int c);
int light_isalnum(int c);
+BUFFER_CTYPE_FUNC(alpha)
+BUFFER_CTYPE_FUNC(alnum)
+
++#define BUF_STR(x) x->ptr
#define BUFFER_APPEND_STRING_CONST(x, y) \
buffer_append_string_len(x, y, sizeof(y) - 1)
- if (x->used > 1 && x->ptr[x->used - 2] != '/') { BUFFER_APPEND_STRING_CONST(x, "/"); }
-
#define CONST_STR_LEN(x) x, x ? sizeof(x) - 1 : 0
- #define CONST_BUF_LEN(x) x->ptr, x->used ? x->used - 1 : 0
+-#define CONST_BUF_LEN(x) x->ptr, x->used ? x->used - 1 : 0
++#define CONST_BUF_LEN(x) BUF_STR(x), x->used ? x->used - 1 : 0
-
- #define SEGFAULT() do { fprintf(stderr, "%s.%d: aborted\n", __FILE__, __LINE__); abort(); } while(0)
+-#define SEGFAULT() do { fprintf(stderr, "%s.%d: aborted\n", __FILE__, __LINE__); abort(); } while(0)
++
#define UNUSED(x) ( (void)(x) )
+ #endif
--- ../lighttpd-1.4.11/src/chunk.c 2005-11-18 15:18:19.000000000 +0200
-+++ lighttpd-1.4.12/src/chunk.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/chunk.c 2006-07-18 13:03:40.000000000 +0300
@@ -1,16 +1,14 @@
/**
* the network chunk-API
return len;
}
-@@ -358,9 +359,9 @@
+@@ -355,12 +356,13 @@
+
+ switch (c->type) {
+ case MEM_CHUNK:
++ if (c->mem->used == 0) is_finished = 1;
if (c->offset == (off_t)c->mem->used - 1) is_finished = 1;
break;
case FILE_CHUNK:
break;
}
+@@ -383,3 +385,50 @@
+
+ return 0;
+ }
++
++void chunkqueue_print(chunkqueue *cq) {
++ chunk *c;
++
++ for (c = cq->first; c; c = c->next) {
++ fprintf(stderr, "(mem) %s", c->mem->ptr + c->offset);
++ }
++ fprintf(stderr, "\r\n");
++}
++
++
++/**
++ * remove the last chunk if it is empty
++ */
++
++void chunkqueue_remove_empty_last_chunk(chunkqueue *cq) {
++ chunk *c;
++ if (!cq->last) return;
++ if (!cq->first) return;
++
++ if (cq->first == cq->last) {
++ c = cq->first;
++
++ if (c->type != MEM_CHUNK) return;
++ if (c->mem->used == 0) {
++ chunk_free(c);
++ cq->first = cq->last = NULL;
++ }
++ return;
++ }
++
++ for (c = cq->first; c->next; c = c->next) {
++ if (c->type != MEM_CHUNK) continue;
++ if (c->mem->used != 0) continue;
++
++ if (c->next == cq->last) {
++ cq->last = c;
++
++ chunk_free(c->next);
++ c->next = NULL;
++
++ return;
++ }
++ }
++}
++
++
--- ../lighttpd-1.4.11/src/chunk.h 2005-11-01 09:32:21.000000000 +0200
-+++ lighttpd-1.4.12/src/chunk.h 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/chunk.h 2006-07-18 13:03:40.000000000 +0300
@@ -6,7 +6,7 @@
typedef struct chunk {
chunk *unused;
size_t unused_chunks;
+@@ -56,6 +56,7 @@
+ buffer * chunkqueue_get_append_buffer(chunkqueue *c);
+ buffer * chunkqueue_get_prepend_buffer(chunkqueue *c);
+ chunk * chunkqueue_get_append_tempfile(chunkqueue *cq);
++void chunkqueue_remove_empty_last_chunk(chunkqueue *cq);
+
+ int chunkqueue_remove_finished_chunks(chunkqueue *cq);
+
+@@ -66,4 +67,6 @@
+
+ int chunkqueue_is_empty(chunkqueue *c);
+
++void chunkqueue_print(chunkqueue *cq);
++
+ #endif
--- ../lighttpd-1.4.11/src/configfile-glue.c 2006-03-03 20:14:56.000000000 +0200
-+++ lighttpd-1.4.12/src/configfile-glue.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/configfile-glue.c 2006-07-16 00:26:03.000000000 +0300
@@ -1,4 +1,5 @@
#include <string.h>
+#include <ctype.h>
+}
+
--- ../lighttpd-1.4.11/src/configfile.c 2006-02-15 14:26:42.000000000 +0200
-+++ lighttpd-1.4.12/src/configfile.c 2006-07-15 22:43:21.000000000 +0300
++++ lighttpd-1.4.12/src/configfile.c 2006-07-18 13:03:40.000000000 +0300
@@ -2,7 +2,6 @@
#include <stdlib.h>
break;
case '+':
-@@ -637,96 +644,88 @@
+@@ -637,115 +644,107 @@
case '{':
t->offset++;
if (i && t->input[t->offset + i]) {
buffer_copy_string_len(token, t->input + t->offset, i);
-
+- if (strcmp(token->ptr, "include") == 0) {
+
- if (strcmp(token->ptr, "include") == 0) {
++ if (buffer_is_equal_string(token, CONST_STR_LEN("include"))) {
tid = TK_INCLUDE;
- } else if (strcmp(token->ptr, "include_shell") == 0) {
-@@ -738,14 +737,14 @@
+- } else if (strcmp(token->ptr, "include_shell") == 0) {
++ } else if (buffer_is_equal_string(token, CONST_STR_LEN("include_shell"))) {
+ tid = TK_INCLUDE_SHELL;
+- } else if (strcmp(token->ptr, "global") == 0) {
++ } else if (buffer_is_equal_string(token, CONST_STR_LEN("global"))) {
+ tid = TK_GLOBAL;
+- } else if (strcmp(token->ptr, "else") == 0) {
++ } else if (buffer_is_equal_string(token, CONST_STR_LEN("else"))) {
+ tid = TK_ELSE;
} else {
tid = TK_LKEY;
}
return 0;
}
--- ../lighttpd-1.4.11/src/configfile.h 2005-08-23 17:36:12.000000000 +0300
-+++ lighttpd-1.4.12/src/configfile.h 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/configfile.h 2006-07-16 00:26:03.000000000 +0300
@@ -9,7 +9,7 @@
server *srv;
int ok;
buffer *basedir;
} config_t;
--- ../lighttpd-1.4.11/src/configparser.c 2006-02-01 19:51:15.000000000 +0200
-+++ lighttpd-1.4.12/src/configparser.c 2006-07-11 22:08:02.000000000 +0300
++++ lighttpd-1.4.12/src/configparser.c 2006-07-17 22:02:23.000000000 +0300
@@ -24,52 +24,34 @@
dc->parent = ctx->current;
array_insert_unique(dc->parent->childs, (data_unset *)dc);
** This is what we do if the grammar does define ERROR:
**
--- ../lighttpd-1.4.11/src/configparser.y 2006-01-26 18:46:25.000000000 +0200
-+++ lighttpd-1.4.12/src/configparser.y 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/configparser.y 2006-07-16 00:26:04.000000000 +0300
@@ -21,52 +21,34 @@
dc->parent = ctx->current;
array_insert_unique(dc->parent->childs, (data_unset *)dc);
A = B;
B = NULL;
--- ../lighttpd-1.4.11/src/connections-glue.c 2005-09-12 10:04:23.000000000 +0300
-+++ lighttpd-1.4.12/src/connections-glue.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/connections-glue.c 2006-07-16 00:26:03.000000000 +0300
@@ -13,7 +13,7 @@
case CON_STATE_REQUEST_END: return "req-end";
case CON_STATE_RESPONSE_START: return "resp-start";
}
--- ../lighttpd-1.4.11/src/connections.c 2006-03-05 22:14:53.000000000 +0200
-+++ lighttpd-1.4.12/src/connections.c 2006-07-15 22:43:21.000000000 +0300
++++ lighttpd-1.4.12/src/connections.c 2006-07-18 13:03:40.000000000 +0300
@@ -2,7 +2,6 @@
#include <stdlib.h>
if (conns->size == 0) {
conns->size = 128;
conns->ptr = NULL;
-@@ -54,21 +54,21 @@
+@@ -54,21 +54,14 @@
} else if (conns->size == conns->used) {
conns->size += 128;
conns->ptr = realloc(conns->ptr, sizeof(*conns->ptr) * conns->size);
connection_reset(srv, conns->ptr[conns->used]);
-#if 0
-+#if 0
- fprintf(stderr, "%s.%d: add: ", __FILE__, __LINE__);
- for (i = 0; i < conns->used + 1; i++) {
- fprintf(stderr, "%d ", conns->ptr[i]->fd);
- }
- fprintf(stderr, "\n");
+- fprintf(stderr, "%s.%d: add: ", __FILE__, __LINE__);
+- for (i = 0; i < conns->used + 1; i++) {
+- fprintf(stderr, "%d ", conns->ptr[i]->fd);
+- }
+- fprintf(stderr, "\n");
-#endif
-
-+#endif
+
conns->ptr[conns->used]->ndx = conns->used;
return conns->ptr[conns->used++];
}
-@@ -77,26 +77,26 @@
+@@ -77,263 +70,134 @@
size_t i;
connections *conns = srv->conns;
connection *temp;
-
+
con->ndx = -1;
- #if 0
- fprintf(stderr, "%s.%d: del: (%d)", __FILE__, __LINE__, conns->used);
-@@ -104,25 +104,23 @@
- fprintf(stderr, "%d ", conns->ptr[i]->fd);
- }
- fprintf(stderr, "\n");
+-#if 0
+- fprintf(stderr, "%s.%d: del: (%d)", __FILE__, __LINE__, conns->used);
+- for (i = 0; i < conns->used; i++) {
+- fprintf(stderr, "%d ", conns->ptr[i]->fd);
+- }
+- fprintf(stderr, "\n");
-#endif
-+#endif
++
return 0;
}
-#ifdef USE_OPENSSL
+
if (srv_sock->is_ssl) {
- if (con->ssl) SSL_free(con->ssl);
- con->ssl = NULL;
+- if (con->ssl) SSL_free(con->ssl);
+- con->ssl = NULL;
++ if (con->sock->ssl) SSL_free(con->sock->ssl);
++ con->sock->ssl = NULL;
}
#endif
-
-+
- fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd);
- fdevent_unregister(srv->ev, con->fd);
+- fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd);
+- fdevent_unregister(srv->ev, con->fd);
-#ifdef __WIN32
-+#ifdef _WIN32
- if (closesocket(con->fd)) {
+- if (closesocket(con->fd)) {
+- log_error_write(srv, __FILE__, __LINE__, "sds",
+- "(warning) close:", con->fd, strerror(errno));
+- }
+-#else
+- if (close(con->fd)) {
++
++ fdevent_event_del(srv->ev, con->sock);
++ fdevent_unregister(srv->ev, con->sock);
++
++ if (closesocket(con->sock->fd)) {
log_error_write(srv, __FILE__, __LINE__, "sds",
- "(warning) close:", con->fd, strerror(errno));
-@@ -133,207 +131,96 @@
- "(warning) close:", con->fd, strerror(errno));
+- "(warning) close:", con->fd, strerror(errno));
++ "(warning) close:", con->sock->fd, strerror(errno));
}
- #endif
+-#endif
-
+
srv->cur_fds--;
- #if 0
- log_error_write(srv, __FILE__, __LINE__, "sd",
- "closed()", con->fd);
- #endif
+-#if 0
+- log_error_write(srv, __FILE__, __LINE__, "sd",
+- "closed()", con->fd);
+-#endif
-
+
connection_del(srv, con);
- b = chunkqueue_get_append_buffer(con->read_queue);
- buffer_prepare_copy(b, 4096);
-+static network_status_t connection_handle_read(server *srv, connection *con) {
-+ off_t oldlen, newlen;
-
+-
-#ifdef USE_OPENSSL
- if (srv_sock->is_ssl) {
- len = SSL_read(con->ssl, b->ptr, b->size - 1);
- return -1;
- }
- buffer_prepare_copy(b, toread);
-+ oldlen = chunkqueue_length(con->read_queue);
++static network_status_t connection_handle_read(server *srv, connection *con) {
++ off_t oldlen, newlen;
- len = read(con->fd, b->ptr, b->size - 1);
- }
- return -1;
- }
- buffer_prepare_copy(b, toread);
--
++ oldlen = chunkqueue_length(con->read_queue);
+
- len = read(con->fd, b->ptr, b->size - 1);
-#endif
-
}
static int connection_handle_write_prepare(server *srv, connection *con) {
-@@ -343,6 +230,7 @@
+@@ -343,6 +207,7 @@
case HTTP_METHOD_GET:
case HTTP_METHOD_POST:
case HTTP_METHOD_HEAD:
case HTTP_METHOD_PUT:
case HTTP_METHOD_MKCOL:
case HTTP_METHOD_DELETE:
-@@ -350,12 +238,14 @@
+@@ -350,12 +215,14 @@
case HTTP_METHOD_MOVE:
case HTTP_METHOD_PROPFIND:
case HTTP_METHOD_PROPPATCH:
* */
if (con->uri.path->used &&
con->uri.path->ptr[0] != '*') {
-@@ -381,55 +271,58 @@
+@@ -381,55 +248,60 @@
break;
}
}
case 423:
case 500:
case 501:
++ case 502:
case 503:
- case 505:
++ case 504:
+ case 505:
+ case 509:
if (con->mode != DIRECT) break;
"<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
-@@ -439,7 +332,7 @@
+@@ -439,7 +311,7 @@
buffer_append_long(b, con->http_status);
buffer_append_string(b, " - ");
buffer_append_string(b, get_http_status_name(con->http_status));
buffer_append_string(b,
"</title>\n"
" </head>\n"
-@@ -448,12 +341,12 @@
+@@ -448,12 +320,12 @@
buffer_append_long(b, con->http_status);
buffer_append_string(b, " - ");
buffer_append_string(b, get_http_status_name(con->http_status));
response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
}
/* fall through */
-@@ -463,10 +356,10 @@
+@@ -463,10 +335,10 @@
case 301:
case 302:
break;
break;
case 205: /* class: header only */
case 304:
-@@ -474,19 +367,19 @@
+@@ -474,19 +346,19 @@
/* disable chunked encoding again as we have no body */
con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED;
chunkqueue_reset(con->write_queue);
response_header_overwrite(srv, con, CONST_STR_LEN("Content-Length"), CONST_BUF_LEN(srv->tmp_buf));
}
} else {
-@@ -495,74 +388,77 @@
+@@ -495,77 +367,79 @@
((con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0)) {
con->keep_alive = 0;
}
- case -1: /* error on our side */
+ case NETWORK_STATUS_FATAL_ERROR: /* error on our side */
log_error_write(srv, __FILE__, __LINE__, "sd",
- "connection closed: write failed on fd", con->fd);
+- "connection closed: write failed on fd", con->fd);
++ "connection closed: write failed on fd", con->sock->fd);
connection_set_state(srv, con, CON_STATE_ERROR);
joblist_append(srv, con);
break;
con = calloc(1, sizeof(*con));
-
+- con->fd = 0;
+
- con->fd = 0;
++ con->sock = iosocket_init();
con->ndx = -1;
- con->fde_ndx = -1;
-@@ -573,32 +469,32 @@
+- con->fde_ndx = -1;
+ con->bytes_written = 0;
+ con->bytes_read = 0;
+ con->bytes_header = 0;
+@@ -573,32 +447,32 @@
#define CLEAN(x) \
con->x = buffer_init();
#undef CLEAN
con->write_queue = chunkqueue_init();
con->read_queue = chunkqueue_init();
-@@ -608,26 +504,26 @@
+@@ -608,26 +482,27 @@
con->request.headers = array_init();
con->response.headers = array_init();
con->environment = array_init();
+
connection_reset(srv, con);
-
++ iosocket_free(con->sock);
+
chunkqueue_free(con->write_queue);
chunkqueue_free(con->read_queue);
chunkqueue_free(con->request_content_queue);
-@@ -637,27 +533,27 @@
+@@ -637,27 +512,27 @@
#define CLEAN(x) \
buffer_free(con->x);
CLEAN(authed_user);
CLEAN(server_name);
CLEAN(error_handler);
-@@ -665,97 +561,97 @@
+@@ -665,97 +540,97 @@
#undef CLEAN
free(con->plugin_ctx);
free(con->cond_cache);
for (i = 0; i < srv->plugins.used; i++) {
plugin *p = ((plugin **)(srv->plugins.ptr))[i];
plugin_data *pd = p->data;
-@@ -768,7 +664,7 @@
+@@ -768,7 +643,7 @@
con->plugin_ctx[pd->id] = NULL;
}
#if COND_RESULT_UNSET
for (i = srv->config_context->used - 1; i >= 0; i --) {
con->cond_cache[i].result = COND_RESULT_UNSET;
-@@ -777,56 +673,56 @@
+@@ -777,56 +652,56 @@
#else
memset(con->cond_cache, 0, sizeof(cond_cache_t) * srv->config_context->used);
#endif
return NULL;
}
/**
-@@ -840,22 +736,25 @@
+@@ -840,22 +715,25 @@
chunk *c;
chunkqueue *cq = con->read_queue;
chunkqueue *dst_cq = con->request_content_queue;
}
default:
break;
-@@ -891,14 +790,14 @@
+@@ -891,14 +769,14 @@
/* the last node was empty */
if (c->next == NULL) {
cq->last = c;
/* nothing to handle */
if (cq->first == NULL) return 0;
-@@ -906,25 +805,26 @@
+@@ -906,25 +784,26 @@
case CON_STATE_READ:
/* prepare con->request.request */
c = cq->first;
} else {
/* not found, copy everything */
buffer_copy_string_len(con->request.request, c->mem->ptr + c->offset, c->mem->used - c->offset - 1);
-@@ -932,14 +832,14 @@
+@@ -932,14 +811,14 @@
}
} else {
/* have to take care of overlapping header terminators */
if (con->request.request->used - 1 > 3 &&
c->mem->used > 1 &&
s[l-2] == '\r' &&
-@@ -948,7 +848,7 @@
+@@ -948,7 +827,7 @@
c->mem->ptr[0] == '\n') {
buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, 1);
c->offset += 1;
h_term = con->request.request->ptr;
} else if (con->request.request->used - 1 > 2 &&
c->mem->used > 2 &&
-@@ -958,7 +858,7 @@
+@@ -958,7 +837,7 @@
c->mem->ptr[1] == '\n') {
buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, 2);
c->offset += 2;
h_term = con->request.request->ptr;
} else if (con->request.request->used - 1 > 1 &&
c->mem->used > 3 &&
-@@ -968,17 +868,17 @@
+@@ -968,17 +847,17 @@
c->mem->ptr[2] == '\n') {
buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, 3);
c->offset += 3;
/* the buffer has been read up to the terminator */
c->offset += h_term - b.ptr + 4;
} else {
-@@ -999,16 +899,16 @@
+@@ -999,16 +878,16 @@
connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
}
break;
toRead = weHave > weWant ? weWant : weHave;
/* the new way, copy everything into a chunkqueue whcih might use tempfiles */
-@@ -1017,13 +917,13 @@
+@@ -1017,13 +896,13 @@
/* copy everything to max 1Mb sized tempfiles */
/*
* */
if (dst_cq->last &&
-@@ -1056,14 +956,14 @@
+@@ -1056,14 +935,14 @@
/* we have a chunk, let's write to it */
if (dst_c->file.fd == -1) {
dst_c->file.name, strerror(errno));
con->http_status = 413; /* Request-Entity too large */
-@@ -1074,15 +974,15 @@
+@@ -1074,15 +953,15 @@
}
if (toRead != write(dst_c->file.fd, c->mem->ptr + c->offset, toRead)) {
close(dst_c->file.fd);
dst_c->file.fd = -1;
-@@ -1090,7 +990,7 @@
+@@ -1090,7 +969,7 @@
}
dst_c->file.length += toRead;
if (dst_cq->bytes_in + toRead == (off_t)con->request.content_length) {
/* we read everything, close the chunk */
close(dst_c->file.fd);
-@@ -1102,7 +1002,7 @@
+@@ -1102,7 +981,7 @@
b = chunkqueue_get_append_buffer(dst_cq);
buffer_copy_string_len(b, c->mem->ptr + c->offset, toRead);
}
c->offset += toRead;
dst_cq->bytes_in += toRead;
}
-@@ -1111,7 +1011,7 @@
+@@ -1111,7 +990,7 @@
if (dst_cq->bytes_in == (off_t)con->request.content_length) {
connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
}
break;
}
-@@ -1123,9 +1023,9 @@
+@@ -1123,100 +1002,104 @@
handler_t connection_handle_fdevent(void *s, void *context, int revents) {
server *srv = (server *)s;
connection *con = context;
+
if (revents & FDEVENT_IN) {
con->is_readable = 1;
- #if 0
-@@ -1136,19 +1036,19 @@
+-#if 0
+- log_error_write(srv, __FILE__, __LINE__, "sd", "read-wait - done", con->fd);
+-#endif
+ }
+ if (revents & FDEVENT_OUT) {
con->is_writable = 1;
/* we don't need the event twice */
}
*/
#ifdef USE_LINUX_SIGIO
if (srv->ev->in_sigio == 1) {
-@@ -1160,32 +1060,39 @@
+ log_error_write(srv, __FILE__, __LINE__, "sd",
+- "connection closed: poll() -> HUP", con->fd);
++ "connection closed: poll() -> HUP", con->sock->fd);
+ } else {
+ connection_set_state(srv, con, CON_STATE_ERROR);
+ }
#else
connection_set_state(srv, con, CON_STATE_ERROR);
#endif
} else if (revents & FDEVENT_ERR) {
#ifndef USE_LINUX_SIGIO
log_error_write(srv, __FILE__, __LINE__, "sd",
- "connection closed: poll() -> ERR", con->fd);
+- "connection closed: poll() -> ERR", con->fd);
-#endif
++ "connection closed: poll() -> ERR", con->sock->fd);
+#endif
connection_set_state(srv, con, CON_STATE_ERROR);
} else {
-
+
log_error_write(srv, __FILE__, __LINE__, "ds",
- con->fd,
+- con->fd,
++ con->sock->fd,
"handle write failed.");
-@@ -1193,30 +1100,30 @@
+ } else if (con->state == CON_STATE_WRITE) {
con->write_request_ts = srv->cur_ts;
}
}
/* flush the read buffers */
int b;
-
+- if (ioctl(con->fd, FIONREAD, &b)) {
+
- if (ioctl(con->fd, FIONREAD, &b)) {
++ if (ioctl(con->sock->fd, FIONREAD, &b)) {
log_error_write(srv, __FILE__, __LINE__, "ss",
"ioctl() failed", strerror(errno));
}
if (b > 0) {
char buf[1024];
log_error_write(srv, __FILE__, __LINE__, "sdd",
- "CLOSE-read()", con->fd, b);
+- "CLOSE-read()", con->fd, b);
-
++ "CLOSE-read()", con->sock->fd, b);
+
/* */
- read(con->fd, buf, sizeof(buf));
+- read(con->fd, buf, sizeof(buf));
++ read(con->sock->fd, buf, sizeof(buf));
} else {
/* nothing to read */
-
return HANDLER_FINISHED;
}
-@@ -1229,63 +1136,68 @@
+@@ -1229,63 +1112,68 @@
sock_addr cnt_addr;
socklen_t cnt_len;
/* accept it and register the fd */
+
cnt_len = sizeof(cnt_addr);
- if (-1 == (cnt = accept(srv_socket->fd, (struct sockaddr *) &cnt_addr, &cnt_len))) {
+- if (-1 == (cnt = accept(srv_socket->fd, (struct sockaddr *) &cnt_addr, &cnt_len))) {
++ if (-1 == (cnt = accept(srv_socket->sock->fd, (struct sockaddr *) &cnt_addr, &cnt_len))) {
+#ifdef _WIN32
+ errno = WSAGetLastError();
+#endif
+ (errno != EWOULDBLOCK) &&
(errno != EINTR)) {
- log_error_write(srv, __FILE__, __LINE__, "ssd", "accept failed:", strerror(errno), errno);
-+ log_error_write(srv, __FILE__, __LINE__, "ssd", "accept failed:", strerror(errno), srv_socket->fd);
++ log_error_write(srv, __FILE__, __LINE__, "ssd", "accept failed:", strerror(errno), srv_socket->sock->fd);
}
return NULL;
} else {
+
con = connections_get_new_connection(srv);
-
- con->fd = cnt;
- con->fde_ndx = -1;
+- con->fd = cnt;
+- con->fde_ndx = -1;
-#if 0
++ con->sock->fd = cnt;
++ con->sock->fde_ndx = -1;
+#if 0
gettimeofday(&(con->start_tv), NULL);
-#endif
-+#endif
- fdevent_register(srv->ev, con->fd, connection_handle_fdevent, con);
+- fdevent_register(srv->ev, con->fd, connection_handle_fdevent, con);
-
++#endif
++ fdevent_register(srv->ev, con->sock, connection_handle_fdevent, con);
+
connection_set_state(srv, con, CON_STATE_REQUEST_START);
-
buffer_copy_string(con->dst_addr_buf, inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
con->srv_socket = srv_socket;
-
+- if (-1 == (fdevent_fcntl_set(srv->ev, con->fd))) {
+
- if (-1 == (fdevent_fcntl_set(srv->ev, con->fd))) {
++ if (-1 == (fdevent_fcntl_set(srv->ev, con->sock))) {
log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno));
+ connection_close(srv, con);
return NULL;
#ifdef USE_OPENSSL
/* connect FD to SSL */
if (srv_socket->is_ssl) {
- if (NULL == (con->ssl = SSL_new(srv_socket->ssl_ctx))) {
+- if (NULL == (con->ssl = SSL_new(srv_socket->ssl_ctx))) {
- log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
++ if (NULL == (con->sock->ssl = SSL_new(srv_socket->ssl_ctx))) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
ERR_error_string(ERR_get_error(), NULL));
-
return NULL;
}
-
+- SSL_set_accept_state(con->ssl);
+
- SSL_set_accept_state(con->ssl);
++ SSL_set_accept_state(con->sock->ssl);
con->conf.is_ssl=1;
-
-+
- if (1 != (SSL_set_fd(con->ssl, cnt))) {
+- if (1 != (SSL_set_fd(con->ssl, cnt))) {
- log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
++
++ if (1 != (SSL_set_fd(con->sock->ssl, cnt))) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
ERR_error_string(ERR_get_error(), NULL));
+ connection_close(srv, con);
return NULL;
}
}
-@@ -1300,10 +1212,10 @@
+@@ -1300,102 +1188,102 @@
#ifdef USE_OPENSSL
server_socket *srv_sock = con->srv_socket;
#endif
if (srv->srvconf.log_state_handling) {
- log_error_write(srv, __FILE__, __LINE__, "sds",
- "state at start",
+- con->fd,
+ log_error_write(srv, __FILE__, __LINE__, "sds",
+ "state at start",
- con->fd,
++ con->sock->fd,
connection_get_state(con->state));
}
-@@ -1311,91 +1223,91 @@
+
while (done == 0) {
size_t ostate = con->state;
int b;
case CON_STATE_REQUEST_START: /* transient */
if (srv->srvconf.log_state_handling) {
- log_error_write(srv, __FILE__, __LINE__, "sds",
+- "state for fd", con->fd, connection_get_state(con->state));
+ log_error_write(srv, __FILE__, __LINE__, "sds",
- "state for fd", con->fd, connection_get_state(con->state));
++ "state for fd", con->sock->fd, connection_get_state(con->state));
}
-
+
case CON_STATE_REQUEST_END: /* transient */
if (srv->srvconf.log_state_handling) {
- log_error_write(srv, __FILE__, __LINE__, "sds",
+- "state for fd", con->fd, connection_get_state(con->state));
+ log_error_write(srv, __FILE__, __LINE__, "sds",
- "state for fd", con->fd, connection_get_state(con->state));
++ "state for fd", con->sock->fd, connection_get_state(con->state));
}
-
+
+
if (srv->srvconf.log_state_handling) {
- log_error_write(srv, __FILE__, __LINE__, "sds",
+- "state for fd", con->fd, connection_get_state(con->state));
+ log_error_write(srv, __FILE__, __LINE__, "sds",
- "state for fd", con->fd, connection_get_state(con->state));
++ "state for fd", con->sock->fd, connection_get_state(con->state));
}
-
+
"If this is a rails app: check your production.log");
con->http_status = con->error_handler_saved_status;
}
-@@ -1403,26 +1315,26 @@
+@@ -1403,73 +1291,73 @@
/* error-handler is back and has generated content */
/* if Status: was set, take it otherwise use 200 */
}
break;
case HANDLER_ERROR:
/* something went wrong */
-@@ -1432,44 +1344,44 @@
- log_error_write(srv, __FILE__, __LINE__, "sdd", "unknown ret-value: ", con->fd, r);
+ connection_set_state(srv, con, CON_STATE_ERROR);
+ break;
+ default:
+- log_error_write(srv, __FILE__, __LINE__, "sdd", "unknown ret-value: ", con->fd, r);
++ log_error_write(srv, __FILE__, __LINE__, "sdd", "unknown ret-value: ", con->sock->fd, r);
break;
}
-
+
if (srv->srvconf.log_state_handling) {
- log_error_write(srv, __FILE__, __LINE__, "sds",
+- "state for fd", con->fd, connection_get_state(con->state));
+ log_error_write(srv, __FILE__, __LINE__, "sds",
- "state for fd", con->fd, connection_get_state(con->state));
++ "state for fd", con->sock->fd, connection_get_state(con->state));
}
-
+
+
if (srv->srvconf.log_state_handling) {
- log_error_write(srv, __FILE__, __LINE__, "sds",
+- "state for fd", con->fd, connection_get_state(con->state));
+ log_error_write(srv, __FILE__, __LINE__, "sds",
- "state for fd", con->fd, connection_get_state(con->state));
++ "state for fd", con->sock->fd, connection_get_state(con->state));
}
-
+
con->request_start = srv->cur_ts;
con->read_idle_ts = srv->cur_ts;
#endif
-@@ -1482,7 +1394,7 @@
+@@ -1482,103 +1370,103 @@
log_error_write(srv, __FILE__, __LINE__, "sd", "unhandling return value", r);
break;
}
+
#ifdef USE_OPENSSL
if (srv_sock->is_ssl) {
- switch (SSL_shutdown(con->ssl)) {
-@@ -1490,44 +1402,44 @@
+- switch (SSL_shutdown(con->ssl)) {
++ switch (SSL_shutdown(con->sock->ssl)) {
+ case 1:
/* done */
break;
case 0:
case CON_STATE_CONNECT:
if (srv->srvconf.log_state_handling) {
- log_error_write(srv, __FILE__, __LINE__, "sds",
+- "state for fd", con->fd, connection_get_state(con->state));
+ log_error_write(srv, __FILE__, __LINE__, "sds",
- "state for fd", con->fd, connection_get_state(con->state));
++ "state for fd", con->sock->fd, connection_get_state(con->state));
}
-
+
case CON_STATE_CLOSE:
if (srv->srvconf.log_state_handling) {
- log_error_write(srv, __FILE__, __LINE__, "sds",
+- "state for fd", con->fd, connection_get_state(con->state));
+ log_error_write(srv, __FILE__, __LINE__, "sds",
- "state for fd", con->fd, connection_get_state(con->state));
++ "state for fd", con->sock->fd, connection_get_state(con->state));
}
-
+
if (con->keep_alive) {
- if (ioctl(con->fd, FIONREAD, &b)) {
+- if (ioctl(con->fd, FIONREAD, &b)) {
++ if (ioctl(con->sock->fd, FIONREAD, &b)) {
log_error_write(srv, __FILE__, __LINE__, "ss",
-@@ -1537,43 +1449,43 @@
+ "ioctl() failed", strerror(errno));
+ }
+ if (b > 0) {
char buf[1024];
log_error_write(srv, __FILE__, __LINE__, "sdd",
- "CLOSE-read()", con->fd, b);
+- "CLOSE-read()", con->fd, b);
-
++ "CLOSE-read()", con->sock->fd, b);
+
/* */
- read(con->fd, buf, sizeof(buf));
+- read(con->fd, buf, sizeof(buf));
++ read(con->sock->fd, buf, sizeof(buf));
} else {
/* nothing to read */
-
+
if (srv->srvconf.log_state_handling) {
- log_error_write(srv, __FILE__, __LINE__, "sd",
+- "connection closed for fd", con->fd);
+ log_error_write(srv, __FILE__, __LINE__, "sd",
- "connection closed for fd", con->fd);
++ "connection closed for fd", con->sock->fd);
}
}
-
case CON_STATE_READ:
if (srv->srvconf.log_state_handling) {
- log_error_write(srv, __FILE__, __LINE__, "sds",
+- "state for fd", con->fd, connection_get_state(con->state));
+ log_error_write(srv, __FILE__, __LINE__, "sds",
- "state for fd", con->fd, connection_get_state(con->state));
++ "state for fd", con->sock->fd, connection_get_state(con->state));
}
-
+
case CON_STATE_WRITE:
if (srv->srvconf.log_state_handling) {
- log_error_write(srv, __FILE__, __LINE__, "sds",
+- "state for fd", con->fd, connection_get_state(con->state));
+ log_error_write(srv, __FILE__, __LINE__, "sds",
- "state for fd", con->fd, connection_get_state(con->state));
++ "state for fd", con->sock->fd, connection_get_state(con->state));
}
-
+
/* only try to write if we have something in the queue */
if (!chunkqueue_is_empty(con->write_queue)) {
#if 0
-@@ -1593,10 +1505,10 @@
+ log_error_write(srv, __FILE__, __LINE__, "dsd",
+- con->fd,
++ con->sock->fd,
+ "packets to write:",
+ con->write_queue->used);
+ #endif
+@@ -1586,17 +1474,17 @@
+ if (!chunkqueue_is_empty(con->write_queue) && con->is_writable) {
+ if (-1 == connection_handle_write(srv, con)) {
+ log_error_write(srv, __FILE__, __LINE__, "ds",
+- con->fd,
++ con->sock->fd,
+ "handle write failed.");
+ connection_set_state(srv, con, CON_STATE_ERROR);
+ } else if (con->state == CON_STATE_WRITE) {
con->write_request_ts = srv->cur_ts;
}
}
/* even if the connection was drop we still have to write it to the access log */
if (con->http_status) {
plugins_call_handle_request_done(srv, con);
-@@ -1612,19 +1524,19 @@
- SSL_shutdown(con->ssl);
+@@ -1604,28 +1492,28 @@
+ #ifdef USE_OPENSSL
+ if (srv_sock->is_ssl) {
+ int ret;
+- switch ((ret = SSL_shutdown(con->ssl))) {
++ switch ((ret = SSL_shutdown(con->sock->ssl))) {
+ case 1:
+ /* ok */
+ break;
+ case 0:
+- SSL_shutdown(con->ssl);
++ SSL_shutdown(con->sock->ssl);
break;
default:
- log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
- SSL_get_error(con->ssl, ret),
+ log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
-+ SSL_get_error(con->ssl, ret),
++ SSL_get_error(con->sock->ssl, ret),
ERR_error_string(ERR_get_error(), NULL));
return -1;
}
#if 0
- log_error_write(srv, __FILE__, __LINE__, "sd",
- "emergency exit: direct",
+- con->fd);
+ log_error_write(srv, __FILE__, __LINE__, "sd",
+ "emergency exit: direct",
- con->fd);
++ con->sock->fd);
#endif
break;
-@@ -1639,35 +1551,35 @@
+ default:
+@@ -1639,35 +1527,35 @@
}
break;
}
+
/* close the connection */
if ((con->keep_alive == 1) &&
- (0 == shutdown(con->fd, SHUT_WR))) {
+- (0 == shutdown(con->fd, SHUT_WR))) {
++ (0 == shutdown(con->sock->fd, SHUT_WR))) {
con->close_timeout_ts = srv->cur_ts;
connection_set_state(srv, con, CON_STATE_CLOSE);
-
+
if (srv->srvconf.log_state_handling) {
- log_error_write(srv, __FILE__, __LINE__, "sd",
+- "shutdown for fd", con->fd);
+ log_error_write(srv, __FILE__, __LINE__, "sd",
- "shutdown for fd", con->fd);
++ "shutdown for fd", con->sock->fd);
}
} else {
connection_close(srv, con);
break;
default:
- log_error_write(srv, __FILE__, __LINE__, "sdd",
-+ log_error_write(srv, __FILE__, __LINE__, "sdd",
- "unknown state:", con->fd, con->state);
+- "unknown state:", con->fd, con->state);
-
++ log_error_write(srv, __FILE__, __LINE__, "sdd",
++ "unknown state:", con->sock->fd, con->state);
+
break;
}
if (done == -1) {
done = 0;
} else if (ostate == con->state) {
-@@ -1676,12 +1588,12 @@
+@@ -1676,33 +1564,33 @@
}
if (srv->srvconf.log_state_handling) {
- log_error_write(srv, __FILE__, __LINE__, "sds",
- "state at exit:",
+- con->fd,
+ log_error_write(srv, __FILE__, __LINE__, "sds",
+ "state at exit:",
- con->fd,
++ con->sock->fd,
connection_get_state(con->state));
}
-
switch(con->state) {
case CON_STATE_READ_POST:
case CON_STATE_READ:
-@@ -1689,11 +1601,11 @@
- fdevent_event_add(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_IN);
+ case CON_STATE_CLOSE:
+- fdevent_event_add(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_IN);
++ fdevent_event_add(srv->ev, con->sock, FDEVENT_IN);
break;
case CON_STATE_WRITE:
- /* request write-fdevent only if we really need it
+ if (!chunkqueue_is_empty(con->write_queue) &&
(con->is_writable == 0) &&
(con->traffic_limit_reached == 0)) {
- fdevent_event_add(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_OUT);
+- fdevent_event_add(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_OUT);
++ fdevent_event_add(srv->ev, con->sock, FDEVENT_OUT);
+ } else {
+- fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd);
++ fdevent_event_del(srv->ev, con->sock);
+ }
+ break;
+ default:
+- fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd);
++ fdevent_event_del(srv->ev, con->sock);
+ break;
+ }
+
--- ../lighttpd-1.4.11/src/crc32.h 2005-09-30 20:18:59.000000000 +0300
-+++ lighttpd-1.4.12/src/crc32.h 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/crc32.h 2006-07-16 00:26:04.000000000 +0300
@@ -6,6 +6,7 @@
#endif
#endif
--- ../lighttpd-1.4.11/src/data_array.c 2005-08-23 17:36:12.000000000 +0300
-+++ lighttpd-1.4.12/src/data_array.c 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/data_array.c 2006-07-16 00:26:04.000000000 +0300
@@ -17,16 +17,16 @@
static void data_array_free(data_unset *d) {
return ds;
}
--- ../lighttpd-1.4.11/src/data_config.c 2005-08-17 12:53:19.000000000 +0300
-+++ lighttpd-1.4.12/src/data_config.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/data_config.c 2006-07-16 00:26:03.000000000 +0300
@@ -17,26 +17,26 @@
static void data_config_free(data_unset *d) {
return ds;
}
--- ../lighttpd-1.4.11/src/data_count.c 2005-08-23 17:36:12.000000000 +0300
-+++ lighttpd-1.4.12/src/data_count.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/data_count.c 2006-07-16 00:26:03.000000000 +0300
@@ -16,53 +16,53 @@
static void data_count_free(data_unset *d) {
return ds;
}
--- ../lighttpd-1.4.11/src/data_fastcgi.c 2005-08-23 17:36:12.000000000 +0300
-+++ lighttpd-1.4.12/src/data_fastcgi.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/data_fastcgi.c 2006-07-16 00:26:04.000000000 +0300
@@ -17,53 +17,53 @@
static void data_fastcgi_free(data_unset *d) {
return ds;
}
--- ../lighttpd-1.4.11/src/data_integer.c 2005-08-23 17:36:12.000000000 +0300
-+++ lighttpd-1.4.12/src/data_integer.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/data_integer.c 2006-07-16 00:26:03.000000000 +0300
@@ -16,15 +16,15 @@
static void data_integer_free(data_unset *d) {
return ds;
}
--- ../lighttpd-1.4.11/src/data_string.c 2005-08-23 17:36:12.000000000 +0300
-+++ lighttpd-1.4.12/src/data_string.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/data_string.c 2006-07-16 00:26:04.000000000 +0300
@@ -17,16 +17,16 @@
static void data_string_free(data_unset *d) {
return ds;
}
--- ../lighttpd-1.4.11/src/etag.c 2005-08-11 01:26:40.000000000 +0300
-+++ lighttpd-1.4.12/src/etag.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/etag.c 2006-07-18 13:03:40.000000000 +0300
+@@ -4,7 +4,7 @@
+ #include "etag.h"
+
+ int etag_is_equal(buffer *etag, const char *matches) {
+- if (0 == strcmp(etag->ptr, matches)) return 1;
++ if (buffer_is_equal_string(etag, matches, strlen(matches))) return 1;
+ return 0;
+ }
+
@@ -14,19 +14,19 @@
buffer_append_off_t(etag, st->st_size);
buffer_append_string_len(etag, CONST_STR_LEN("-"));
return 0;
}
--- ../lighttpd-1.4.11/src/etag.h 2005-08-11 01:26:40.000000000 +0300
-+++ lighttpd-1.4.12/src/etag.h 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/etag.h 2006-07-16 00:26:03.000000000 +0300
@@ -3,13 +3,12 @@
#include <sys/types.h>
#endif
--- ../lighttpd-1.4.11/src/fastcgi.h 2005-08-11 01:26:40.000000000 +0300
-+++ lighttpd-1.4.12/src/fastcgi.h 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/fastcgi.h 2006-07-16 00:26:03.000000000 +0300
@@ -1,4 +1,4 @@
-/*
+/*
} FCGI_UnknownTypeBody;
--- ../lighttpd-1.4.11/src/fdevent.c 2005-11-15 10:51:05.000000000 +0200
-+++ lighttpd-1.4.12/src/fdevent.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/fdevent.c 2006-07-18 13:03:40.000000000 +0300
@@ -2,7 +2,6 @@
#include "settings.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
-@@ -12,59 +11,61 @@
+@@ -11,60 +10,116 @@
+
#include "fdevent.h"
#include "buffer.h"
-
++#include "log.h"
++
+#include "sys-socket.h"
+
++fdevent_revent *fdevent_revent_init(void) {
++ STRUCT_INIT(fdevent_revent, revent);
++
++ return revent;
++}
++
++void fdevent_revent_free(fdevent_revent *revent) {
++ if (!revent) return;
++
++ free(revent);
++}
++
++fdevent_revents *fdevent_revents_init(void) {
++ STRUCT_INIT(fdevent_revents, revents);
++
++ return revents;
++}
++
++void fdevent_revents_reset(fdevent_revents *revents) {
++ if (!revents) return;
++
++ revents->used = 0;
++}
++
++void fdevent_revents_add(fdevent_revents *revents, int fd, int events) {
++ fdevent_revent *revent;
++
++ if (revents->used == revents->size) {
++ /* resize the events-array */
++ revents->ptr = realloc(revents->ptr, (revents->size + 1) * sizeof(*(revents->ptr)));
++ revents->ptr[revents->size++] = fdevent_revent_init();
++ }
++
++ revent = revents->ptr[revents->used++];
++ revent->fd = fd;
++ revent->revents = events;
++}
++
++void fdevent_revents_free(fdevent_revents *revents) {
++ size_t i;
++
++ if (!revents) return;
++
++ if (revents->size) {
++ for (i = 0; i < revents->size; i++) {
++ fdevent_revent_free(revents->ptr[i]);
++ }
++
++ free(revents->ptr);
++ }
++ free(revents);
++}
+
fdevents *fdevent_init(size_t maxfds, fdevent_handler_t type) {
fdevents *ev;
-
__FILE__, __LINE__);
return NULL;
}
-@@ -75,26 +76,26 @@
+@@ -75,28 +130,29 @@
void fdevent_free(fdevents *ev) {
size_t i;
if (!ev) return;
+
fdn = calloc(1, sizeof(*fdn));
fdn->fd = -1;
++
return fdn;
-@@ -106,12 +107,12 @@
+ }
- int fdevent_register(fdevents *ev, int fd, fdevent_handler handler, void *ctx) {
+@@ -104,48 +160,40 @@
+ free(fdn);
+ }
+
+-int fdevent_register(fdevents *ev, int fd, fdevent_handler handler, void *ctx) {
++int fdevent_register(fdevents *ev, iosocket *sock, fdevent_handler handler, void *ctx) {
fdnode *fdn;
-
+
fdn = fdnode_init();
fdn->handler = handler;
- fdn->fd = fd;
+- fdn->fd = fd;
++ fdn->fd = sock->fd;
fdn->ctx = ctx;
-
+- ev->fdarray[fd] = fdn;
+
- ev->fdarray[fd] = fdn;
++ ev->fdarray[sock->fd] = fdn;
return 0;
-@@ -121,31 +122,31 @@
+ }
+
+-int fdevent_unregister(fdevents *ev, int fd) {
++int fdevent_unregister(fdevents *ev, iosocket *sock) {
fdnode *fdn;
if (!ev) return 0;
- fdn = ev->fdarray[fd];
+- fdn = ev->fdarray[fd];
-
++ fdn = ev->fdarray[sock->fd];
+
fdnode_free(fdn);
-
-+
- ev->fdarray[fd] = NULL;
+- ev->fdarray[fd] = NULL;
-
++
++ ev->fdarray[sock->fd] = NULL;
+
return 0;
}
- int fdevent_event_del(fdevents *ev, int *fde_ndx, int fd) {
- int fde = fde_ndx ? *fde_ndx : -1;
+-int fdevent_event_del(fdevents *ev, int *fde_ndx, int fd) {
+- int fde = fde_ndx ? *fde_ndx : -1;
-
-+
- if (ev->event_del) fde = ev->event_del(ev, fde, fd);
+- if (ev->event_del) fde = ev->event_del(ev, fde, fd);
-
-+
- if (fde_ndx) *fde_ndx = fde;
+- if (fde_ndx) *fde_ndx = fde;
-
++int fdevent_event_del(fdevents *ev, iosocket *sock) {
++ if (ev->event_del) ev->event_del(ev, sock);
+
return 0;
}
- int fdevent_event_add(fdevents *ev, int *fde_ndx, int fd, int events) {
- int fde = fde_ndx ? *fde_ndx : -1;
+-int fdevent_event_add(fdevents *ev, int *fde_ndx, int fd, int events) {
+- int fde = fde_ndx ? *fde_ndx : -1;
-
-+
- if (ev->event_add) fde = ev->event_add(ev, fde, fd, events);
+- if (ev->event_add) fde = ev->event_add(ev, fde, fd, events);
-
-+
- if (fde_ndx) *fde_ndx = fde;
+- if (fde_ndx) *fde_ndx = fde;
-
++int fdevent_event_add(fdevents *ev, iosocket *sock, int events) {
++ if (ev->event_add) ev->event_add(ev, sock, events);
+
return 0;
}
-@@ -156,38 +157,43 @@
+@@ -154,49 +202,41 @@
+ return ev->poll(ev, timeout_ms);
+ }
- int fdevent_event_get_revent(fdevents *ev, size_t ndx) {
- if (ev->event_get_revent == NULL) SEGFAULT();
+-int fdevent_event_get_revent(fdevents *ev, size_t ndx) {
+- if (ev->event_get_revent == NULL) SEGFAULT();
-
-+
- return ev->event_get_revent(ev, ndx);
- }
+- return ev->event_get_revent(ev, ndx);
+-}
++int fdevent_get_revents(fdevents *ev, size_t event_count, fdevent_revents *revents) {
++ size_t i;
- int fdevent_event_get_fd(fdevents *ev, size_t ndx) {
- if (ev->event_get_fd == NULL) SEGFAULT();
+-int fdevent_event_get_fd(fdevents *ev, size_t ndx) {
+- if (ev->event_get_fd == NULL) SEGFAULT();
-
-+
- return ev->event_get_fd(ev, ndx);
- }
+- return ev->event_get_fd(ev, ndx);
+-}
++ if (ev->get_revents == NULL) SEGFAULT();
- fdevent_handler fdevent_get_handler(fdevents *ev, int fd) {
- if (ev->fdarray[fd] == NULL) SEGFAULT();
- if (ev->fdarray[fd]->fd != fd) SEGFAULT();
+-fdevent_handler fdevent_get_handler(fdevents *ev, int fd) {
+- if (ev->fdarray[fd] == NULL) SEGFAULT();
+- if (ev->fdarray[fd]->fd != fd) SEGFAULT();
-
-+
- return ev->fdarray[fd]->handler;
- }
+- return ev->fdarray[fd]->handler;
+-}
++ fdevent_revents_reset(revents);
- void * fdevent_get_context(fdevents *ev, int fd) {
- if (ev->fdarray[fd] == NULL) SEGFAULT();
- if (ev->fdarray[fd]->fd != fd) SEGFAULT();
+-void * fdevent_get_context(fdevents *ev, int fd) {
+- if (ev->fdarray[fd] == NULL) SEGFAULT();
+- if (ev->fdarray[fd]->fd != fd) SEGFAULT();
-
+- return ev->fdarray[fd]->ctx;
++ ev->get_revents(ev, event_count, revents);
++
++ /* patch the event handlers */
++ for (i = 0; i < event_count; i++) {
++ fdevent_revent *r = revents->ptr[i];
++
++ r->handler = ev->fdarray[r->fd]->handler;
++ r->context = ev->fdarray[r->fd]->ctx;
++ }
+
- return ev->fdarray[fd]->ctx;
++ return 0;
}
- int fdevent_fcntl_set(fdevents *ev, int fd) {
+-int fdevent_fcntl_set(fdevents *ev, int fd) {
++int fdevent_fcntl_set(fdevents *ev, iosocket *sock) {
+#ifdef _WIN32
-+ int i = 1;
++ int i = 1;
+#endif
#ifdef FD_CLOEXEC
/* close fd on exec (cgi) */
- fcntl(fd, F_SETFD, FD_CLOEXEC);
+- fcntl(fd, F_SETFD, FD_CLOEXEC);
++ fcntl(sock->fd, F_SETFD, FD_CLOEXEC);
#endif
- if ((ev) && (ev->fcntl_set)) return ev->fcntl_set(ev, fd);
+- if ((ev) && (ev->fcntl_set)) return ev->fcntl_set(ev, fd);
-#ifdef O_NONBLOCK
+- return fcntl(fd, F_SETFL, O_NONBLOCK | O_RDWR);
++ if ((ev) && (ev->fcntl_set)) return ev->fcntl_set(ev, sock->fd);
+#ifdef O_NONBLOCK
- return fcntl(fd, F_SETFL, O_NONBLOCK | O_RDWR);
++ return fcntl(sock->fd, F_SETFL, O_NONBLOCK | O_RDWR);
+#elif defined _WIN32
-+ return ioctlsocket(fd, FIONBIO, &i);
++ return ioctlsocket(sock->fd, FIONBIO, &i);
#else
return 0;
#endif
-@@ -196,7 +202,7 @@
+ }
- int fdevent_event_next_fdndx(fdevents *ev, int ndx) {
- if (ev->event_next_fdndx) return ev->event_next_fdndx(ev, ndx);
+-
+-int fdevent_event_next_fdndx(fdevents *ev, int ndx) {
+- if (ev->event_next_fdndx) return ev->event_next_fdndx(ev, ndx);
-
+- return -1;
+-}
+-
+--- ../lighttpd-1.4.11/src/fdevent.h 2005-09-27 11:26:33.000000000 +0300
++++ lighttpd-1.4.12/src/fdevent.h 2006-07-18 13:03:40.000000000 +0300
+@@ -7,6 +7,9 @@
+ #include "settings.h"
+ #include "bitset.h"
+
++#include "iosocket.h"
++#include "array-static.h"
+
- return -1;
- }
+ /* select event-system */
---- ../lighttpd-1.4.11/src/fdevent.h 2005-09-27 11:26:33.000000000 +0300
-+++ lighttpd-1.4.12/src/fdevent.h 2006-07-11 22:07:51.000000000 +0300
-@@ -17,13 +17,13 @@
+ #if defined(HAVE_EPOLL_CTL) && defined(HAVE_SYS_EPOLL_H)
+@@ -17,13 +20,13 @@
# include <sys/epoll.h>
#endif
# include <sys/poll.h>
# endif
# if defined HAVE_SIGTIMEDWAIT && defined(__linux__)
-@@ -31,9 +31,11 @@
+@@ -31,9 +34,11 @@
# include <signal.h>
# endif
#endif
# include <winsock2.h>
# endif
# define USE_SELECT
-@@ -67,14 +69,14 @@
+@@ -67,14 +72,14 @@
#define FDEVENT_HUP BV(4)
#define FDEVENT_NVAL BV(5)
FDEVENT_HANDLER_SELECT,
FDEVENT_HANDLER_POLL,
FDEVENT_HANDLER_LINUX_RTSIG,
-@@ -86,7 +88,7 @@
+@@ -86,7 +91,7 @@
/**
* a mapping from fd to connection structure
*/
typedef struct {
int fd; /**< the fd */
-@@ -98,41 +100,41 @@
+@@ -96,43 +101,51 @@
+ int revents;
+ } fd_conn;
++ARRAY_STATIC_DEF(fd_conn_buffer, fd_conn, );
++
++/**
++ * revents
++ */
typedef struct {
- fd_conn *ptr;
+- fd_conn *ptr;
-
+- size_t size;
+- size_t used;
+-} fd_conn_buffer;
++ int fd;
++ int revents;
+
- size_t size;
- size_t used;
- } fd_conn_buffer;
++ fdevent_handler handler;
++ void *context;
++} fdevent_revent;
++
++ARRAY_STATIC_DEF(fdevent_revents, fdevent_revent, );
/**
* array of unused fd's
*/
typedef struct _fdnode {
- fdevent_handler handler;
- void *ctx;
- int fd;
+- fdevent_handler handler;
+- void *ctx;
+- int fd;
-
++ fdevent_handler handler; /* who handles the events for this fd */
++ void *ctx; /* opaque pointer which is passed as 3rd parameter to the handler */
++ int fd; /* fd */
+
struct _fdnode *prev, *next;
} fdnode;
typedef struct fdevents {
fdevent_handler_t type;
-
+- fdnode **fdarray;
+
- fdnode **fdarray;
++ fdnode **fdarray; /* a list of fdnodes */
size_t maxfds;
-
+
#ifdef USE_LINUX_SIGIO
int in_sigio;
int signum;
-@@ -146,21 +148,21 @@
+@@ -146,21 +159,21 @@
#endif
#ifdef USE_POLL
struct pollfd *pollfds;
int select_max_fd;
#endif
#ifdef USE_SOLARIS_DEVPOLL
-@@ -177,16 +179,16 @@
+@@ -177,16 +190,13 @@
#endif
int (*reset)(struct fdevents *ev);
void (*free)(struct fdevents *ev);
-
-+
- int (*event_add)(struct fdevents *ev, int fde_ndx, int fd, int events);
- int (*event_del)(struct fdevents *ev, int fde_ndx, int fd);
- int (*event_get_revent)(struct fdevents *ev, size_t ndx);
- int (*event_get_fd)(struct fdevents *ev, size_t ndx);
+- int (*event_add)(struct fdevents *ev, int fde_ndx, int fd, int events);
+- int (*event_del)(struct fdevents *ev, int fde_ndx, int fd);
+- int (*event_get_revent)(struct fdevents *ev, size_t ndx);
+- int (*event_get_fd)(struct fdevents *ev, size_t ndx);
-
-+
- int (*event_next_fdndx)(struct fdevents *ev, int ndx);
+- int (*event_next_fdndx)(struct fdevents *ev, int ndx);
-
++
++ int (*event_add)(struct fdevents *ev, iosocket *sock, int events);
++ int (*event_del)(struct fdevents *ev, iosocket *sock);
++ int (*get_revents)(struct fdevents *ev, size_t event_count, fdevent_revents *revents);
+
int (*poll)(struct fdevents *ev, int timeout_ms);
-
int (*fcntl_set)(struct fdevents *ev, int fd);
} fdevents;
+@@ -194,22 +204,44 @@
+ int fdevent_reset(fdevents *ev);
+ void fdevent_free(fdevents *ev);
+
+-int fdevent_event_add(fdevents *ev, int *fde_ndx, int fd, int events);
+-int fdevent_event_del(fdevents *ev, int *fde_ndx, int fd);
+-int fdevent_event_get_revent(fdevents *ev, size_t ndx);
+-int fdevent_event_get_fd(fdevents *ev, size_t ndx);
+-fdevent_handler fdevent_get_handler(fdevents *ev, int fd);
+-void * fdevent_get_context(fdevents *ev, int fd);
++/**
++ * call the plugin for the number of available events
++ */
++int fdevent_poll(fdevents *ev, int timeout_ms);
++/**
++ * get all available events
++ */
++int fdevent_get_revents(fdevents *ev, size_t event_count, fdevent_revents *revents);
+
+-int fdevent_event_next_fdndx(fdevents *ev, int ndx);
++/**
++ * add or remove a fd to the handled-pool
++ */
++int fdevent_register(fdevents *ev, iosocket *sock, fdevent_handler handler, void *ctx);
++int fdevent_unregister(fdevents *ev, iosocket *sock);
+
+-int fdevent_poll(fdevents *ev, int timeout_ms);
++/**
++ * add a event to a registered fd
++ */
++int fdevent_event_add(fdevents *ev, iosocket *sock, int events);
++int fdevent_event_del(fdevents *ev, iosocket *sock);
++
++/**
++ * set non-blocking
++ */
++int fdevent_fcntl_set(fdevents *ev, iosocket *sock);
++
++fdevent_revents *fdevent_revents_init(void);
++void fdevent_revents_reset(fdevent_revents *revents);
++void fdevent_revents_add(fdevent_revents *revents, int fd, int events);
++void fdevent_revents_free(fdevent_revents *revents);
+
+-int fdevent_register(fdevents *ev, int fd, fdevent_handler handler, void *ctx);
+-int fdevent_unregister(fdevents *ev, int fd);
++fdevent_revent *fdevent_revent_init(void);
++void fdevent_revent_free(fdevent_revent *revent);
+
+-int fdevent_fcntl_set(fdevents *ev, int fd);
+
++/**
++ * plugin init
++ */
+ int fdevent_select_init(fdevents *ev);
+ int fdevent_poll_init(fdevents *ev);
+ int fdevent_linux_rtsig_init(fdevents *ev);
--- ../lighttpd-1.4.11/src/fdevent_freebsd_kqueue.c 2005-09-01 10:46:24.000000000 +0300
-+++ lighttpd-1.4.12/src/fdevent_freebsd_kqueue.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/fdevent_freebsd_kqueue.c 2006-07-16 00:26:03.000000000 +0300
@@ -1,6 +1,5 @@
#include <sys/types.h>
}
--- ../lighttpd-1.4.11/src/fdevent_linux_rtsig.c 2005-11-21 19:56:11.000000000 +0200
-+++ lighttpd-1.4.12/src/fdevent_linux_rtsig.c 2006-07-15 22:43:21.000000000 +0300
++++ lighttpd-1.4.12/src/fdevent_linux_rtsig.c 2006-07-18 13:03:40.000000000 +0300
@@ -1,6 +1,5 @@
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-@@ -14,6 +13,7 @@
+@@ -14,6 +13,8 @@
#include "fdevent.h"
#include "settings.h"
#include "buffer.h"
+#include "sys-process.h"
++#include "log.h"
#ifdef USE_LINUX_SIGIO
static void fdevent_linux_rtsig_free(fdevents *ev) {
-@@ -26,19 +26,19 @@
+@@ -24,21 +25,21 @@
+ }
- static int fdevent_linux_rtsig_event_del(fdevents *ev, int fde_ndx, int fd) {
- if (fde_ndx < 0) return -1;
+
+-static int fdevent_linux_rtsig_event_del(fdevents *ev, int fde_ndx, int fd) {
+- if (fde_ndx < 0) return -1;
-
+- if ((size_t)fde_ndx >= ev->used) {
+- fprintf(stderr, "%s.%d: del! out of range %d %zu\n", __FILE__, __LINE__, fde_ndx, ev->used);
++static int fdevent_linux_rtsig_event_del(fdevents *ev, iosocket *sock) {
++ if (sock->fde_ndx < 0) return -1;
+
- if ((size_t)fde_ndx >= ev->used) {
- fprintf(stderr, "%s.%d: del! out of range %d %zu\n", __FILE__, __LINE__, fde_ndx, ev->used);
++ if ((size_t)sock->fde_ndx >= ev->used) {
++ TRACE("del! out of range %d %zu\n", sock->fde_ndx, ev->used);
SEGFAULT();
}
-
-+
- if (ev->pollfds[fde_ndx].fd == fd) {
- size_t k = fde_ndx;
+- if (ev->pollfds[fde_ndx].fd == fd) {
+- size_t k = fde_ndx;
-
++
++ if (ev->pollfds[sock->fde_ndx].fd == sock->fd) {
++ size_t k = sock->fde_ndx;
+
ev->pollfds[k].fd = -1;
- bitset_clear_bit(ev->sigbset, fd);
+- bitset_clear_bit(ev->sigbset, fd);
-
++ bitset_clear_bit(ev->sigbset, sock->fd);
+
if (ev->unused.size == 0) {
ev->unused.size = 16;
ev->unused.ptr = malloc(sizeof(*(ev->unused.ptr)) * ev->unused.size);
-@@ -46,29 +46,29 @@
+@@ -46,53 +47,54 @@
ev->unused.size += 16;
ev->unused.ptr = realloc(ev->unused.ptr, sizeof(*(ev->unused.ptr)) * ev->unused.size);
}
+
ev->unused.ptr[ev->unused.used++] = k;
} else {
- fprintf(stderr, "%s.%d: del! %d %d\n", __FILE__, __LINE__, ev->pollfds[fde_ndx].fd, fd);
+- fprintf(stderr, "%s.%d: del! %d %d\n", __FILE__, __LINE__, ev->pollfds[fde_ndx].fd, fd);
-
++ fprintf(stderr, "%s.%d: del! %d %d\n", __FILE__, __LINE__, ev->pollfds[sock->fde_ndx].fd, sock->fd);
+
SEGFAULT();
}
-
+- return -1;
++ sock->fde_ndx = -1;
+
- return -1;
++ return 0;
}
#if 0
return 0;
}
#endif
-@@ -78,21 +78,21 @@
- if (fde_ndx != -1) {
- if (ev->pollfds[fde_ndx].fd == fd) {
- ev->pollfds[fde_ndx].events = events;
+
+-static int fdevent_linux_rtsig_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
++static int fdevent_linux_rtsig_event_add(fdevents *ev, iosocket *sock, int events) {
+ /* known index */
+- if (fde_ndx != -1) {
+- if (ev->pollfds[fde_ndx].fd == fd) {
+- ev->pollfds[fde_ndx].events = events;
-
+- return fde_ndx;
++ if (sock->fde_ndx != -1) {
++ if (ev->pollfds[sock->fde_ndx].fd == sock->fd) {
++ ev->pollfds[sock->fde_ndx].events = events;
+
- return fde_ndx;
++ return sock->fde_ndx;
}
- fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, fde_ndx, ev->pollfds[fde_ndx].fd);
+- fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, fde_ndx, ev->pollfds[fde_ndx].fd);
++ fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, sock->fde_ndx, ev->pollfds[sock->fde_ndx].fd);
SEGFAULT();
}
-
if (ev->unused.used > 0) {
int k = ev->unused.ptr[--ev->unused.used];
-
+- ev->pollfds[k].fd = fd;
+
- ev->pollfds[k].fd = fd;
++ ev->pollfds[k].fd = sock->fd;
ev->pollfds[k].events = events;
- bitset_set_bit(ev->sigbset, fd);
+- bitset_set_bit(ev->sigbset, fd);
-
++ bitset_set_bit(ev->sigbset, sock->fd);
+
return k;
} else {
if (ev->size == 0) {
-@@ -102,12 +102,12 @@
+@@ -102,12 +104,12 @@
ev->size += 16;
ev->pollfds = realloc(ev->pollfds, sizeof(*ev->pollfds) * ev->size);
}
-
+- ev->pollfds[ev->used].fd = fd;
+
- ev->pollfds[ev->used].fd = fd;
++ ev->pollfds[ev->used].fd = sock->fd;
ev->pollfds[ev->used].events = events;
- bitset_set_bit(ev->sigbset, fd);
+- bitset_set_bit(ev->sigbset, fd);
-
++ bitset_set_bit(ev->sigbset, sock->fd);
+
return ev->used++;
}
}
-@@ -115,20 +115,20 @@
+@@ -115,20 +117,20 @@
static int fdevent_linux_rtsig_poll(fdevents *ev, int timeout_ms) {
struct timespec ts;
int r;
} else if (r == SIGIO) {
struct sigaction act;
-@@ -140,7 +140,7 @@
+@@ -140,7 +142,7 @@
/* re-enable the signal queue */
act.sa_handler = SIG_DFL;
sigaction(ev->signum, &act, NULL);
ev->in_sigio = 0;
r = poll(ev->pollfds, ev->used, timeout_ms);
-@@ -162,12 +162,12 @@
- if (ev->siginfo.si_band == POLLERR) {
- fprintf(stderr, "event: %d %02lx %02x %s\n", ev->siginfo.si_fd, ev->siginfo.si_band, errno, strerror(errno));
- }
+@@ -156,97 +158,67 @@
+ }
+ }
+
+-static int fdevent_linux_rtsig_event_get_revent(fdevents *ev, size_t ndx) {
++static int fdevent_linux_rtsig_get_revents(fdevents *ev, size_t event_count, fdevent_revents *revents) {
+ if (ev->in_sigio == 1) {
+-# if 0
+- if (ev->siginfo.si_band == POLLERR) {
+- fprintf(stderr, "event: %d %02lx %02x %s\n", ev->siginfo.si_fd, ev->siginfo.si_band, errno, strerror(errno));
+- }
-# endif
-+# endif
- if (ndx != 0) {
- fprintf(stderr, "+\n");
- return 0;
- }
+- if (ndx != 0) {
+- fprintf(stderr, "+\n");
+- return 0;
+- }
-
+- return ev->siginfo.si_band & 0x3f;
++ /* only one event */
+
- return ev->siginfo.si_band & 0x3f;
++ fdevent_revents_add(revents, ev->siginfo.si_fd, ev->siginfo.si_band & 0x3f);
} else {
- if (ndx >= ev->used) {
-@@ -188,13 +188,13 @@
+- if (ndx >= ev->used) {
+- fprintf(stderr, "%s.%d: event: %zu %zu\n", __FILE__, __LINE__, ndx, ev->used);
+- return 0;
++ size_t ndx;
++
++ for (ndx = 0; ndx < ev->used; ndx++) {
++ if (ev->pollfds[ndx].revents) {
++ fdevent_revents_add(revents, ev->pollfds[ndx].fd, ev->pollfds[ndx].revents);
++ }
+ }
+- return ev->pollfds[ndx].revents;
+ }
+-}
+
+-static int fdevent_linux_rtsig_event_get_fd(fdevents *ev, size_t ndx) {
+- if (ev->in_sigio == 1) {
+- return ev->siginfo.si_fd;
+- } else {
+- return ev->pollfds[ndx].fd;
+- }
++ return 0;
+ }
static int fdevent_linux_rtsig_fcntl_set(fdevents *ev, int fd) {
static pid_t pid = 0;
return fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK | O_RDWR);
}
-@@ -205,12 +205,12 @@
- return -1;
- } else {
- size_t i;
+
+-static int fdevent_linux_rtsig_event_next_fdndx(fdevents *ev, int ndx) {
+- if (ev->in_sigio == 1) {
+- if (ndx < 0) return 0;
+- return -1;
+- } else {
+- size_t i;
-
-+
- i = (ndx < 0) ? 0 : ndx + 1;
- for (; i < ev->used; i++) {
- if (ev->pollfds[i].revents) break;
- }
+- i = (ndx < 0) ? 0 : ndx + 1;
+- for (; i < ev->used; i++) {
+- if (ev->pollfds[i].revents) break;
+- }
-
-+
- return i;
- }
- }
-@@ -219,34 +219,34 @@
+- return i;
+- }
+-}
+-
+ int fdevent_linux_rtsig_init(fdevents *ev) {
ev->type = FDEVENT_HANDLER_LINUX_RTSIG;
#define SET(x) \
ev->x = fdevent_linux_rtsig_##x;
SET(event_del);
SET(event_add);
-
+- SET(event_next_fdndx);
+
- SET(event_next_fdndx);
SET(fcntl_set);
- SET(event_get_fd);
- SET(event_get_revent);
+- SET(event_get_fd);
+- SET(event_get_revent);
-
++ SET(get_revents);
+
ev->signum = SIGRTMIN + 1;
-
}
#else
--- ../lighttpd-1.4.11/src/fdevent_linux_sysepoll.c 2005-09-30 20:29:27.000000000 +0300
-+++ lighttpd-1.4.12/src/fdevent_linux_sysepoll.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/fdevent_linux_sysepoll.c 2006-07-18 13:03:40.000000000 +0300
@@ -1,6 +1,5 @@
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-@@ -12,6 +11,8 @@
+@@ -11,6 +10,9 @@
+ #include "fdevent.h"
#include "settings.h"
#include "buffer.h"
-
-+#include "sys-files.h"
++#include "log.h"
+
++#include "sys-files.h"
+
#ifdef USE_LINUX_EPOLL
static void fdevent_linux_sysepoll_free(fdevents *ev) {
- close(ev->epoll_fd);
-@@ -20,36 +21,36 @@
+@@ -18,38 +20,40 @@
+ free(ev->epoll_events);
+ }
- static int fdevent_linux_sysepoll_event_del(fdevents *ev, int fde_ndx, int fd) {
+-static int fdevent_linux_sysepoll_event_del(fdevents *ev, int fde_ndx, int fd) {
++static int fdevent_linux_sysepoll_event_del(fdevents *ev, iosocket *sock) {
struct epoll_event ep;
-
-+
- if (fde_ndx < 0) return -1;
+- if (fde_ndx < 0) return -1;
-
++
++ if (sock->fde_ndx < 0) return -1;
+
memset(&ep, 0, sizeof(ep));
-
+- ep.data.fd = fd;
+
- ep.data.fd = fd;
++ ep.data.fd = sock->fd;
ep.data.ptr = NULL;
-
+- if (0 != epoll_ctl(ev->epoll_fd, EPOLL_CTL_DEL, fd, &ep)) {
+
- if (0 != epoll_ctl(ev->epoll_fd, EPOLL_CTL_DEL, fd, &ep)) {
++ if (0 != epoll_ctl(ev->epoll_fd, EPOLL_CTL_DEL, sock->fd, &ep)) {
fprintf(stderr, "%s.%d: epoll_ctl failed: %s, dying\n", __FILE__, __LINE__, strerror(errno));
-
+
}
-
-
+- return -1;
+
++ sock->fde_ndx = -1;
+
- return -1;
++ return 0;
}
- static int fdevent_linux_sysepoll_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
+-static int fdevent_linux_sysepoll_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
++static int fdevent_linux_sysepoll_event_add(fdevents *ev, iosocket *sock, int events) {
struct epoll_event ep;
int add = 0;
-
-+
- if (fde_ndx == -1) add = 1;
+- if (fde_ndx == -1) add = 1;
-
++
++ /* a new fd */
++ if (sock->fde_ndx == -1) add = 1;
+
memset(&ep, 0, sizeof(ep));
-
if (events & FDEVENT_IN) ep.events |= EPOLLIN;
if (events & FDEVENT_OUT) ep.events |= EPOLLOUT;
-@@ -60,20 +61,20 @@
+@@ -60,73 +64,61 @@
* sent.
*
*/
-
+
ep.data.ptr = NULL;
- ep.data.fd = fd;
+- ep.data.fd = fd;
-
+- if (0 != epoll_ctl(ev->epoll_fd, add ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, fd, &ep)) {
++ ep.data.fd = sock->fd;
+
- if (0 != epoll_ctl(ev->epoll_fd, add ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, fd, &ep)) {
++ if (0 != epoll_ctl(ev->epoll_fd, add ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, sock->fd, &ep)) {
fprintf(stderr, "%s.%d: epoll_ctl failed: %s, dying\n", __FILE__, __LINE__, strerror(errno));
-
+
return 0;
}
-
+- return fd;
+
- return fd;
++ sock->fde_ndx = sock->fd;
++
++ return 0;
}
-@@ -83,14 +84,14 @@
+ static int fdevent_linux_sysepoll_poll(fdevents *ev, int timeout_ms) {
+ return epoll_wait(ev->epoll_fd, ev->epoll_events, ev->maxfds, timeout_ms);
+ }
- static int fdevent_linux_sysepoll_event_get_revent(fdevents *ev, size_t ndx) {
- int events = 0, e;
+-static int fdevent_linux_sysepoll_event_get_revent(fdevents *ev, size_t ndx) {
+- int events = 0, e;
-
-+
- e = ev->epoll_events[ndx].events;
- if (e & EPOLLIN) events |= FDEVENT_IN;
- if (e & EPOLLOUT) events |= FDEVENT_OUT;
- if (e & EPOLLERR) events |= FDEVENT_ERR;
- if (e & EPOLLHUP) events |= FDEVENT_HUP;
- if (e & EPOLLPRI) events |= FDEVENT_PRI;
+- e = ev->epoll_events[ndx].events;
+- if (e & EPOLLIN) events |= FDEVENT_IN;
+- if (e & EPOLLOUT) events |= FDEVENT_OUT;
+- if (e & EPOLLERR) events |= FDEVENT_ERR;
+- if (e & EPOLLHUP) events |= FDEVENT_HUP;
+- if (e & EPOLLPRI) events |= FDEVENT_PRI;
-
-+
- return e;
- }
-
-@@ -98,17 +99,17 @@
- # if 0
- fprintf(stderr, "%s.%d: %d, %d\n", __FILE__, __LINE__, ndx, ev->epoll_events[ndx].data.fd);
- # endif
+- return e;
+-}
+-
+-static int fdevent_linux_sysepoll_event_get_fd(fdevents *ev, size_t ndx) {
+-# if 0
+- fprintf(stderr, "%s.%d: %d, %d\n", __FILE__, __LINE__, ndx, ev->epoll_events[ndx].data.fd);
+-# endif
-
-+
- return ev->epoll_events[ndx].data.fd;
- }
-
- static int fdevent_linux_sysepoll_event_next_fdndx(fdevents *ev, int ndx) {
- size_t i;
+- return ev->epoll_events[ndx].data.fd;
+-}
+-
+-static int fdevent_linux_sysepoll_event_next_fdndx(fdevents *ev, int ndx) {
+- size_t i;
-
+- UNUSED(ev);
++static int fdevent_linux_sysepoll_get_revents(fdevents *ev, size_t event_count, fdevent_revents *revents) {
++ size_t ndx;
+
- UNUSED(ev);
++ for (ndx = 0; ndx < event_count; ndx++) {
++ int events = 0, e;
++
++ e = ev->epoll_events[ndx].events;
++ if (e & EPOLLIN) events |= FDEVENT_IN;
++ if (e & EPOLLOUT) events |= FDEVENT_OUT;
++ if (e & EPOLLERR) events |= FDEVENT_ERR;
++ if (e & EPOLLHUP) events |= FDEVENT_HUP;
++ if (e & EPOLLPRI) events |= FDEVENT_PRI;
- i = (ndx < 0) ? 0 : ndx + 1;
+- i = (ndx < 0) ? 0 : ndx + 1;
-
+- return i;
++ fdevent_revents_add(revents, ev->epoll_events[ndx].data.fd, e);
++ }
+
- return i;
++ return 0;
}
-@@ -116,17 +117,17 @@
+ int fdevent_linux_sysepoll_init(fdevents *ev) {
ev->type = FDEVENT_HANDLER_LINUX_SYSEPOLL;
#define SET(x) \
ev->x = fdevent_linux_sysepoll_##x;
SET(event_del);
SET(event_add);
-
-+
- SET(event_next_fdndx);
- SET(event_get_fd);
- SET(event_get_revent);
+- SET(event_next_fdndx);
+- SET(event_get_fd);
+- SET(event_get_revent);
-
++
++ SET(get_revents);
+
if (-1 == (ev->epoll_fd = epoll_create(ev->maxfds))) {
fprintf(stderr, "%s.%d: epoll_create failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
__FILE__, __LINE__, strerror(errno));
-@@ -154,7 +155,7 @@
+@@ -154,7 +146,7 @@
fprintf(stderr, "%s.%d: linux-sysepoll not supported, try to set server.event-handler = \"poll\" or \"select\"\n",
__FILE__, __LINE__);
}
#endif
--- ../lighttpd-1.4.11/src/fdevent_poll.c 2005-11-18 13:59:16.000000000 +0200
-+++ lighttpd-1.4.12/src/fdevent_poll.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/fdevent_poll.c 2006-07-18 13:03:40.000000000 +0300
@@ -1,6 +1,5 @@
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-@@ -20,19 +19,19 @@
+@@ -11,6 +10,7 @@
+ #include "fdevent.h"
+ #include "settings.h"
+ #include "buffer.h"
++#include "log.h"
- static int fdevent_poll_event_del(fdevents *ev, int fde_ndx, int fd) {
- if (fde_ndx < 0) return -1;
+ #ifdef USE_POLL
+ static void fdevent_poll_free(fdevents *ev) {
+@@ -18,21 +18,21 @@
+ if (ev->unused.ptr) free(ev->unused.ptr);
+ }
+
+-static int fdevent_poll_event_del(fdevents *ev, int fde_ndx, int fd) {
+- if (fde_ndx < 0) return -1;
-
+- if ((size_t)fde_ndx >= ev->used) {
+- fprintf(stderr, "%s.%d: del! out of range %d %zd\n", __FILE__, __LINE__, fde_ndx, ev->used);
++static int fdevent_poll_event_del(fdevents *ev, iosocket *sock) {
++ if (sock->fde_ndx < 0) return -1;
+
- if ((size_t)fde_ndx >= ev->used) {
- fprintf(stderr, "%s.%d: del! out of range %d %zd\n", __FILE__, __LINE__, fde_ndx, ev->used);
++ if ((size_t)sock->fde_ndx >= ev->used) {
++ fprintf(stderr, "%s.%d: del! out of range %d %zd\n", __FILE__, __LINE__, sock->fde_ndx, ev->used);
SEGFAULT();
}
-
-+
- if (ev->pollfds[fde_ndx].fd == fd) {
- size_t k = fde_ndx;
+- if (ev->pollfds[fde_ndx].fd == fd) {
+- size_t k = fde_ndx;
-
++
++ if (ev->pollfds[sock->fde_ndx].fd == sock->fd) {
++ size_t k = sock->fde_ndx;
+
ev->pollfds[k].fd = -1;
/* ev->pollfds[k].events = 0; */
if (ev->unused.size == 0) {
ev->unused.size = 16;
ev->unused.ptr = malloc(sizeof(*(ev->unused.ptr)) * ev->unused.size);
-@@ -40,47 +39,47 @@
+@@ -40,48 +40,51 @@
ev->unused.size += 16;
ev->unused.ptr = realloc(ev->unused.ptr, sizeof(*(ev->unused.ptr)) * ev->unused.size);
}
SEGFAULT();
}
-
+- return -1;
+
- return -1;
++ sock->fde_ndx = -1;
++
++ return 0;
}
#if 0
}
#endif
- static int fdevent_poll_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
- /* known index */
+-static int fdevent_poll_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
+- /* known index */
-
-+
- if (fde_ndx != -1) {
- if (ev->pollfds[fde_ndx].fd == fd) {
- ev->pollfds[fde_ndx].events = events;
+- if (fde_ndx != -1) {
+- if (ev->pollfds[fde_ndx].fd == fd) {
+- ev->pollfds[fde_ndx].events = events;
-
+- return fde_ndx;
++static int fdevent_poll_event_add(fdevents *ev, iosocket *sock, int events) {
++ if (sock->fde_ndx != -1) {
++ /* this fd was already added, just change the requested events */
++
++ if (ev->pollfds[sock->fde_ndx].fd == sock->fd) {
++ ev->pollfds[sock->fde_ndx].events = events;
+
- return fde_ndx;
++ return sock->fde_ndx;
}
- fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, fde_ndx, ev->pollfds[fde_ndx].fd);
+- fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, fde_ndx, ev->pollfds[fde_ndx].fd);
++ fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, sock->fde_ndx, ev->pollfds[sock->fde_ndx].fd);
SEGFAULT();
}
-
if (ev->unused.used > 0) {
int k = ev->unused.ptr[--ev->unused.used];
-
+- ev->pollfds[k].fd = fd;
+
- ev->pollfds[k].fd = fd;
++ ev->pollfds[k].fd = sock->fd;
ev->pollfds[k].events = events;
-
+- return k;
++
++ sock->fde_ndx = k;
+
- return k;
} else {
if (ev->size == 0) {
-@@ -90,10 +89,10 @@
+ ev->size = 16;
+@@ -90,12 +93,13 @@
ev->size += 16;
ev->pollfds = realloc(ev->pollfds, sizeof(*ev->pollfds) * ev->size);
}
-
+- ev->pollfds[ev->used].fd = fd;
+
- ev->pollfds[ev->used].fd = fd;
++ ev->pollfds[ev->used].fd = sock->fd;
ev->pollfds[ev->used].events = events;
-
+- return ev->used++;
+
- return ev->used++;
++ sock->fde_ndx = ev->used++;
}
++ return 0;
}
-@@ -109,12 +108,12 @@
- int r, poll_r;
- if (ndx >= ev->used) {
- fprintf(stderr, "%s.%d: dying because: event: %zd >= %zd\n", __FILE__, __LINE__, ndx, ev->used);
+
+ static int fdevent_poll_poll(fdevents *ev, int timeout_ms) {
+@@ -105,71 +109,38 @@
+ return poll(ev->pollfds, ev->used, timeout_ms);
+ }
+
+-static int fdevent_poll_event_get_revent(fdevents *ev, size_t ndx) {
+- int r, poll_r;
+- if (ndx >= ev->used) {
+- fprintf(stderr, "%s.%d: dying because: event: %zd >= %zd\n", __FILE__, __LINE__, ndx, ev->used);
-
-+
- SEGFAULT();
+- SEGFAULT();
-
-+
- return 0;
- }
--
-+
- if (ev->pollfds[ndx].revents & POLLNVAL) {
- /* should never happen */
- SEGFAULT();
-@@ -131,7 +130,7 @@
- if (poll_r & POLLHUP) r |= FDEVENT_HUP;
- if (poll_r & POLLNVAL) r |= FDEVENT_NVAL;
- if (poll_r & POLLPRI) r |= FDEVENT_PRI;
+- return 0;
+- }
-
-+
- return ev->pollfds[ndx].revents;
- }
-
-@@ -141,12 +140,12 @@
+- if (ev->pollfds[ndx].revents & POLLNVAL) {
+- /* should never happen */
+- SEGFAULT();
+- }
++static int fdevent_poll_get_revents(fdevents *ev, size_t event_count, fdevent_revents *revents) {
++ size_t ndx;
+
+- r = 0;
+- poll_r = ev->pollfds[ndx].revents;
++ for (ndx = 0; ndx < ev->used; ndx++) {
++ if (ev->pollfds[ndx].revents) {
++ if (ev->pollfds[ndx].revents & POLLNVAL) {
++ /* should never happen */
++ SEGFAULT();
++ }
- static int fdevent_poll_event_next_fdndx(fdevents *ev, int ndx) {
- size_t i;
+- /* map POLL* to FDEVEN_* */
+-
+- if (poll_r & POLLIN) r |= FDEVENT_IN;
+- if (poll_r & POLLOUT) r |= FDEVENT_OUT;
+- if (poll_r & POLLERR) r |= FDEVENT_ERR;
+- if (poll_r & POLLHUP) r |= FDEVENT_HUP;
+- if (poll_r & POLLNVAL) r |= FDEVENT_NVAL;
+- if (poll_r & POLLPRI) r |= FDEVENT_PRI;
+-
+- return ev->pollfds[ndx].revents;
+-}
+-
+-static int fdevent_poll_event_get_fd(fdevents *ev, size_t ndx) {
+- return ev->pollfds[ndx].fd;
+-}
+-
+-static int fdevent_poll_event_next_fdndx(fdevents *ev, int ndx) {
+- size_t i;
-
-+
- i = (ndx < 0) ? 0 : ndx + 1;
- for (; i < ev->used; i++) {
- if (ev->pollfds[i].revents) break;
+- i = (ndx < 0) ? 0 : ndx + 1;
+- for (; i < ev->used; i++) {
+- if (ev->pollfds[i].revents) break;
++ fdevent_revents_add(revents, ev->pollfds[ndx].fd, ev->pollfds[ndx].revents);
++ }
}
-
+- return i;
+
- return i;
++ return 0;
}
-@@ -154,17 +153,17 @@
+ int fdevent_poll_init(fdevents *ev) {
ev->type = FDEVENT_HANDLER_POLL;
#define SET(x) \
ev->x = fdevent_poll_##x;
SET(event_del);
SET(event_add);
-
-+
- SET(event_next_fdndx);
- SET(event_get_fd);
- SET(event_get_revent);
+- SET(event_next_fdndx);
+- SET(event_get_fd);
+- SET(event_get_revent);
-
-+
- return 0;
- }
+- return 0;
+-}
+-
++ SET(get_revents);
+
++ return 0;
++}
+
+ #else
+ int fdevent_poll_init(fdevents *ev) {
--- ../lighttpd-1.4.11/src/fdevent_select.c 2005-08-31 11:12:46.000000000 +0300
-+++ lighttpd-1.4.12/src/fdevent_select.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/fdevent_select.c 2006-07-18 13:03:40.000000000 +0300
@@ -1,18 +1,19 @@
-#include <sys/time.h>
#include <sys/types.h>
#ifdef USE_SELECT
static int fdevent_select_reset(fdevents *ev) {
-@@ -38,7 +39,9 @@
- UNUSED(fde_ndx);
+@@ -24,101 +25,98 @@
+ return 0;
+ }
+
+-static int fdevent_select_event_del(fdevents *ev, int fde_ndx, int fd) {
+- if (fde_ndx < 0) return -1;
++static int fdevent_select_event_del(fdevents *ev, iosocket *sock) {
++ if (sock->fde_ndx < 0) return -1;
+- FD_CLR(fd, &(ev->select_set_read));
+- FD_CLR(fd, &(ev->select_set_write));
+- FD_CLR(fd, &(ev->select_set_error));
++ FD_CLR(sock->fd, &(ev->select_set_read));
++ FD_CLR(sock->fd, &(ev->select_set_write));
++ FD_CLR(sock->fd, &(ev->select_set_error));
+
+- return -1;
+-}
++ /* mark the fdevent as deleted */
++ sock->fde_ndx = -1;
+
+-static int fdevent_select_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
+- UNUSED(fde_ndx);
++ return 0;
++}
+
++static int fdevent_select_event_add(fdevents *ev, iosocket *sock, int events) {
/* we should be protected by max-fds, but you never know */
+- assert(fd < FD_SETSIZE);
+#ifndef _WIN32
- assert(fd < FD_SETSIZE);
++ assert(sock->fd < FD_SETSIZE);
+#endif
if (events & FDEVENT_IN) {
- FD_SET(fd, &(ev->select_set_read));
-@@ -49,28 +52,28 @@
- FD_SET(fd, &(ev->select_set_write));
+- FD_SET(fd, &(ev->select_set_read));
+- FD_CLR(fd, &(ev->select_set_write));
++ FD_SET(sock->fd, &(ev->select_set_read));
++ FD_CLR(sock->fd, &(ev->select_set_write));
}
- FD_SET(fd, &(ev->select_set_error));
+ if (events & FDEVENT_OUT) {
+- FD_CLR(fd, &(ev->select_set_read));
+- FD_SET(fd, &(ev->select_set_write));
++ FD_CLR(sock->fd, &(ev->select_set_read));
++ FD_SET(sock->fd, &(ev->select_set_write));
+ }
+- FD_SET(fd, &(ev->select_set_error));
-
-+
- if (fd > ev->select_max_fd) ev->select_max_fd = fd;
+- if (fd > ev->select_max_fd) ev->select_max_fd = fd;
-
+- return fd;
++ FD_SET(sock->fd, &(ev->select_set_error));
+
- return fd;
++ /* we need this for the poll */
++ if (sock->fd > ev->select_max_fd) ev->select_max_fd = sock->fd;
++
++ /* mark fd as added */
++ sock->fde_ndx = sock->fd;
++
++ return 0;
}
static int fdevent_select_poll(fdevents *ev, int timeout_ms) {
return select(ev->select_max_fd + 1, &(ev->select_read), &(ev->select_write), &(ev->select_error), &tv);
}
- static int fdevent_select_event_get_revent(fdevents *ev, size_t ndx) {
- int revents = 0;
+-static int fdevent_select_event_get_revent(fdevents *ev, size_t ndx) {
+- int revents = 0;
-
+- if (FD_ISSET(ndx, &(ev->select_read))) {
+- revents |= FDEVENT_IN;
++/**
++ * scan the fdset for events
++ */
++static int fdevent_select_get_revents(fdevents *ev, size_t event_count, fdevent_revents *revents) {
+
- if (FD_ISSET(ndx, &(ev->select_read))) {
- revents |= FDEVENT_IN;
- }
-@@ -80,7 +83,7 @@
- if (FD_ISSET(ndx, &(ev->select_error))) {
- revents |= FDEVENT_ERR;
++ int ndx = 0;
++
++ for (ndx = 0; ndx < ev->select_max_fd; ndx++) {
++ int events = 0;
++
++ if (FD_ISSET(ndx, &(ev->select_read))) {
++ events |= FDEVENT_IN;
++ }
++ if (FD_ISSET(ndx, &(ev->select_write))) {
++ events |= FDEVENT_OUT;
++ }
++ if (FD_ISSET(ndx, &(ev->select_error))) {
++ events |= FDEVENT_ERR;
++ }
++
++ if (events) {
++ fdevent_revents_add(revents, ndx, events);
++ }
}
+- if (FD_ISSET(ndx, &(ev->select_write))) {
+- revents |= FDEVENT_OUT;
+- }
+- if (FD_ISSET(ndx, &(ev->select_error))) {
+- revents |= FDEVENT_ERR;
+- }
-
-+
- return revents;
- }
-
-@@ -92,15 +95,15 @@
+- return revents;
+-}
+-
+-static int fdevent_select_event_get_fd(fdevents *ev, size_t ndx) {
+- UNUSED(ev);
+-
+- return ndx;
+-}
- static int fdevent_select_event_next_fdndx(fdevents *ev, int ndx) {
- int i;
+-static int fdevent_select_event_next_fdndx(fdevents *ev, int ndx) {
+- int i;
-
-+
- i = (ndx < 0) ? 0 : ndx + 1;
+- i = (ndx < 0) ? 0 : ndx + 1;
-
-+
- for (; i < ev->select_max_fd + 1; i++) {
- if (FD_ISSET(i, &(ev->select_read))) break;
- if (FD_ISSET(i, &(ev->select_write))) break;
- if (FD_ISSET(i, &(ev->select_error))) break;
- }
+- for (; i < ev->select_max_fd + 1; i++) {
+- if (FD_ISSET(i, &(ev->select_read))) break;
+- if (FD_ISSET(i, &(ev->select_write))) break;
+- if (FD_ISSET(i, &(ev->select_error))) break;
+- }
-
-+
- return i;
+- return i;
++ return 0;
}
-@@ -108,17 +111,17 @@
+ int fdevent_select_init(fdevents *ev) {
ev->type = FDEVENT_HANDLER_SELECT;
#define SET(x) \
ev->x = fdevent_select_##x;
SET(event_del);
SET(event_add);
-
-+
- SET(event_next_fdndx);
- SET(event_get_fd);
- SET(event_get_revent);
+- SET(event_next_fdndx);
+- SET(event_get_fd);
+- SET(event_get_revent);
-
++
++ SET(get_revents);
+
return 0;
}
--- ../lighttpd-1.4.11/src/fdevent_solaris_devpoll.c 2005-09-01 10:45:26.000000000 +0300
-+++ lighttpd-1.4.12/src/fdevent_solaris_devpoll.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/fdevent_solaris_devpoll.c 2006-07-16 00:26:03.000000000 +0300
@@ -1,6 +1,5 @@
#include <sys/types.h>
}
#endif
--- ../lighttpd-1.4.11/src/http-header-glue.c 2006-02-08 15:31:36.000000000 +0200
-+++ lighttpd-1.4.12/src/http-header-glue.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/http-header-glue.c 2006-07-18 13:03:40.000000000 +0300
@@ -45,20 +45,20 @@
# ifdef HAVE_STRUCT_SOCKADDR_STORAGE
static size_t get_sa_len(const struct sockaddr *addr) {
+
our_addr_len = sizeof(our_addr);
-
+- if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) {
+
- if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) {
++ if (-1 == getsockname(con->sock->fd, &(our_addr.plain), &our_addr_len)) {
con->http_status = 500;
-
+
}
--- ../lighttpd-1.4.11/src/http_auth.c 2006-02-01 13:02:52.000000000 +0200
-+++ lighttpd-1.4.12/src/http_auth.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/http_auth.c 2006-07-18 13:03:40.000000000 +0300
@@ -22,7 +22,6 @@
#include <string.h>
#include <time.h>
-
+
/* if we get here, the user we got a authed user */
- if (0 == strcmp(require->value->ptr, "valid-user")) {
+- if (0 == strcmp(require->value->ptr, "valid-user")) {
++ if (buffer_is_equal_string(require->value, CONST_STR_LEN("valid-user"))) {
return 0;
}
-
+
CvtHex(HA1, a1);
-
+- if (0 == strcmp(password->ptr, a1)) {
+
- if (0 == strcmp(password->ptr, a1)) {
++ if (buffer_is_equal_string(password, a1, strlen(a1))) {
return 0;
}
- } else if (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) {
if (NULL == (dollar = strchr(password->ptr + 3, '$'))) {
fprintf(stderr, "%s.%d\n", __FILE__, __LINE__);
return -1;
-@@ -495,7 +485,7 @@
+@@ -495,48 +485,21 @@
strncpy(salt, password->ptr, salt_len);
salt[salt_len] = '\0';
+
crypted = crypt(pw, salt);
- if (0 == strcmp(password->ptr, crypted)) {
-@@ -503,40 +493,13 @@
+- if (0 == strcmp(password->ptr, crypted)) {
++ if (buffer_is_equal_string(password, crypted, strlen(crypted))) {
+ return 0;
} else {
fprintf(stderr, "%s.%d\n", __FILE__, __LINE__);
}
-
-#endif
- } else if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
-+
-+#endif
-+ } else if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
- if (0 == strcmp(password->ptr, pw)) {
- return 0;
- }
+- if (0 == strcmp(password->ptr, pw)) {
+- return 0;
+- }
- } else if (p->conf.auth_backend == AUTH_BACKEND_PAM) {
-#ifdef USE_PAM
- pam_handle_t *pamh=NULL;
-
- if (retval == PAM_SUCCESS) {
- log_error_write(srv, __FILE__, __LINE__, "s", "Authenticated");
-- return 0;
++
++#endif
++ } else if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
++ if (buffer_is_equal_string(password, pw, strlen(pw))) {
+ return 0;
- } else {
- log_error_write(srv, __FILE__, __LINE__, "s", "Not Authenticated");
-- }
+ }
-#endif
- } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) {
+ } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) {
return 0;
}
--- ../lighttpd-1.4.11/src/http_auth.h 2005-08-14 17:12:31.000000000 +0300
-+++ lighttpd-1.4.12/src/http_auth.h 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/http_auth.h 2006-07-16 00:26:04.000000000 +0300
@@ -9,22 +9,26 @@
# include <ldap.h>
#endif
} mod_auth_plugin_data;
--- ../lighttpd-1.4.11/src/http_auth_digest.h 2006-01-05 00:54:01.000000000 +0200
-+++ lighttpd-1.4.12/src/http_auth_digest.h 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/http_auth_digest.h 2006-07-16 00:26:04.000000000 +0300
@@ -12,7 +12,7 @@
#ifdef USE_OPENSSL
#define IN const
#define OUT
--- ../lighttpd-1.4.11/src/http_chunk.c 2005-08-11 01:26:50.000000000 +0300
-+++ lighttpd-1.4.12/src/http_chunk.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/http_chunk.c 2006-07-16 00:26:04.000000000 +0300
@@ -1,7 +1,7 @@
/**
* the HTTP chunk-API
return chunkqueue_length(con->write_queue);
}
--- ../lighttpd-1.4.11/src/http_resp.c 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.4.12/src/http_resp.c 2006-07-15 22:43:21.000000000 +0300
-@@ -0,0 +1,274 @@
++++ lighttpd-1.4.12/src/http_resp.c 2006-07-18 13:03:40.000000000 +0300
+@@ -0,0 +1,277 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
++#include "log.h"
+#include "http_resp.h"
+#include "http_resp_parser.h"
+
+ if (context.ok == 0) {
+ ret = PARSE_ERROR;
+
-+ fprintf(stderr, "%s.%d: parsing failed at: ...%20s\r\n",
-+ __FILE__, __LINE__, t.c->mem->ptr + t.offset);
++ if (!buffer_is_empty(context.errmsg)) {
++ TRACE("parsing failed: %s", BUF_STR(context.errmsg));
++ } else {
++ TRACE("%s", "parsing failed ...");
++ }
+ }
+
+ http_resp_parser(pParser, 0, token, &context);
-+ http_resp_parserFree(pParser, free );
++ http_resp_parserFree(pParser, free);
+
+ if (context.ok == 0) {
+ /* we are missing the some tokens */
+
+ if (!buffer_is_empty(context.errmsg)) {
-+ fprintf(stderr, "%s.%d: hmm, %20s\r\n",
-+ __FILE__, __LINE__, context.errmsg->ptr);
++ TRACE("parsing failed: %s", BUF_STR(context.errmsg));
+ }
+
+ if (ret == PARSE_UNSET) {
+}
+
--- ../lighttpd-1.4.11/src/http_resp.h 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.4.12/src/http_resp.h 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/http_resp.h 2006-07-16 00:26:04.000000000 +0300
@@ -0,0 +1,34 @@
+#ifndef _HTTP_RESP_H_
+#define _HTTP_RESP_H_
+
+#endif
--- ../lighttpd-1.4.11/src/http_resp_parser.c 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.4.12/src/http_resp_parser.c 2006-07-15 22:44:07.000000000 +0300
-@@ -0,0 +1,895 @@
++++ lighttpd-1.4.12/src/http_resp_parser.c 2006-07-18 13:03:52.000000000 +0300
+@@ -0,0 +1,901 @@
+/* Driver template for the LEMON parser generator.
+** The author disclaims copyright to this source code.
+*/
+#include "http_resp.h"
+#include "keyvalue.h"
+#include "array.h"
++#include "log.h"
+
-+#line 16 "http_resp_parser.c"
++#line 17 "http_resp_parser.c"
+/* Next is all token values, in a form suitable for use by makeheaders.
+** This section will be null unless lemon is run with the -m switch.
+*/
+ case 1:
+ case 2:
+ case 3:
-+#line 23 "./http_resp_parser.y"
++#line 25 "./http_resp_parser.y"
++{ buffer_free((yypminor->yy0)); }
++#line 327 "http_resp_parser.c"
++ break;
++ case 10:
++#line 24 "./http_resp_parser.y"
+{ buffer_free((yypminor->yy0)); }
-+#line 326 "http_resp_parser.c"
++#line 332 "http_resp_parser.c"
+ break;
+ default: break; /* If no destructor action specified: do nothing */
+ }
+ ** break;
+ */
+ case 0:
-+#line 26 "./http_resp_parser.y"
++#line 28 "./http_resp_parser.y"
+{
+ http_resp *resp = ctx->resp;
+ data_string *ds;
+
+ yymsp[-1].minor.yy12 = NULL;
+}
-+#line 576 "http_resp_parser.c"
++#line 582 "http_resp_parser.c"
+ yy_destructor(1,&yymsp[0].minor);
+ break;
+ case 1:
-+#line 54 "./http_resp_parser.y"
++#line 56 "./http_resp_parser.y"
+{
+ http_resp *resp = ctx->resp;
+
+ resp->status = yymsp[-4].minor.yy20;
+ resp->protocol = yymsp[-5].minor.yy20;
+ buffer_copy_string_buffer(resp->reason, yymsp[-3].minor.yy0);
-+
++ buffer_free(yymsp[-3].minor.yy0);
++
+ array_free(resp->headers);
+
+ resp->headers = yymsp[-1].minor.yy12;
-+
-+ yymsp[-1].minor.yy12 = NULL;
+}
-+#line 594 "http_resp_parser.c"
++#line 599 "http_resp_parser.c"
+ yy_destructor(1,&yymsp[-2].minor);
+ yy_destructor(1,&yymsp[0].minor);
+ break;
+ case 2:
-+#line 68 "./http_resp_parser.y"
++#line 69 "./http_resp_parser.y"
+{
+ if (buffer_is_equal_string(yymsp[0].minor.yy0, CONST_STR_LEN("HTTP/1.0"))) {
+ yygotominor.yy20 = HTTP_VERSION_1_0;
+
+ ctx->ok = 0;
+ }
++ buffer_free(yymsp[0].minor.yy0);
+}
-+#line 612 "http_resp_parser.c"
++#line 618 "http_resp_parser.c"
+ break;
+ case 3:
-+#line 81 "./http_resp_parser.y"
++#line 83 "./http_resp_parser.y"
+{
+ char *err;
+ yygotominor.yy20 = strtol(yymsp[0].minor.yy0->ptr, &err, 10);
+
+ if (*err != '\0') {
-+ buffer_copy_string(ctx->errmsg, "expected a number: ");
++ buffer_copy_string(ctx->errmsg, "expected a number, got: ");
+ buffer_append_string_buffer(ctx->errmsg, yymsp[0].minor.yy0);
+
+ ctx->ok = 0;
+ }
++ buffer_free(yymsp[0].minor.yy0);
+}
-+#line 627 "http_resp_parser.c"
++#line 634 "http_resp_parser.c"
+ break;
+ case 4:
-+#line 93 "./http_resp_parser.y"
++#line 96 "./http_resp_parser.y"
+{
+ yygotominor.yy0 = yymsp[0].minor.yy0;
-+ yymsp[0].minor.yy0 = NULL;
+}
-+#line 635 "http_resp_parser.c"
++#line 641 "http_resp_parser.c"
+ break;
+ case 5:
-+#line 98 "./http_resp_parser.y"
++#line 100 "./http_resp_parser.y"
+{
+ yygotominor.yy0 = yymsp[-1].minor.yy0;
+
+ buffer_append_string(yygotominor.yy0, " ");
+ buffer_append_string_buffer(yygotominor.yy0, yymsp[0].minor.yy0);
-+
-+ yymsp[-1].minor.yy0 = NULL;
++
++ buffer_free(yymsp[0].minor.yy0);
+}
-+#line 647 "http_resp_parser.c"
++#line 653 "http_resp_parser.c"
+ break;
+ case 6:
-+#line 107 "./http_resp_parser.y"
++#line 109 "./http_resp_parser.y"
+{
+ yygotominor.yy12 = yymsp[-1].minor.yy12;
+
+ array_insert_unique(yygotominor.yy12, (data_unset *)yymsp[0].minor.yy9);
-+
-+ yymsp[-1].minor.yy12 = NULL;
+}
-+#line 658 "http_resp_parser.c"
++#line 662 "http_resp_parser.c"
+ break;
+ case 7:
+#line 115 "./http_resp_parser.y"
+
+ array_insert_unique(yygotominor.yy12, (data_unset *)yymsp[0].minor.yy9);
+}
-+#line 667 "http_resp_parser.c"
++#line 671 "http_resp_parser.c"
+ break;
+ case 8:
+#line 120 "./http_resp_parser.y"
+
+ buffer_copy_string_buffer(yygotominor.yy9->key, yymsp[-3].minor.yy0);
+ buffer_copy_string_buffer(yygotominor.yy9->value, yymsp[-1].minor.yy0);
++ buffer_free(yymsp[-3].minor.yy0);
++ buffer_free(yymsp[-1].minor.yy0);
+}
-+#line 677 "http_resp_parser.c"
++#line 683 "http_resp_parser.c"
+ yy_destructor(3,&yymsp[-2].minor);
+ yy_destructor(1,&yymsp[0].minor);
+ break;
+ while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
+ /* Here code is inserted which will be executed whenever the
+ ** parser fails */
-+#line 14 "./http_resp_parser.y"
++#line 15 "./http_resp_parser.y"
+
+ ctx->ok = 0;
+
-+#line 712 "http_resp_parser.c"
++#line 718 "http_resp_parser.c"
+ http_resp_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+}
+
+ return;
+}
--- ../lighttpd-1.4.11/src/http_resp_parser.h 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.4.12/src/http_resp_parser.h 2006-07-15 22:44:07.000000000 +0300
++++ lighttpd-1.4.12/src/http_resp_parser.h 2006-07-18 13:03:52.000000000 +0300
@@ -0,0 +1,3 @@
+#define TK_CRLF 1
+#define TK_STRING 2
+#define TK_COLON 3
--- ../lighttpd-1.4.11/src/http_resp_parser.y 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.4.12/src/http_resp_parser.y 2006-07-15 22:43:21.000000000 +0300
-@@ -0,0 +1,125 @@
++++ lighttpd-1.4.12/src/http_resp_parser.y 2006-07-18 13:03:40.000000000 +0300
+@@ -0,0 +1,127 @@
+%token_prefix TK_
+%token_type {buffer *}
+%extra_argument {http_resp_ctx_t *ctx}
+#include "http_resp.h"
+#include "keyvalue.h"
+#include "array.h"
++#include "log.h"
+}
+
+%parse_failure {
+%type number { int }
+%type headers { array * }
+%type header { data_string * }
++%destructor reason { buffer_free($$); }
+%token_destructor { buffer_free($$); }
+
+/* just headers + Status: ... */
+ resp->status = C;
+ resp->protocol = B;
+ buffer_copy_string_buffer(resp->reason, D);
-+
++ buffer_free(D);
++
+ array_free(resp->headers);
+
+ resp->headers = HDR;
-+
-+ HDR = NULL;
+}
+
+protocol(A) ::= STRING(B). {
+
+ ctx->ok = 0;
+ }
++ buffer_free(B);
+}
+
+number(A) ::= STRING(B). {
+ A = strtol(B->ptr, &err, 10);
+
+ if (*err != '\0') {
-+ buffer_copy_string(ctx->errmsg, "expected a number: ");
++ buffer_copy_string(ctx->errmsg, "expected a number, got: ");
+ buffer_append_string_buffer(ctx->errmsg, B);
+
+ ctx->ok = 0;
+ }
++ buffer_free(B);
+}
+
+reason(A) ::= STRING(B). {
+ A = B;
-+ B = NULL;
+}
+
+reason(A) ::= reason(C) STRING(B). {
+
+ buffer_append_string(A, " ");
+ buffer_append_string_buffer(A, B);
-+
-+ C = NULL;
++
++ buffer_free(B);
+}
+
+headers(HDRS) ::= headers(SRC) header(HDR). {
+ HDRS = SRC;
+
+ array_insert_unique(HDRS, (data_unset *)HDR);
-+
-+ SRC = NULL;
+}
+
+headers(HDRS) ::= header(HDR). {
+
+ buffer_copy_string_buffer(HDR->key, A);
+ buffer_copy_string_buffer(HDR->value, B);
++ buffer_free(A);
++ buffer_free(B);
+}
--- ../lighttpd-1.4.11/src/inet_ntop_cache.c 2005-08-11 01:26:38.000000000 +0300
-+++ lighttpd-1.4.12/src/inet_ntop_cache.c 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/inet_ntop_cache.c 2006-07-16 00:26:04.000000000 +0300
@@ -8,7 +8,7 @@
#include "sys-socket.h"
return srv->inet_ntop_cache[i].b2;
#else
UNUSED(srv);
+--- ../lighttpd-1.4.11/src/iosocket.c 1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/iosocket.c 2006-07-18 13:03:40.000000000 +0300
+@@ -0,0 +1,36 @@
++#include <stdlib.h>
++
++#include "iosocket.h"
++#include "sys-socket.h"
++#include "sys-files.h"
++#include "array-static.h"
++
++iosocket *iosocket_init(void) {
++ STRUCT_INIT(iosocket, sock);
++
++ sock->fde_ndx = -1;
++ sock->fd = -1;
++
++ sock->type = IOSOCKET_TYPE_SOCKET;
++
++ return sock;
++}
++
++void iosocket_free(iosocket *sock) {
++ if (!sock) return;
++
++ if (sock->fd != -1) {
++ switch (sock->type) {
++ case IOSOCKET_TYPE_SOCKET:
++ closesocket(sock->fd);
++ break;
++ case IOSOCKET_TYPE_PIPE:
++ close(sock->fd);
++ break;
++ default:
++ break;
++ }
++ }
++
++ free(sock);
++}
+--- ../lighttpd-1.4.11/src/iosocket.h 1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/iosocket.h 2006-07-18 13:03:40.000000000 +0300
+@@ -0,0 +1,32 @@
++#ifndef _IOSOCKET_H_
++#define _IOSOCKET_H_
++
++#if defined HAVE_LIBSSL && defined HAVE_OPENSSL_SSL_H
++# define USE_OPENSSL
++# include <openssl/ssl.h>
++#endif
++
++typedef enum {
++ IOSOCKET_TYPE_UNSET,
++ IOSOCKET_TYPE_SOCKET,
++ IOSOCKET_TYPE_PIPE
++} iosocket_t;
++
++/**
++ * a non-blocking fd
++ */
++typedef struct {
++ int fd;
++ int fde_ndx;
++
++#ifdef USE_OPENSSL
++ SSL *ssl;
++#endif
++
++ iosocket_t type; /**< sendfile on solaris doesn't work on pipes */
++} iosocket;
++
++iosocket *iosocket_init(void);
++void iosocket_free(iosocket *sock);
++
++#endif
--- ../lighttpd-1.4.11/src/joblist.c 2005-08-11 01:26:41.000000000 +0300
-+++ lighttpd-1.4.12/src/joblist.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/joblist.c 2006-07-16 00:26:03.000000000 +0300
@@ -7,7 +7,7 @@
int joblist_append(server *srv, connection *con) {
}
--- ../lighttpd-1.4.11/src/keyvalue.c 2006-03-02 16:08:06.000000000 +0200
-+++ lighttpd-1.4.12/src/keyvalue.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/keyvalue.c 2006-07-16 00:26:03.000000000 +0300
@@ -87,7 +87,8 @@
{ 504, "Gateway Timeout" },
{ 505, "HTTP Version Not Supported" },
free(kvb);
}
--- ../lighttpd-1.4.11/src/keyvalue.h 2006-03-02 16:08:06.000000000 +0200
-+++ lighttpd-1.4.12/src/keyvalue.h 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/keyvalue.h 2006-07-16 00:26:04.000000000 +0300
@@ -9,19 +9,19 @@
# include <pcre.h>
#endif
httpauth_type type;
} httpauth_keyvalue;
--- ../lighttpd-1.4.11/src/lemon.c 2005-09-01 00:21:34.000000000 +0300
-+++ lighttpd-1.4.12/src/lemon.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/lemon.c 2006-07-16 00:26:03.000000000 +0300
@@ -579,7 +579,7 @@
*/
if( x4a->tbl==0 ){
free(x4a);
--- ../lighttpd-1.4.11/src/lempar.c 2005-08-11 01:26:40.000000000 +0300
-+++ lighttpd-1.4.12/src/lempar.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/lempar.c 2006-07-16 00:26:03.000000000 +0300
@@ -8,10 +8,10 @@
/* Next is all token values, in a form suitable for use by makeheaders.
** This section will be null unless lemon is run with the -m switch.
** This is what we do if the grammar does define ERROR:
**
--- ../lighttpd-1.4.11/src/log.c 2005-11-07 15:01:35.000000000 +0200
-+++ lighttpd-1.4.12/src/log.c 2006-07-15 22:43:21.000000000 +0300
++++ lighttpd-1.4.12/src/log.c 2006-07-18 13:03:40.000000000 +0300
@@ -5,7 +5,6 @@
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_VALGRIND_VALGRIND_H
#include <valgrind/valgrind.h>
#endif
-@@ -31,38 +36,38 @@
+@@ -31,55 +36,114 @@
# define O_LARGEFILE 0
#endif
+ *
*/
- int log_error_open(server *srv) {
+-int log_error_open(server *srv) {
++
++typedef struct {
++ buffer *file;
++ unsigned short use_syslog;
++
++ /* the errorlog */
int fd;
- int close_stderr = 1;
--
+- int close_stderr = 1;
++ enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG } mode;
++ buffer *buf;
++
++ time_t cached_ts;
++ buffer *cached_ts_str;
++} errorlog;
++
++errorlog *myconfig = NULL;
++
++void log_init(void) {
++ /* use syslog */
++ errorlog *err;
++
++ err = calloc(1, sizeof(*err));
+
++ err->fd = -1;
++ err->mode = ERRORLOG_STDERR;
++ err->buf = buffer_init();
++ err->cached_ts_str = buffer_init();
++
++ myconfig = err;
++}
++
++void log_free(void) {
++ errorlog *err = myconfig;
++
++ if (!err) return;
++
++ TRACE("%s", "server stopped");
++
++ switch(err->mode) {
++ case ERRORLOG_FILE:
++ close(err->fd);
++ break;
++ case ERRORLOG_SYSLOG:
++#ifdef HAVE_SYSLOG_H
++ closelog();
++#endif
++ break;
++ case ERRORLOG_STDERR:
++ break;
++ }
++
++ buffer_free(err->buf);
++ buffer_free(err->cached_ts_str);
++ if (err->file) buffer_free(err->file);
++
++ free(err);
++
++ myconfig = NULL;
++}
++
++int log_error_open(buffer *file, int use_syslog) {
++ int fd;
++ int close_stderr = 1;
++
++ errorlog *err = myconfig;
+
#ifdef HAVE_SYSLOG_H
/* perhaps someone wants to use syslog() */
openlog("lighttpd", LOG_CONS | LOG_PID, LOG_DAEMON);
#endif
- srv->errorlog_mode = ERRORLOG_STDERR;
+- srv->errorlog_mode = ERRORLOG_STDERR;
-
-+
- if (srv->srvconf.errorlog_use_syslog) {
- srv->errorlog_mode = ERRORLOG_SYSLOG;
- } else if (!buffer_is_empty(srv->srvconf.errorlog_file)) {
- const char *logfile = srv->srvconf.errorlog_file->ptr;
+- if (srv->srvconf.errorlog_use_syslog) {
+- srv->errorlog_mode = ERRORLOG_SYSLOG;
+- } else if (!buffer_is_empty(srv->srvconf.errorlog_file)) {
+- const char *logfile = srv->srvconf.errorlog_file->ptr;
-
-+
- if (-1 == (srv->errorlog_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
+- if (-1 == (srv->errorlog_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
- log_error_write(srv, __FILE__, __LINE__, "SSSS",
-+ log_error_write(srv, __FILE__, __LINE__, "SSSS",
- "opening errorlog '", logfile,
+- "opening errorlog '", logfile,
++ err->mode = ERRORLOG_STDERR;
++
++ if (use_syslog) {
++ err->mode = ERRORLOG_SYSLOG;
++ } else if (!buffer_is_empty(file)) {
++ if (-1 == (err->fd = open(file->ptr, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
++ log_error_write(NULL, __FILE__, __LINE__, "SBSS",
++ "opening errorlog '", file,
"' failed: ", strerror(errno));
-
+
return -1;
}
#ifdef FD_CLOEXEC
-@@ -71,15 +76,15 @@
+ /* close fd on exec (cgi) */
+- fcntl(srv->errorlog_fd, F_SETFD, FD_CLOEXEC);
++ fcntl(err->fd, F_SETFD, FD_CLOEXEC);
#endif
- srv->errorlog_mode = ERRORLOG_FILE;
+- srv->errorlog_mode = ERRORLOG_FILE;
++ err->mode = ERRORLOG_FILE;
}
-
-+
- log_error_write(srv, __FILE__, __LINE__, "s", "server started");
+- log_error_write(srv, __FILE__, __LINE__, "s", "server started");
-
++
++ TRACE("%s", "server started");
+
#ifdef HAVE_VALGRIND_VALGRIND_H
/* don't close stderr for debugging purposes if run in valgrind */
if (RUNNING_ON_VALGRIND) close_stderr = 0;
#endif
- if (srv->errorlog_mode == ERRORLOG_STDERR) close_stderr = 0;
+- if (srv->errorlog_mode == ERRORLOG_STDERR) close_stderr = 0;
-
++ if (err->mode == ERRORLOG_STDERR) close_stderr = 0;
+
/* move stderr to /dev/null */
if (close_stderr &&
-1 != (fd = open("/dev/null", O_WRONLY))) {
-@@ -90,33 +95,33 @@
+@@ -90,167 +154,202 @@
return 0;
}
+ *
*/
- int log_error_cycle(server *srv) {
+-int log_error_cycle(server *srv) {
++int log_error_cycle(void) {
/* only cycle if we are not in syslog-mode */
-
+- if (srv->errorlog_mode == ERRORLOG_FILE) {
+- const char *logfile = srv->srvconf.errorlog_file->ptr;
+
- if (srv->errorlog_mode == ERRORLOG_FILE) {
- const char *logfile = srv->srvconf.errorlog_file->ptr;
++ errorlog *err = myconfig;
++
++ if (err->mode == ERRORLOG_FILE) {
++ buffer *file = err->file;
/* already check of opening time */
-
+
int new_fd;
-
+- if (-1 == (new_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
+
- if (-1 == (new_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
++ if (-1 == (new_fd = open(file->ptr, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
/* write to old log */
- log_error_write(srv, __FILE__, __LINE__, "SSSSS",
-+ log_error_write(srv, __FILE__, __LINE__, "SSSSS",
- "cycling errorlog '", logfile,
+- "cycling errorlog '", logfile,
++ log_error_write(NULL, __FILE__, __LINE__, "SBSSS",
++ "cycling errorlog '", file,
"' failed: ", strerror(errno),
", falling back to syslog()");
-
-+
- close(srv->errorlog_fd);
- srv->errorlog_fd = -1;
+- close(srv->errorlog_fd);
+- srv->errorlog_fd = -1;
-#ifdef HAVE_SYSLOG_H
+- srv->errorlog_mode = ERRORLOG_SYSLOG;
++
++ close(err->fd);
++ err->fd = -1;
+#ifdef HAVE_SYSLOG_H
- srv->errorlog_mode = ERRORLOG_SYSLOG;
++ err->mode = ERRORLOG_SYSLOG;
#endif
} else {
-@@ -125,15 +130,15 @@
- srv->errorlog_fd = new_fd;
+ /* ok, new log is open, close the old one */
+- close(srv->errorlog_fd);
+- srv->errorlog_fd = new_fd;
++ close(err->fd);
++ err->fd = new_fd;
}
}
-
-+
- log_error_write(srv, __FILE__, __LINE__, "s", "logfiles cycled");
+- log_error_write(srv, __FILE__, __LINE__, "s", "logfiles cycled");
-
-+
- return 0;
- }
+- return 0;
+-}
- int log_error_close(server *srv) {
- log_error_write(srv, __FILE__, __LINE__, "s", "server stopped");
+-int log_error_close(server *srv) {
+- log_error_write(srv, __FILE__, __LINE__, "s", "server stopped");
-
-+
- switch(srv->errorlog_mode) {
- case ERRORLOG_FILE:
- close(srv->errorlog_fd);
-@@ -146,13 +151,13 @@
- case ERRORLOG_STDERR:
- break;
- }
+- switch(srv->errorlog_mode) {
+- case ERRORLOG_FILE:
+- close(srv->errorlog_fd);
+- break;
+- case ERRORLOG_SYSLOG:
+-#ifdef HAVE_SYSLOG_H
+- closelog();
+-#endif
+- break;
+- case ERRORLOG_STDERR:
+- break;
+- }
-
++ TRACE("%s", "logfiles cycled");
+
return 0;
}
- int log_error_write(server *srv, const char *filename, unsigned int line, const char *fmt, ...) {
+-int log_error_write(server *srv, const char *filename, unsigned int line, const char *fmt, ...) {
++int log_error_write(void *srv, const char *filename, unsigned int line, const char *fmt, ...) {
va_list ap;
-
+- switch(srv->errorlog_mode) {
++ time_t t;
++
++ errorlog *err = myconfig;
+
- switch(srv->errorlog_mode) {
++ switch(err->mode) {
case ERRORLOG_FILE:
case ERRORLOG_STDERR:
-@@ -161,7 +166,7 @@
- buffer_prepare_copy(srv->ts_debug_str, 255);
- strftime(srv->ts_debug_str->ptr, srv->ts_debug_str->size - 1, "%Y-%m-%d %H:%M:%S", localtime(&(srv->cur_ts)));
- srv->ts_debug_str->used = strlen(srv->ts_debug_str->ptr) + 1;
+ /* cache the generated timestamp */
+- if (srv->cur_ts != srv->last_generated_debug_ts) {
+- buffer_prepare_copy(srv->ts_debug_str, 255);
+- strftime(srv->ts_debug_str->ptr, srv->ts_debug_str->size - 1, "%Y-%m-%d %H:%M:%S", localtime(&(srv->cur_ts)));
+- srv->ts_debug_str->used = strlen(srv->ts_debug_str->ptr) + 1;
-
-+
- srv->last_generated_debug_ts = srv->cur_ts;
+- srv->last_generated_debug_ts = srv->cur_ts;
++ t = time(NULL);
++
++ if (t != err->cached_ts) {
++ buffer_prepare_copy(err->cached_ts_str, 255);
++ strftime(err->cached_ts_str->ptr, err->cached_ts_str->size - 1, "%Y-%m-%d %H:%M:%S", localtime(&(t)));
++ err->cached_ts_str->used = strlen(err->cached_ts_str->ptr) + 1;
++ err->cached_ts = t;
}
-@@ -173,19 +178,19 @@
- BUFFER_COPY_STRING_CONST(srv->errorlog_buf, "(");
+- buffer_copy_string_buffer(srv->errorlog_buf, srv->ts_debug_str);
+- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ": (");
++ buffer_copy_string_buffer(err->buf, err->cached_ts_str);
++ BUFFER_APPEND_STRING_CONST(err->buf, ": (");
+ break;
+ case ERRORLOG_SYSLOG:
+ /* syslog is generating its own timestamps */
+- BUFFER_COPY_STRING_CONST(srv->errorlog_buf, "(");
++ BUFFER_COPY_STRING_CONST(err->buf, "(");
break;
}
-
-+
- buffer_append_string(srv->errorlog_buf, filename);
- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ".");
- buffer_append_long(srv->errorlog_buf, line);
- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ") ");
+- buffer_append_string(srv->errorlog_buf, filename);
+- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ".");
+- buffer_append_long(srv->errorlog_buf, line);
+- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ") ");
-
-
+
++ buffer_append_string(err->buf, filename);
++ BUFFER_APPEND_STRING_CONST(err->buf, ".");
++ buffer_append_long(err->buf, line);
++ BUFFER_APPEND_STRING_CONST(err->buf, ") ");
+
for(va_start(ap, fmt); *fmt; fmt++) {
int d;
switch(*fmt) {
case 's': /* string */
s = va_arg(ap, char *);
-@@ -227,7 +232,7 @@
+- buffer_append_string(srv->errorlog_buf, s);
+- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " ");
++ buffer_append_string(err->buf, s);
++ BUFFER_APPEND_STRING_CONST(err->buf, " ");
+ break;
+ case 'b': /* buffer */
+ b = va_arg(ap, buffer *);
+- buffer_append_string_buffer(srv->errorlog_buf, b);
+- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " ");
++ buffer_append_string_buffer(err->buf, b);
++ BUFFER_APPEND_STRING_CONST(err->buf, " ");
+ break;
+ case 'd': /* int */
+ d = va_arg(ap, int);
+- buffer_append_long(srv->errorlog_buf, d);
+- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " ");
++ buffer_append_long(err->buf, d);
++ BUFFER_APPEND_STRING_CONST(err->buf, " ");
+ break;
+ case 'o': /* off_t */
+ o = va_arg(ap, off_t);
+- buffer_append_off_t(srv->errorlog_buf, o);
+- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " ");
++ buffer_append_off_t(err->buf, o);
++ BUFFER_APPEND_STRING_CONST(err->buf, " ");
+ break;
+ case 'x': /* int (hex) */
+ d = va_arg(ap, int);
+- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "0x");
+- buffer_append_long_hex(srv->errorlog_buf, d);
+- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, " ");
++ BUFFER_APPEND_STRING_CONST(err->buf, "0x");
++ buffer_append_long_hex(err->buf, d);
++ BUFFER_APPEND_STRING_CONST(err->buf, " ");
+ break;
+ case 'S': /* string */
+ s = va_arg(ap, char *);
+- buffer_append_string(srv->errorlog_buf, s);
++ buffer_append_string(err->buf, s);
+ break;
+ case 'B': /* buffer */
+ b = va_arg(ap, buffer *);
+- buffer_append_string_buffer(srv->errorlog_buf, b);
++ buffer_append_string_buffer(err->buf, b);
+ break;
+ case 'D': /* int */
+ d = va_arg(ap, int);
+- buffer_append_long(srv->errorlog_buf, d);
++ buffer_append_long(err->buf, d);
break;
case '(':
case ')':
case '>':
case ',':
case ' ':
-@@ -236,7 +241,7 @@
+- buffer_append_string_len(srv->errorlog_buf, fmt, 1);
++ buffer_append_string_len(err->buf, fmt, 1);
+ break;
}
}
va_end(ap);
-
+- switch(srv->errorlog_mode) {
+
- switch(srv->errorlog_mode) {
++ switch(err->mode) {
case ERRORLOG_FILE:
- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n");
-@@ -246,11 +251,13 @@
- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n");
- write(STDERR_FILENO, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1);
+- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n");
+- write(srv->errorlog_fd, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1);
++ BUFFER_APPEND_STRING_CONST(err->buf, "\n");
++ write(err->fd, err->buf->ptr, err->buf->used - 1);
+ break;
+ case ERRORLOG_STDERR:
+- BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n");
+- write(STDERR_FILENO, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1);
++ BUFFER_APPEND_STRING_CONST(err->buf, "\n");
++ write(STDERR_FILENO, err->buf->ptr, err->buf->used - 1);
break;
++#ifdef HAVE_SYSLOG_H
++ case ERRORLOG_SYSLOG:
++ syslog(LOG_ERR, "%s", err->buf->ptr);
++ break;
++#endif
++ }
++
++ return 0;
++}
++
++static int log_trace_write(const char *fmt, va_list ap) {
++ buffer *b;
++ int l;
++ errorlog *err = myconfig;
++
++ b = buffer_init();
++ buffer_prepare_copy(b, 1024);
++ l = vsnprintf(b->ptr, b->size - 1, fmt, ap);
++ if (l > 0) {
++ b->used = (l > b->size - 1) ? b->size : l + 1;
++ }
++
++ /* write b */
++ switch(err->mode) {
++ case ERRORLOG_FILE:
++ buffer_append_string(b, "\r\n");
++ write(err->fd, b->ptr, b->used - 1);
++ break;
++ case ERRORLOG_STDERR:
++ buffer_append_string(b, "\r\n");
++ write(STDERR_FILENO, b->ptr, b->used - 1);
++ break;
+#ifdef HAVE_SYSLOG_H
case ERRORLOG_SYSLOG:
- syslog(LOG_ERR, "%s", srv->errorlog_buf->ptr);
+- syslog(LOG_ERR, "%s", srv->errorlog_buf->ptr);
++ syslog(LOG_ERR, "%s", b->ptr);
break;
+#endif
}
--
+
++ buffer_free(b);
++
++ return 0;
++}
++
++int log_trace(const char *fmt, ...) {
++ va_list ap;
++
++ va_start(ap, fmt);
++
++ log_trace_write(fmt, ap);
++
++ va_end(ap);
+
return 0;
}
++
--- ../lighttpd-1.4.11/src/log.h 2005-08-11 01:26:36.000000000 +0300
-+++ lighttpd-1.4.12/src/log.h 2006-07-11 22:07:53.000000000 +0300
-@@ -9,5 +9,5 @@
- int log_error_close(server *srv);
- int log_error_write(server *srv, const char *filename, unsigned int line, const char *fmt, ...);
- int log_error_cycle(server *srv);
++++ lighttpd-1.4.12/src/log.h 2006-07-18 13:03:40.000000000 +0300
+@@ -1,13 +1,22 @@
+ #ifndef _LOG_H_
+ #define _LOG_H_
+
+-#include "server.h"
++#include "buffer.h"
+
+-#define WP() log_error_write(srv, __FILE__, __LINE__, "");
++void log_init(void);
++void log_free(void);
+
+-int log_error_open(server *srv);
+-int log_error_close(server *srv);
+-int log_error_write(server *srv, const char *filename, unsigned int line, const char *fmt, ...);
+-int log_error_cycle(server *srv);
-
++int log_error_open(buffer *file, int use_syslog);
++int log_error_close();
++int log_error_write(void *srv, const char *filename, unsigned int line, const char *fmt, ...);
++int log_error_cycle();
++
++#define ERROR(fmt, ...) \
++ log_trace("%s.%d: (error) "fmt, __FILE__, __LINE__, __VA_ARGS__)
++
++#define TRACE(fmt, ...) \
++ log_trace("%s.%d: (trace) "fmt, __FILE__, __LINE__, __VA_ARGS__)
+
++#define SEGFAULT() do { ERROR("%s", "Ooh, Ooh, Ooh. Something is not good ... going down"); abort(); } while(0)
++int log_trace(const char *fmt, ...);
#endif
--- ../lighttpd-1.4.11/src/md5.h 2005-11-17 16:20:40.000000000 +0200
-+++ lighttpd-1.4.12/src/md5.h 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/md5.h 2006-07-16 00:26:04.000000000 +0300
@@ -30,9 +30,15 @@
# include <inttypes.h>
#endif
/* MD5 context. */
typedef struct {
--- ../lighttpd-1.4.11/src/mod_access.c 2006-01-14 19:44:54.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_access.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/mod_access.c 2006-07-16 00:26:04.000000000 +0300
@@ -8,126 +8,125 @@
#include "plugin.h"
return 0;
}
--- ../lighttpd-1.4.11/src/mod_accesslog.c 2006-01-31 14:01:43.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_accesslog.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/mod_accesslog.c 2006-07-16 00:26:04.000000000 +0300
@@ -6,8 +6,7 @@
#include <ctype.h>
#include <stdlib.h>
return 0;
}
--- ../lighttpd-1.4.11/src/mod_alias.c 2006-03-01 23:18:51.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_alias.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/mod_alias.c 2006-07-16 00:26:03.000000000 +0300
@@ -8,6 +8,7 @@
#include "buffer.h"
return 0;
}
--- ../lighttpd-1.4.11/src/mod_auth.c 2006-02-15 20:01:31.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_auth.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/mod_auth.c 2006-07-18 13:03:40.000000000 +0300
@@ -5,168 +5,167 @@
#include <string.h>
#include <errno.h>
/* search auth-directives for path */
for (k = 0; k < p->conf.auth_require->used; k++) {
buffer *req = p->conf.auth_require->data[k]->key;
-@@ -212,31 +211,31 @@
+@@ -212,76 +211,76 @@
}
}
}
if ((auth_type_len == 5) &&
(0 == strncmp(http_authorization, "Basic", auth_type_len))) {
-
+- if (0 == strcmp(method->value->ptr, "basic")) {
+
- if (0 == strcmp(method->value->ptr, "basic")) {
++ if (buffer_is_equal_string(method->value, CONST_STR_LEN("basic"))) {
auth_satisfied = http_auth_basic_check(srv, con, p, req, con->uri.path, auth_realm+1);
}
-@@ -245,43 +244,43 @@
- if (0 == strcmp(method->value->ptr, "digest")) {
+ } else if ((auth_type_len == 6) &&
+ (0 == strncmp(http_authorization, "Digest", auth_type_len))) {
+- if (0 == strcmp(method->value->ptr, "digest")) {
++ if (buffer_is_equal_string(method->value, CONST_STR_LEN("digest"))) {
if (-1 == (auth_satisfied = http_auth_digest_check(srv, con, p, req, con->uri.path, auth_realm+1))) {
con->http_status = 400;
-
+
con->http_status = 401;
-
+- if (0 == strcmp(method->value->ptr, "basic")) {
+
- if (0 == strcmp(method->value->ptr, "basic")) {
++ if (buffer_is_equal_string(method->value, CONST_STR_LEN("basic"))) {
buffer_copy_string(p->tmp_buf, "Basic realm=\"");
buffer_append_string_buffer(p->tmp_buf, realm->value);
buffer_append_string(p->tmp_buf, "\"");
-
+
response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(p->tmp_buf));
- } else if (0 == strcmp(method->value->ptr, "digest")) {
+- } else if (0 == strcmp(method->value->ptr, "digest")) {
++ } else if (buffer_is_equal_string(method->value, CONST_STR_LEN("digest"))) {
char hh[33];
http_auth_digest_generate_nonce(srv, p, srv->tmp_buf, hh);
-
cv[0].destination = s->auth_backend_conf;
cv[1].destination = s->auth_plain_groupfile;
cv[2].destination = s->auth_plain_userfile;
-@@ -364,14 +363,14 @@
+@@ -364,146 +363,148 @@
cv[11].destination = s->auth_htdigest_userfile;
cv[12].destination = s->auth_htpasswd_userfile;
cv[13].destination = &(s->auth_debug);
return HANDLER_ERROR;
}
-
+- if (s->auth_backend_conf->used) {
+- if (0 == strcmp(s->auth_backend_conf->ptr, "htpasswd")) {
+
- if (s->auth_backend_conf->used) {
- if (0 == strcmp(s->auth_backend_conf->ptr, "htpasswd")) {
++ if (!buffer_is_empty(s->auth_backend_conf)) {
++ if (buffer_is_equal_string(s->auth_backend_conf, CONST_STR_LEN("htpasswd"))) {
s->auth_backend = AUTH_BACKEND_HTPASSWD;
-@@ -383,31 +382,31 @@
+- } else if (0 == strcmp(s->auth_backend_conf->ptr, "htdigest")) {
++ } else if (buffer_is_equal_string(s->auth_backend_conf, CONST_STR_LEN("htdigest"))) {
+ s->auth_backend = AUTH_BACKEND_HTDIGEST;
+- } else if (0 == strcmp(s->auth_backend_conf->ptr, "plain")) {
++ } else if (buffer_is_equal_string(s->auth_backend_conf, CONST_STR_LEN("plain"))) {
+ s->auth_backend = AUTH_BACKEND_PLAIN;
+- } else if (0 == strcmp(s->auth_backend_conf->ptr, "ldap")) {
++ } else if (buffer_is_equal_string(s->auth_backend_conf, CONST_STR_LEN("ldap"))) {
s->auth_backend = AUTH_BACKEND_LDAP;
} else {
log_error_write(srv, __FILE__, __LINE__, "sb", "auth.backend not supported:", s->auth_backend_conf);
for (n = 0; n < da->value->used; n++) {
size_t m;
data_array *da_file = (data_array *)da->value->data[n];
- const char *method, *realm, *require;
+- const char *method, *realm, *require;
-
++ buffer *method, *realm, *require;
+
if (da->value->data[n]->type != TYPE_ARRAY) {
- log_error_write(srv, __FILE__, __LINE__, "ss",
-
+
for (m = 0; m < da_file->value->used; m++) {
- if (da_file->value->data[m]->type == TYPE_STRING) {
- if (0 == strcmp(da_file->value->data[m]->key->ptr, "method")) {
-@@ -417,8 +416,8 @@
- } else if (0 == strcmp(da_file->value->data[m]->key->ptr, "require")) {
- require = ((data_string *)(da_file->value->data[m]))->value->ptr;
- } else {
+- if (da_file->value->data[m]->type == TYPE_STRING) {
+- if (0 == strcmp(da_file->value->data[m]->key->ptr, "method")) {
+- method = ((data_string *)(da_file->value->data[m]))->value->ptr;
+- } else if (0 == strcmp(da_file->value->data[m]->key->ptr, "realm")) {
+- realm = ((data_string *)(da_file->value->data[m]))->value->ptr;
+- } else if (0 == strcmp(da_file->value->data[m]->key->ptr, "require")) {
+- require = ((data_string *)(da_file->value->data[m]))->value->ptr;
+- } else {
- log_error_write(srv, __FILE__, __LINE__, "ssbs",
- "the field is unknown in:",
-+ log_error_write(srv, __FILE__, __LINE__, "ssbs",
++ data_string *ds_auth_req = (data_string *)da_file->value->data[m];
++
++ if (ds_auth_req->type != TYPE_STRING) {
++ log_error_write(srv, __FILE__, __LINE__, "ssbs",
++ "a string was expected for:",
++ "auth.require = ( \"...\" => ( ..., -> \"",
++ ds_auth_req->key,
++ "\" <- => \"...\" ) )");
++
++ return HANDLER_ERROR;
++ }
++
++ if (buffer_is_equal_string(ds_auth_req->key, CONST_STR_LEN("method"))) {
++ method = ds_auth_req->value;
++ } else if (buffer_is_equal_string(ds_auth_req->key, CONST_STR_LEN("realm"))) {
++ realm = ds_auth_req->value;
++ } else if (buffer_is_equal_string(ds_auth_req->key, CONST_STR_LEN("require"))) {
++ require = ds_auth_req->value;
++ } else {
++ log_error_write(srv, __FILE__, __LINE__, "ssbs",
+ "the field is unknown in:",
"auth.require = ( \"...\" => ( ..., -> \"",
da_file->value->data[m]->key,
"\" <- => \"...\" ) )");
-@@ -426,19 +425,19 @@
- return HANDLER_ERROR;
- }
- } else {
+
+- return HANDLER_ERROR;
+- }
+- } else {
- log_error_write(srv, __FILE__, __LINE__, "ssbs",
- "a string was expected for:",
-+ log_error_write(srv, __FILE__, __LINE__, "ssbs",
-+ "a string was expected for:",
- "auth.require = ( \"...\" => ( ..., -> \"",
- da_file->value->data[m]->key,
- "\" <- => \"...\" ) )");
+- "auth.require = ( \"...\" => ( ..., -> \"",
+- da_file->value->data[m]->key,
+- "\" <- => \"...\" ) )");
-
-+
return HANDLER_ERROR;
++
}
}
-
+ "the require field is missing in:",
"auth.require = ( \"...\" => ( ..., \"method\" => \"...\" ) )");
return HANDLER_ERROR;
- } else {
-@@ -450,60 +449,60 @@
- return HANDLER_ERROR;
- }
+- } else {
+- if (0 != strcmp(method, "basic") &&
+- 0 != strcmp(method, "digest")) {
+- log_error_write(srv, __FILE__, __LINE__, "ss",
+- "method has to be either \"basic\" or \"digest\" in",
+- "auth.require = ( \"...\" => ( ..., \"method\" => \"...\") )");
+- return HANDLER_ERROR;
+- }
++ }
++ if (!buffer_is_equal_string(method, CONST_STR_LEN("basic")) &&
++ !buffer_is_equal_string(method, CONST_STR_LEN("digest"))) {
++ log_error_write(srv, __FILE__, __LINE__, "ss",
++ "method has to be either \"basic\" or \"digest\" in",
++ "auth.require = ( \"...\" => ( ..., \"method\" => \"...\") )");
++ return HANDLER_ERROR;
}
-
+
-
+
buffer_copy_string(ds->key, "method");
- buffer_copy_string(ds->value, method);
+- buffer_copy_string(ds->value, method);
-
++ buffer_copy_string_buffer(ds->value, method);
+
array_insert_unique(a->value, (data_unset *)ds);
-
-
+
buffer_copy_string(ds->key, "realm");
- buffer_copy_string(ds->value, realm);
+- buffer_copy_string(ds->value, realm);
-
++ buffer_copy_string_buffer(ds->value, realm);
+
array_insert_unique(a->value, (data_unset *)ds);
-
-
+
buffer_copy_string(ds->key, "require");
- buffer_copy_string(ds->value, require);
+- buffer_copy_string(ds->value, require);
-
++ buffer_copy_string_buffer(ds->value, require);
+
array_insert_unique(a->value, (data_unset *)ds);
-
"opening auth.backend.plain.userfile:", s->auth_plain_userfile,
"failed:", strerror(errno));
return HANDLER_ERROR;
-@@ -516,7 +515,7 @@
+@@ -516,7 +517,7 @@
int fd;
/* try to read */
if (-1 == (fd = open(s->auth_htpasswd_userfile->ptr, O_RDONLY))) {
"opening auth.backend.htpasswd.userfile:", s->auth_htpasswd_userfile,
"failed:", strerror(errno));
return HANDLER_ERROR;
-@@ -529,7 +528,7 @@
+@@ -529,7 +530,7 @@
int fd;
/* try to read */
if (-1 == (fd = open(s->auth_htdigest_userfile->ptr, O_RDONLY))) {
"opening auth.backend.htdigest.userfile:", s->auth_htdigest_userfile,
"failed:", strerror(errno));
return HANDLER_ERROR;
-@@ -554,75 +553,75 @@
+@@ -554,75 +555,75 @@
handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) {
#ifdef USE_LDAP
int ret;
return HANDLER_ERROR;
}
}
-@@ -641,8 +640,8 @@
+@@ -641,8 +642,8 @@
p->set_defaults = mod_auth_set_defaults;
p->handle_uri_clean = mod_auth_uri_handler;
p->cleanup = mod_auth_free;
return 0;
}
--- ../lighttpd-1.4.11/src/mod_cgi.c 2006-02-22 15:15:10.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_cgi.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/mod_cgi.c 2006-07-18 13:03:40.000000000 +0300
@@ -1,21 +1,8 @@
#include <sys/types.h>
-#ifdef __WIN32
#include <signal.h>
#include <ctype.h>
#include <assert.h>
-@@ -29,9 +16,16 @@
+@@ -29,8 +16,16 @@
#include "connections.h"
#include "joblist.h"
#include "http_chunk.h"
+#include "fdevent.h"
#include "plugin.h"
-
++#include "http_resp.h"
++
+#include "sys-files.h"
+#include "sys-mmap.h"
+#include "sys-socket.h"
+#include "sys-strings.h"
+#include "sys-process.h"
-+
+
#ifdef HAVE_SYS_FILIO_H
# include <sys/filio.h>
- #endif
-@@ -40,11 +34,12 @@
+@@ -40,11 +35,12 @@
typedef struct {
char **ptr;
typedef struct {
pid_t *ptr;
size_t used;
-@@ -58,23 +53,23 @@
+@@ -58,57 +54,68 @@
typedef struct {
PLUGIN_DATA;
buffer_pid_t cgi_pid;
-
+
buffer *tmp_buf;
- buffer *parse_response;
+- buffer *parse_response;
-
++
++ http_resp *resp;
+
plugin_config **config_storage;
-
+ plugin_config conf;
} plugin_data;
++typedef enum {
++ CGI_STATE_UNSET,
++ CGI_STATE_CONNECTING,
++ CGI_STATE_READ_RESPONSE_HEADER,
++ CGI_STATE_READ_RESPONSE_CONTENT
++} cgi_state_t;
++
typedef struct {
pid_t pid;
- int fd;
- int fde_ndx; /* index into the fd-event buffer */
+- int fd;
+- int fde_ndx; /* index into the fd-event buffer */
-
-+
- connection *remote_conn; /* dumb pointer */
- plugin_data *plugin_data; /* dumb pointer */
+- connection *remote_conn; /* dumb pointer */
+- plugin_data *plugin_data; /* dumb pointer */
-
-+
- buffer *response;
- buffer *response_header;
- } handler_ctx;
-@@ -83,17 +78,17 @@
- handler_ctx *hctx = calloc(1, sizeof(*hctx));
+- buffer *response;
+- buffer *response_header;
+-} handler_ctx;
- assert(hctx);
+-static handler_ctx * cgi_handler_ctx_init() {
+- handler_ctx *hctx = calloc(1, sizeof(*hctx));
++ iosocket *sock;
+
+- assert(hctx);
-
-+
- hctx->response = buffer_init();
- hctx->response_header = buffer_init();
+- hctx->response = buffer_init();
+- hctx->response_header = buffer_init();
-
-+
- return hctx;
- }
+- return hctx;
+-}
++ chunkqueue *rb;
++ chunkqueue *wb;
- static void cgi_handler_ctx_free(handler_ctx *hctx) {
- buffer_free(hctx->response);
- buffer_free(hctx->response_header);
+-static void cgi_handler_ctx_free(handler_ctx *hctx) {
+- buffer_free(hctx->response);
+- buffer_free(hctx->response_header);
-
+- free(hctx);
++ cgi_state_t state;
+
- free(hctx);
++ connection *remote_con; /* dumb pointer */
++} cgi_session;
++
++static cgi_session * cgi_session_init() {
++ cgi_session *sess = calloc(1, sizeof(*sess));
++ assert(sess);
++
++ sess->sock = iosocket_init();
++ sess->wb = chunkqueue_init();
++ sess->rb = chunkqueue_init();
++
++ return sess;
}
-@@ -101,14 +96,14 @@
+-enum {FDEVENT_HANDLED_UNSET, FDEVENT_HANDLED_FINISHED, FDEVENT_HANDLED_NOT_FINISHED, FDEVENT_HANDLED_ERROR};
++static void cgi_session_free(cgi_session *sess) {
++ if (!sess) return;
++
++ iosocket_free(sess->sock);
++
++ chunkqueue_free(sess->wb);
++ chunkqueue_free(sess->rb);
++
++ free(sess);
++}
INIT_FUNC(mod_cgi_init) {
plugin_data *p;
-
+
p->tmp_buf = buffer_init();
- p->parse_response = buffer_init();
+- p->parse_response = buffer_init();
-
++ p->resp = http_response_init();
+
return p;
}
-@@ -116,62 +111,62 @@
+@@ -116,62 +123,62 @@
FREE_FUNC(mod_cgi_free) {
plugin_data *p = p_d;
buffer_pid_t *r = &(p->cgi_pid);
-
+
buffer_free(p->tmp_buf);
- buffer_free(p->parse_response);
+- buffer_free(p->parse_response);
-
++ http_response_free(p->resp);
+
free(p);
-
return HANDLER_GO_ON;
}
-@@ -180,13 +175,13 @@
+@@ -180,13 +187,13 @@
int m = -1;
size_t i;
buffer_pid_t *r = &(p->cgi_pid);
if (r->size == 0) {
r->size = 16;
r->ptr = malloc(sizeof(*r->ptr) * r->size);
-@@ -194,31 +189,31 @@
+@@ -194,321 +201,178 @@
r->size += 16;
r->ptr = realloc(r->ptr, sizeof(*r->ptr) * r->size);
}
return 0;
}
-@@ -226,32 +221,32 @@
- char *ns;
- const char *s;
- int line = 0;
+-static int cgi_response_parse(server *srv, connection *con, plugin_data *p, buffer *in, int eol) {
+- char *ns;
+- const char *s;
+- int line = 0;
-
-+
- UNUSED(srv);
+- UNUSED(srv);
-
-+
- buffer_copy_string_buffer(p->parse_response, in);
+- buffer_copy_string_buffer(p->parse_response, in);
-
- for (s = p->parse_response->ptr;
- NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n')));
-+
-+ for (s = p->parse_response->ptr;
-+ NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n')));
- s = ns + (eol == EOL_RN ? 2 : 1), line++) {
- const char *key, *value;
- int key_len;
- data_string *ds;
+- s = ns + (eol == EOL_RN ? 2 : 1), line++) {
+- const char *key, *value;
+- int key_len;
+- data_string *ds;
-
-+
- ns[0] = '\0';
+- ns[0] = '\0';
-
- if (line == 0 &&
-+
-+ if (line == 0 &&
- 0 == strncmp(s, "HTTP/1.", 7)) {
- /* non-parsed header ... we parse them anyway */
--
-+
- if ((s[7] == '1' ||
- s[7] == '0') &&
- s[8] == ' ') {
- int status;
- /* after the space should be a status code for us */
--
-+
- status = strtol(s+9, NULL, 10);
--
-+
- if (con->http_status >= 100 &&
- con->http_status < 1000) {
- /* we expected 3 digits and didn't got them */
-@@ -260,27 +255,27 @@
- }
- }
- } else {
+- 0 == strncmp(s, "HTTP/1.", 7)) {
+- /* non-parsed header ... we parse them anyway */
+-
+- if ((s[7] == '1' ||
+- s[7] == '0') &&
+- s[8] == ' ') {
+- int status;
+- /* after the space should be a status code for us */
+-
+- status = strtol(s+9, NULL, 10);
+-
+- if (con->http_status >= 100 &&
+- con->http_status < 1000) {
+- /* we expected 3 digits and didn't got them */
+- con->parsed_response |= HTTP_STATUS;
+- con->http_status = status;
+- }
+- }
+- } else {
-
-+
- key = s;
- if (NULL == (value = strchr(s, ':'))) {
- /* we expect: "<key>: <value>\r\n" */
- continue;
- }
+- key = s;
+- if (NULL == (value = strchr(s, ':'))) {
+- /* we expect: "<key>: <value>\r\n" */
+- continue;
+- }
-
-+
- key_len = value - key;
- value += 1;
+- key_len = value - key;
+- value += 1;
-
-+
- /* skip LWS */
- while (*value == ' ' || *value == '\t') value++;
+- /* skip LWS */
+- while (*value == ' ' || *value == '\t') value++;
-
-+
- if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
- ds = data_response_init();
- }
- buffer_copy_string_len(ds->key, key, key_len);
- buffer_copy_string(ds->value, value);
+- if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
+- ds = data_response_init();
+- }
+- buffer_copy_string_len(ds->key, key, key_len);
+- buffer_copy_string(ds->value, value);
-
-+
- array_insert_unique(con->response.headers, (data_unset *)ds);
+- array_insert_unique(con->response.headers, (data_unset *)ds);
-
-+
- switch(key_len) {
- case 4:
- if (0 == strncasecmp(key, "Date", key_len)) {
-@@ -315,13 +310,13 @@
- }
- }
- }
+- switch(key_len) {
+- case 4:
+- if (0 == strncasecmp(key, "Date", key_len)) {
+- con->parsed_response |= HTTP_DATE;
+- }
+- break;
+- case 6:
+- if (0 == strncasecmp(key, "Status", key_len)) {
+- con->http_status = strtol(value, NULL, 10);
+- con->parsed_response |= HTTP_STATUS;
+- }
+- break;
+- case 8:
+- if (0 == strncasecmp(key, "Location", key_len)) {
+- con->parsed_response |= HTTP_LOCATION;
+- }
+- break;
+- case 10:
+- if (0 == strncasecmp(key, "Connection", key_len)) {
+- con->response.keep_alive = (0 == strcasecmp(value, "Keep-Alive")) ? 1 : 0;
+- con->parsed_response |= HTTP_CONNECTION;
+- }
+- break;
+- case 14:
+- if (0 == strncasecmp(key, "Content-Length", key_len)) {
+- con->response.content_length = strtol(value, NULL, 10);
+- con->parsed_response |= HTTP_CONTENT_LENGTH;
+- }
+- break;
+- default:
+- break;
+- }
+- }
+- }
-
+- /* CGI/1.1 rev 03 - 7.2.1.2 */
+- if ((con->parsed_response & HTTP_LOCATION) &&
+- !(con->parsed_response & HTTP_STATUS)) {
+- con->http_status = 302;
++static int cgi_demux_response(server *srv, connection *con, plugin_data *p) {
++ cgi_session *sess = con->plugin_ctx[p->id];
++ chunk *c = NULL;
+
- /* CGI/1.1 rev 03 - 7.2.1.2 */
- if ((con->parsed_response & HTTP_LOCATION) &&
- !(con->parsed_response & HTTP_STATUS)) {
- con->http_status = 302;
++ switch(srv->network_backend_read(srv, con, sess->sock, sess->rb)) {
++ case NETWORK_STATUS_SUCCESS:
++ /* we got content */
++ break;
++ case NETWORK_STATUS_WAIT_FOR_EVENT:
++ return 0;
++ case NETWORK_STATUS_CONNECTION_CLOSE:
++ /* this is a bit too early */
++ ERROR("%s", "cgi-connection got closed before we read the response-header (CGI died ?)");
++ return -1;
++ default:
++ /* oops */
++ ERROR("%s", "oops, read-pipe-read failed and I don't know why");
++ return -1;
}
-
-+
- return 0;
- }
+- return 0;
+-}
-@@ -329,10 +324,10 @@
- static int cgi_demux_response(server *srv, handler_ctx *hctx) {
- plugin_data *p = hctx->plugin_data;
- connection *con = hctx->remote_conn;
++ /* looks like we got some content
++ *
++ * split off the header from the incoming stream
++ */
+
+-static int cgi_demux_response(server *srv, handler_ctx *hctx) {
+- plugin_data *p = hctx->plugin_data;
+- connection *con = hctx->remote_conn;
-
-+
- while(1) {
- int n;
+- while(1) {
+- int n;
-
-+
- buffer_prepare_copy(hctx->response, 1024);
- if (-1 == (n = read(hctx->fd, hctx->response->ptr, hctx->response->size - 1))) {
- if (errno == EAGAIN || errno == EINTR) {
-@@ -343,125 +338,125 @@
- log_error_write(srv, __FILE__, __LINE__, "sdd", strerror(errno), con->fd, hctx->fd);
- return FDEVENT_HANDLED_ERROR;
- }
+- buffer_prepare_copy(hctx->response, 1024);
+- if (-1 == (n = read(hctx->fd, hctx->response->ptr, hctx->response->size - 1))) {
+- if (errno == EAGAIN || errno == EINTR) {
+- /* would block, wait for signal */
+- return FDEVENT_HANDLED_NOT_FINISHED;
+- }
+- /* error */
+- log_error_write(srv, __FILE__, __LINE__, "sdd", strerror(errno), con->fd, hctx->fd);
+- return FDEVENT_HANDLED_ERROR;
+- }
-
-+
- if (n == 0) {
- /* read finished */
+- if (n == 0) {
+- /* read finished */
-
-+
- con->file_finished = 1;
+- con->file_finished = 1;
-
-+
- /* send final chunk */
- http_chunk_append_mem(srv, con, NULL, 0);
- joblist_append(srv, con);
+- /* send final chunk */
+- http_chunk_append_mem(srv, con, NULL, 0);
+- joblist_append(srv, con);
-
-+
- return FDEVENT_HANDLED_FINISHED;
- }
+- return FDEVENT_HANDLED_FINISHED;
+- }
-
-+
- hctx->response->ptr[n] = '\0';
- hctx->response->used = n+1;
+- hctx->response->ptr[n] = '\0';
+- hctx->response->used = n+1;
-
-+
- /* split header from body */
+- /* split header from body */
-
-+
- if (con->file_started == 0) {
- char *c;
- int in_header = 0;
- int header_end = 0;
- int cp, eol = EOL_UNSET;
- size_t used = 0;
--
-+
- buffer_append_string_buffer(hctx->response_header, hctx->response);
--
-+
- /* nph (non-parsed headers) */
- if (0 == strncmp(hctx->response_header->ptr, "HTTP/1.", 7)) in_header = 1;
--
-+
- /* search for the \r\n\r\n or \n\n in the string */
- for (c = hctx->response_header->ptr, cp = 0, used = hctx->response_header->used - 1; used; c++, cp++, used--) {
- if (*c == ':') in_header = 1;
- else if (*c == '\n') {
- if (in_header == 0) {
- /* got a response without a response header */
+- if (con->file_started == 0) {
+- char *c;
+- int in_header = 0;
+- int header_end = 0;
+- int cp, eol = EOL_UNSET;
+- size_t used = 0;
+-
+- buffer_append_string_buffer(hctx->response_header, hctx->response);
+-
+- /* nph (non-parsed headers) */
+- if (0 == strncmp(hctx->response_header->ptr, "HTTP/1.", 7)) in_header = 1;
+-
+- /* search for the \r\n\r\n or \n\n in the string */
+- for (c = hctx->response_header->ptr, cp = 0, used = hctx->response_header->used - 1; used; c++, cp++, used--) {
+- if (*c == ':') in_header = 1;
+- else if (*c == '\n') {
+- if (in_header == 0) {
+- /* got a response without a response header */
-
-+
- c = NULL;
- header_end = 1;
- break;
- }
+- c = NULL;
+- header_end = 1;
+- break;
+- }
-
-+
- if (eol == EOL_UNSET) eol = EOL_N;
+- if (eol == EOL_UNSET) eol = EOL_N;
-
-+
- if (*(c+1) == '\n') {
- header_end = 1;
- break;
- }
+- if (*(c+1) == '\n') {
+- header_end = 1;
+- break;
+- }
-
-+
- } else if (used > 1 && *c == '\r' && *(c+1) == '\n') {
- if (in_header == 0) {
- /* got a response without a response header */
+- } else if (used > 1 && *c == '\r' && *(c+1) == '\n') {
+- if (in_header == 0) {
+- /* got a response without a response header */
-
-+
- c = NULL;
- header_end = 1;
- break;
- }
+- c = NULL;
+- header_end = 1;
+- break;
+- }
-
-+
- if (eol == EOL_UNSET) eol = EOL_RN;
+- if (eol == EOL_UNSET) eol = EOL_RN;
-
-+
- if (used > 3 &&
+- if (used > 3 &&
- *(c+2) == '\r' &&
-+ *(c+2) == '\r' &&
- *(c+3) == '\n') {
- header_end = 1;
- break;
- }
+- *(c+3) == '\n') {
+- header_end = 1;
+- break;
+- }
-
+- /* skip the \n */
+- c++;
+- cp++;
+- used--;
++ if (con->file_started == 0) {
++ size_t i;
++ int have_content_length = 0;
++
++ http_response_reset(p->resp);
++
++ /* the response header is not fully received yet,
++ *
++ * extract the http-response header from the rb-cq
++ */
++ switch (http_response_parse_cq(sess->rb, p->resp)) {
++ case PARSE_ERROR:
++ /* parsing failed */
++
++ TRACE("%s", "response parser failed");
++
++ con->http_status = 502; /* Bad Gateway */
++ return -1;
++ case PARSE_NEED_MORE:
++ return 0;
++ case PARSE_SUCCESS:
++ con->http_status = p->resp->status;
++
++ chunkqueue_remove_finished_chunks(sess->rb);
+
- /* skip the \n */
- c++;
- cp++;
- used--;
++ /* copy the http-headers */
++ for (i = 0; i < p->resp->headers->used; i++) {
++ const char *ign[] = { "Status", "Connection", NULL };
++ size_t j;
++ data_string *ds;
++
++ data_string *header = (data_string *)p->resp->headers->data[i];
++
++ /* some headers are ignored by default */
++ for (j = 0; ign[j]; j++) {
++ if (0 == strcasecmp(ign[j], header->key->ptr)) break;
}
- }
+- }
-
-+
- if (header_end) {
- if (c == NULL) {
- /* no header, but a body */
+- if (header_end) {
+- if (c == NULL) {
+- /* no header, but a body */
-
-+
- if (con->request.http_version == HTTP_VERSION_1_1) {
- con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
- }
+- if (con->request.http_version == HTTP_VERSION_1_1) {
+- con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
+- }
-
-+
- http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
- joblist_append(srv, con);
- } else {
- size_t hlen = c - hctx->response_header->ptr + (eol == EOL_RN ? 4 : 2);
- size_t blen = hctx->response_header->used - hlen - 1;
+- http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
+- joblist_append(srv, con);
+- } else {
+- size_t hlen = c - hctx->response_header->ptr + (eol == EOL_RN ? 4 : 2);
+- size_t blen = hctx->response_header->used - hlen - 1;
-
-+
- /* a small hack: terminate after at the second \r */
- hctx->response_header->used = hlen + 1 - (eol == EOL_RN ? 2 : 1);
- hctx->response_header->ptr[hlen - (eol == EOL_RN ? 2 : 1)] = '\0';
+- /* a small hack: terminate after at the second \r */
+- hctx->response_header->used = hlen + 1 - (eol == EOL_RN ? 2 : 1);
+- hctx->response_header->ptr[hlen - (eol == EOL_RN ? 2 : 1)] = '\0';
-
-+
- /* parse the response header */
- cgi_response_parse(srv, con, p, hctx->response_header, eol);
+- /* parse the response header */
+- cgi_response_parse(srv, con, p, hctx->response_header, eol);
-
-+
- /* enable chunked-transfer-encoding */
- if (con->request.http_version == HTTP_VERSION_1_1 &&
- !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
- con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
- }
+- /* enable chunked-transfer-encoding */
+- if (con->request.http_version == HTTP_VERSION_1_1 &&
+- !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
+- con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
+- }
-
+- if ((hctx->response->used != hlen) && blen > 0) {
+- http_chunk_append_mem(srv, con, c + (eol == EOL_RN ? 4: 2), blen + 1);
+- joblist_append(srv, con);
+- }
++ if (ign[j]) continue;
+
- if ((hctx->response->used != hlen) && blen > 0) {
- http_chunk_append_mem(srv, con, c + (eol == EOL_RN ? 4: 2), blen + 1);
- joblist_append(srv, con);
- }
++ if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Location"))) {
++ /* CGI/1.1 rev 03 - 7.2.1.2 */
++ if (con->http_status == 0) con->http_status = 302;
++ } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Content-Length"))) {
++ have_content_length = 1;
}
--
+
+- con->file_started = 1;
++ if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
++ ds = data_response_init();
++ }
++ buffer_copy_string_buffer(ds->key, header->key);
++ buffer_copy_string_buffer(ds->value, header->value);
+
- con->file_started = 1;
++ array_insert_unique(con->response.headers, (data_unset *)ds);
}
- } else {
- http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
- joblist_append(srv, con);
+- } else {
+- http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
+- joblist_append(srv, con);
++
++ con->file_started = 1;
++ sess->state = CGI_STATE_READ_RESPONSE_CONTENT;
++
++ if (con->request.http_version == HTTP_VERSION_1_1 &&
++ !have_content_length) {
++ con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
++ }
++
++ break;
}
-
-#if 0
-+
-+#if 0
- log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), b->ptr);
- #endif
+- log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), b->ptr);
+-#endif
}
-
+- return FDEVENT_HANDLED_NOT_FINISHED;
+
- return FDEVENT_HANDLED_NOT_FINISHED;
++ /* FIXME: pass the response-header to the other plugins to
++ * setup the filter-queue
++ *
++ * - use next-queue instead of con->write_queue
++ */
++
++ /* copy the content to the next cq */
++ for (c = sess->rb->first; c; c = c->next) {
++ http_chunk_append_mem(srv, con, c->mem->ptr + c->offset, c->mem->used - c->offset);
++
++ c->offset = c->mem->used - 1;
++ }
++
++ chunkqueue_remove_finished_chunks(sess->rb);
++ joblist_append(srv, con);
++
++ return 0;
}
-@@ -470,45 +465,46 @@
+-static handler_t cgi_connection_close(server *srv, handler_ctx *hctx) {
++static handler_t cgi_connection_close(server *srv, connection *con, plugin_data *p) {
++ cgi_session *sess = con->plugin_ctx[p->id];
+ int status;
pid_t pid;
- plugin_data *p;
- connection *con;
+- plugin_data *p;
+- connection *con;
-
-+
- if (NULL == hctx) return HANDLER_GO_ON;
+- if (NULL == hctx) return HANDLER_GO_ON;
-
-+
- p = hctx->plugin_data;
- con = hctx->remote_conn;
+- p = hctx->plugin_data;
+- con = hctx->remote_conn;
-
+
++ if (NULL == sess) return HANDLER_GO_ON;
if (con->mode != p->id) return HANDLER_GO_ON;
-#ifndef __WIN32
* close cgi-connection
*/
-
+- if (hctx->fd != -1) {
+
- if (hctx->fd != -1) {
++ if (sess->sock->fd != -1) {
/* close connection to the cgi-script */
- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
- fdevent_unregister(srv->ev, hctx->fd);
+- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
+- fdevent_unregister(srv->ev, hctx->fd);
-
-+
- if (close(hctx->fd)) {
- log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno));
- }
+- if (close(hctx->fd)) {
+- log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno));
+- }
-
-+
- hctx->fd = -1;
- hctx->fde_ndx = -1;
+- hctx->fd = -1;
+- hctx->fde_ndx = -1;
++ fdevent_event_del(srv->ev, sess->sock);
++ fdevent_unregister(srv->ev, sess->sock);
}
-
-+
- pid = hctx->pid;
+- pid = hctx->pid;
-
++
++ pid = sess->pid;
+
con->plugin_ctx[p->id] = NULL;
-
+
/* is this a good idea ? */
- cgi_handler_ctx_free(hctx);
+- cgi_handler_ctx_free(hctx);
-
++ cgi_session_free(sess);
+
/* if waitpid hasn't been called by response.c yet, do it here */
if (pid) {
switch(waitpid(pid, &status, WNOHANG)) {
case 0:
/* not finished yet */
-@@ -519,19 +515,19 @@
+@@ -519,35 +383,35 @@
case -1:
/* */
if (errno == EINTR) break;
log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed: ", strerror(errno));
return HANDLER_ERROR;
default:
-@@ -541,13 +537,13 @@
- con->http_status = 500;
+ /* Send an error if we haven't sent any data yet */
+ if (0 == con->file_started) {
+ connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
+- con->http_status = 500;
++ if (con->http_status == 0) con->http_status = 500;
con->mode = DIRECT;
}
-
return HANDLER_GO_ON;
} else {
log_error_write(srv, __FILE__, __LINE__, "sd", "cgi died, pid:", pid);
-@@ -555,20 +551,20 @@
+@@ -555,122 +419,126 @@
return HANDLER_GO_ON;
}
}
static handler_t cgi_connection_close_callback(server *srv, connection *con, void *p_d) {
plugin_data *p = p_d;
-
+- return cgi_connection_close(srv, con->plugin_ctx[p->id]);
+
- return cgi_connection_close(srv, con->plugin_ctx[p->id]);
++ return cgi_connection_close(srv, con, p);
}
-@@ -577,43 +573,43 @@
+
+ static handler_t cgi_handle_fdevent(void *s, void *ctx, int revents) {
server *srv = (server *)s;
- handler_ctx *hctx = ctx;
- connection *con = hctx->remote_conn;
+- handler_ctx *hctx = ctx;
+- connection *con = hctx->remote_conn;
-
-+
- joblist_append(srv, con);
+- joblist_append(srv, con);
-
-+
- if (hctx->fd == -1) {
- log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), "invalid cgi-fd");
+- if (hctx->fd == -1) {
+- log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), "invalid cgi-fd");
-
-+
- return HANDLER_ERROR;
- }
+- return HANDLER_ERROR;
+- }
-
++ cgi_session *sess = ctx;
++ connection *con = sess->remote_con;
++ chunk *c;
+
if (revents & FDEVENT_IN) {
- switch (cgi_demux_response(srv, hctx)) {
- case FDEVENT_HANDLED_NOT_FINISHED:
+- switch (cgi_demux_response(srv, hctx)) {
+- case FDEVENT_HANDLED_NOT_FINISHED:
++ switch (sess->state) {
++ case CGI_STATE_READ_RESPONSE_HEADER:
++ /* parse the header and set file-started, the demuxer will care about it */
++ joblist_append(srv, con);
++
break;
- case FDEVENT_HANDLED_FINISHED:
- /* we are done */
+- case FDEVENT_HANDLED_FINISHED:
+- /* we are done */
-
++ case CGI_STATE_READ_RESPONSE_CONTENT:
++ /* just forward the content to the out-going queue */
+
++ chunkqueue_remove_finished_chunks(sess->rb);
++
++ switch (srv->network_backend_read(srv, sess->remote_con, sess->sock, sess->rb)) {
++ case NETWORK_STATUS_CONNECTION_CLOSE:
++ fdevent_event_del(srv->ev, sess->sock);
++
++ /* the connection is gone
++ * make the connect */
++ sess->remote_con->file_finished = 1;
#if 0
- log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), "finished");
+- log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), "finished");
++ fdevent_event_del(srv->ev, sess->sock);
#endif
- cgi_connection_close(srv, hctx);
+- cgi_connection_close(srv, hctx);
-
- /* if we get a IN|HUP and have read everything don't exec the close twice */
-+
-+ /* if we get a IN|HUP and have read everything don't exec the close twice */
- return HANDLER_FINISHED;
- case FDEVENT_HANDLED_ERROR:
- connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
- con->http_status = 500;
- con->mode = DIRECT;
+- return HANDLER_FINISHED;
+- case FDEVENT_HANDLED_ERROR:
+- connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
+- con->http_status = 500;
+- con->mode = DIRECT;
-
+- log_error_write(srv, __FILE__, __LINE__, "s", "demuxer failed: ");
++ case NETWORK_STATUS_SUCCESS:
++ /* read even more, do we have all the content */
++
++ /* how much do we want to read ? */
++
++ /* call stream-decoder (HTTP-chunked, FastCGI, ... ) */
++
++ chunkqueue_remove_finished_chunks(sess->rb);
++
++ /* copy the content to the next cq */
++ for (c = sess->rb->first; c; c = c->next) {
++ if (c->mem->used == 0) continue;
++
++ http_chunk_append_mem(srv, sess->remote_con, c->mem->ptr + c->offset, c->mem->used - c->offset);
++
++ c->offset = c->mem->used - 1;
++
++ }
++ chunkqueue_remove_finished_chunks(sess->rb);
+
- log_error_write(srv, __FILE__, __LINE__, "s", "demuxer failed: ");
++ if (sess->remote_con->file_finished) {
++ /* send final HTTP-Chunk packet */
++ http_chunk_append_mem(srv, sess->remote_con, NULL, 0);
++ }
++
++ break;
++ default:
++ ERROR("%s", "oops, we failed to read");
++ break;
++ }
++
++ joblist_append(srv, sess->remote_con);
++ break;
++ default:
++ TRACE("unexpected state for a FDEVENT_IN: %d", sess->state);
break;
}
}
+
/* perhaps this issue is already handled */
if (revents & FDEVENT_HUP) {
- /* check if we still have a unfinished header package which is a body in reality */
-@@ -623,54 +619,54 @@
- http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
- joblist_append(srv, con);
- }
+- /* check if we still have a unfinished header package which is a body in reality */
+- if (con->file_started == 0 &&
+- hctx->response_header->used) {
+- con->file_started = 1;
+- http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
+- joblist_append(srv, con);
+- }
-
-+
- if (con->file_finished == 0) {
- http_chunk_append_mem(srv, con, NULL, 0);
- joblist_append(srv, con);
- }
+- if (con->file_finished == 0) {
+- http_chunk_append_mem(srv, con, NULL, 0);
+- joblist_append(srv, con);
+- }
-
-+
con->file_finished = 1;
-
-+
- if (chunkqueue_is_empty(con->write_queue)) {
- /* there is nothing left to write */
- connection_set_state(srv, con, CON_STATE_RESPONSE_END);
- } else {
- /* used the write-handler to finish the request on demand */
+- if (chunkqueue_is_empty(con->write_queue)) {
+- /* there is nothing left to write */
+- connection_set_state(srv, con, CON_STATE_RESPONSE_END);
+- } else {
+- /* used the write-handler to finish the request on demand */
-
-+
- }
+- }
-
-+
- # if 0
- log_error_write(srv, __FILE__, __LINE__, "sddd", "got HUP from cgi", con->fd, hctx->fd, revents);
- # endif
+-# if 0
+- log_error_write(srv, __FILE__, __LINE__, "sddd", "got HUP from cgi", con->fd, hctx->fd, revents);
+-# endif
-
+- /* rtsigs didn't liked the close */
+- cgi_connection_close(srv, hctx);
++
++ fdevent_event_del(srv->ev, sess->sock);
+
- /* rtsigs didn't liked the close */
- cgi_connection_close(srv, hctx);
++ /* someone has to close this socket now :) */
++ http_chunk_append_mem(srv, sess->remote_con, NULL, 0);
++ joblist_append(srv, sess->remote_con);
} else if (revents & FDEVENT_ERR) {
con->file_finished = 1;
-
+
/* kill all connections to the cgi process */
- cgi_connection_close(srv, hctx);
- #if 1
- log_error_write(srv, __FILE__, __LINE__, "s", "cgi-FDEVENT_ERR");
+- cgi_connection_close(srv, hctx);
+-#if 1
+- log_error_write(srv, __FILE__, __LINE__, "s", "cgi-FDEVENT_ERR");
-#endif
-+#endif
- return HANDLER_ERROR;
+- return HANDLER_ERROR;
++ fdevent_event_del(srv->ev, sess->sock);
}
-
+
if (env->size == 0) {
env->size = 16;
env->ptr = malloc(env->size * sizeof(*env->ptr));
-@@ -678,45 +674,45 @@
+@@ -678,45 +546,45 @@
env->size += 16;
env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr));
}
/* fork, execve */
switch (pid = fork()) {
case 0: {
-@@ -730,22 +726,22 @@
+@@ -730,44 +598,40 @@
char *c;
const char *s;
server_socket *srv_sock = con->srv_socket;
close(to_cgi_fds[1]);
-
- /* HACK:
+- * this is not nice, but it works
+- *
+- * we feed the stderr of the CGI to our errorlog, if possible
+
-+ /* HACK:
- * this is not nice, but it works
- *
- * we feed the stderr of the CGI to our errorlog, if possible
-@@ -754,20 +750,20 @@
- close(STDERR_FILENO);
- dup2(srv->errorlog_fd, STDERR_FILENO);
- }
++ /**
++ * FIXME: add a event-handler for STDERR_FILENO and let it LOG()
+ */
+- if (srv->errorlog_mode == ERRORLOG_FILE) {
+- close(STDERR_FILENO);
+- dup2(srv->errorlog_fd, STDERR_FILENO);
+- }
-
++
++ close(STDERR_FILENO);
+
/* create environment */
env.ptr = NULL;
(const void *) &(srv_sock->addr.ipv6.sin6_addr) :
(const void *) &(srv_sock->addr.ipv4.sin_addr),
b2, sizeof(b2)-1);
-@@ -779,10 +775,10 @@
+@@ -779,10 +643,12 @@
cgi_env_add(&env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1"));
s = get_http_version_name(con->request.http_version);
-
++
++ TRACE("http-version: %s (%d)", s, con->request.http_version);
+
cgi_env_add(&env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s));
-
#ifdef HAVE_IPV6
ntohs(srv_sock->addr.plain.sa_family == AF_INET6 ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
#else
-@@ -790,10 +786,10 @@
+@@ -790,10 +656,10 @@
#endif
);
cgi_env_add(&env, CONST_STR_LEN("SERVER_PORT"), buf, strlen(buf));
(const void *) &(srv_sock->addr.ipv6.sin6_addr) :
(const void *) &(srv_sock->addr.ipv4.sin_addr),
b2, sizeof(b2)-1);
-@@ -811,15 +807,18 @@
+@@ -811,15 +677,18 @@
cgi_env_add(&env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200"));
if (!buffer_is_empty(con->uri.query)) {
cgi_env_add(&env, CONST_STR_LEN("QUERY_STRING"), CONST_BUF_LEN(con->uri.query));
(const void *) &(con->dst_addr.ipv6.sin6_addr) :
(const void *) &(con->dst_addr.ipv4.sin_addr),
b2, sizeof(b2)-1);
-@@ -828,7 +827,7 @@
+@@ -828,7 +697,7 @@
#endif
cgi_env_add(&env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s));
#ifdef HAVE_IPV6
ntohs(con->dst_addr.plain.sa_family == AF_INET6 ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port)
#else
-@@ -836,19 +835,19 @@
+@@ -836,19 +705,19 @@
#endif
);
cgi_env_add(&env, CONST_STR_LEN("REMOTE_PORT"), buf, strlen(buf));
/* for valgrind */
if (NULL != (s = getenv("LD_PRELOAD"))) {
cgi_env_add(&env, CONST_STR_LEN("LD_PRELOAD"), s, strlen(s));
-@@ -863,24 +862,24 @@
+@@ -863,24 +732,24 @@
cgi_env_add(&env, CONST_STR_LEN("SYSTEMROOT"), s, strlen(s));
}
#endif
for (j = 0; j < ds->key->used - 1; j++) {
char cr = '_';
if (light_isalpha(ds->key->ptr[j])) {
-@@ -893,46 +892,46 @@
+@@ -893,46 +762,46 @@
p->tmp_buf->ptr[p->tmp_buf->used++] = cr;
}
p->tmp_buf->ptr[p->tmp_buf->used++] = '\0';
if (cgi_handler->used > 1) {
args[i++] = cgi_handler->ptr;
}
-@@ -942,7 +941,7 @@
+@@ -942,7 +811,7 @@
/* search for the last / */
if (NULL != (c = strrchr(con->physical.path->ptr, '/'))) {
*c = '\0';
/* change to the physical directory */
if (-1 == chdir(con->physical.path->ptr)) {
log_error_write(srv, __FILE__, __LINE__, "ssb", "chdir failed:", strerror(errno), con->physical.path);
-@@ -954,12 +953,12 @@
+@@ -952,14 +821,14 @@
+
+ /* we don't need the client socket */
for (i = 3; i < 256; i++) {
- if (i != srv->errorlog_fd) close(i);
+- if (i != srv->errorlog_fd) close(i);
++ close(i);
}
-
+
/* */
SEGFAULT();
break;
-@@ -974,11 +973,11 @@
+@@ -969,16 +838,16 @@
+ log_error_write(srv, __FILE__, __LINE__, "ss", "fork failed:", strerror(errno));
+ break;
+ default: {
+- handler_ctx *hctx;
++ cgi_session *sess;
+ /* father */
close(from_cgi_fds[1]);
close(to_cgi_fds[0]);
assert(chunkqueue_length(cq) == (off_t)con->request.content_length);
/* there is content to send */
-@@ -993,16 +992,16 @@
+@@ -993,16 +862,16 @@
if (-1 == c->file.fd && /* open the file if not already open */
-1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
strerror(errno), c->file.name, c->file.fd);
close(from_cgi_fds[0]);
-@@ -1012,7 +1011,7 @@
+@@ -1012,7 +881,7 @@
close(c->file.fd);
c->file.fd = -1;
/* chunk_reset() or chunk_free() will cleanup for us */
}
-@@ -1020,7 +1019,7 @@
+@@ -1020,7 +889,7 @@
switch(errno) {
case ENOSPC:
con->http_status = 507;
break;
default:
con->http_status = 403;
-@@ -1033,7 +1032,7 @@
+@@ -1033,7 +902,7 @@
switch(errno) {
case ENOSPC:
con->http_status = 507;
break;
default:
con->http_status = 403;
-@@ -1056,103 +1055,100 @@
+@@ -1056,103 +925,95 @@
}
close(to_cgi_fds[1]);
con->mode = p->id;
buffer_reset(con->physical.path);
-
-+
- hctx = cgi_handler_ctx_init();
+- hctx = cgi_handler_ctx_init();
-
-+
- hctx->remote_conn = con;
- hctx->plugin_data = p;
- hctx->pid = pid;
- hctx->fd = from_cgi_fds[0];
- hctx->fde_ndx = -1;
+- hctx->remote_conn = con;
+- hctx->plugin_data = p;
+- hctx->pid = pid;
+- hctx->fd = from_cgi_fds[0];
+- hctx->fde_ndx = -1;
-
-+
- con->plugin_ctx[p->id] = hctx;
+- con->plugin_ctx[p->id] = hctx;
-
-+
- fdevent_register(srv->ev, hctx->fd, cgi_handle_fdevent, hctx);
- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
+- fdevent_register(srv->ev, hctx->fd, cgi_handle_fdevent, hctx);
+- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
-
+- if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) {
+
- if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) {
++ sess = cgi_session_init();
++
++ sess->remote_con = con;
++ sess->pid = pid;
++
++ sess->sock->fd = from_cgi_fds[0];
++ sess->sock->type = IOSOCKET_TYPE_PIPE;
++
++ if (-1 == fdevent_fcntl_set(srv->ev, sess->sock)) {
log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno));
-
-+
- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
- fdevent_unregister(srv->ev, hctx->fd);
+- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
+- fdevent_unregister(srv->ev, hctx->fd);
-
-+
- log_error_write(srv, __FILE__, __LINE__, "sd", "cgi close:", hctx->fd);
+- log_error_write(srv, __FILE__, __LINE__, "sd", "cgi close:", hctx->fd);
-
-+
- close(hctx->fd);
+- close(hctx->fd);
-
-+
- cgi_handler_ctx_free(hctx);
+- cgi_handler_ctx_free(hctx);
-
-+
- con->plugin_ctx[p->id] = NULL;
+- con->plugin_ctx[p->id] = NULL;
-
++
++ cgi_session_free(sess);
+
return -1;
}
-
++
++ con->plugin_ctx[p->id] = sess;
++
++ fdevent_register(srv->ev, sess->sock, cgi_handle_fdevent, sess);
++ fdevent_event_add(srv->ev, sess->sock, FDEVENT_IN);
++
++ sess->state = CGI_STATE_READ_RESPONSE_HEADER;
+
break;
}
+
if (fn->used == 0) return HANDLER_GO_ON;
-
++
++ TRACE("http-version: (%d)", con->request.http_version);
+
mod_cgi_patch_connection(srv, con, p);
-
buffer_reset(con->physical.path);
return HANDLER_FINISHED;
}
-@@ -1160,7 +1156,7 @@
+@@ -1160,7 +1021,7 @@
break;
}
}
return HANDLER_GO_ON;
}
-@@ -1168,11 +1164,11 @@
+@@ -1168,11 +1029,11 @@
plugin_data *p = p_d;
size_t ndx;
/* the trigger handle only cares about lonely PID which we have to wait for */
switch(waitpid(p->cgi_pid.ptr[ndx], &status, WNOHANG)) {
case 0:
/* not finished yet */
-@@ -1182,7 +1178,7 @@
+@@ -1182,7 +1043,7 @@
break;
case -1:
log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed: ", strerror(errno));
return HANDLER_ERROR;
default:
-@@ -1193,16 +1189,16 @@
+@@ -1193,96 +1054,103 @@
} else {
log_error_write(srv, __FILE__, __LINE__, "s", "cgi died ?");
}
return HANDLER_GO_ON;
}
-@@ -1210,15 +1206,15 @@
+ SUBREQUEST_FUNC(mod_cgi_handle_subrequest) {
int status;
plugin_data *p = p_d;
- handler_ctx *hctx = con->plugin_ctx[p->id];
+- handler_ctx *hctx = con->plugin_ctx[p->id];
-
++ cgi_session *sess = con->plugin_ctx[p->id];
+
if (con->mode != p->id) return HANDLER_GO_ON;
- if (NULL == hctx) return HANDLER_GO_ON;
+- if (NULL == hctx) return HANDLER_GO_ON;
-
++ if (NULL == sess) return HANDLER_GO_ON;
++
++ switch (cgi_demux_response(srv, con, p)) {
++ case 0:
++ break;
++ case 1:
++ cgi_connection_close(srv, con, p);
++
++ /* if we get a IN|HUP and have read everything don't exec the close twice */
++ return HANDLER_FINISHED;
++ case -1:
++ cgi_connection_close(srv, con, p);
++
++ if (0 == con->http_status) con->http_status = 500;
++ connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
++ con->mode = DIRECT;
++
++ return HANDLER_FINISHED;
++ }
+
#if 0
- log_error_write(srv, __FILE__, __LINE__, "sdd", "subrequest, pid =", hctx, hctx->pid);
+- log_error_write(srv, __FILE__, __LINE__, "sdd", "subrequest, pid =", hctx, hctx->pid);
-#endif
-+#endif
- if (hctx->pid == 0) return HANDLER_FINISHED;
+- if (hctx->pid == 0) return HANDLER_FINISHED;
-#ifndef __WIN32
+- switch(waitpid(hctx->pid, &status, WNOHANG)) {
++ log_error_write(srv, __FILE__, __LINE__, "sdd", "subrequest, pid =", sess, sess->pid);
++#endif
++ if (sess->pid == 0) return HANDLER_FINISHED;
+#ifndef _WIN32
- switch(waitpid(hctx->pid, &status, WNOHANG)) {
++ switch(waitpid(sess->pid, &status, WNOHANG)) {
case 0:
/* we only have for events here if we don't have the header yet,
-@@ -1228,61 +1224,61 @@
- return HANDLER_WAIT_FOR_EVENT;
+ * otherwise the event-handler will send us the incoming data */
+- if (con->file_started) return HANDLER_FINISHED;
+
+- return HANDLER_WAIT_FOR_EVENT;
++ if (!con->file_started) return HANDLER_WAIT_FOR_EVENT;
++ if (con->file_finished) return HANDLER_FINISHED;
++
++ return HANDLER_GO_ON;
case -1:
if (errno == EINTR) return HANDLER_WAIT_FOR_EVENT;
-
con->mode = DIRECT;
con->http_status = 500;
-
-+
- hctx->pid = 0;
+- hctx->pid = 0;
-
-+
- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
- fdevent_unregister(srv->ev, hctx->fd);
+- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
+- fdevent_unregister(srv->ev, hctx->fd);
-
-+
- if (close(hctx->fd)) {
- log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno));
- }
+- if (close(hctx->fd)) {
+- log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno));
+- }
-
-+
- cgi_handler_ctx_free(hctx);
+- cgi_handler_ctx_free(hctx);
-
++
++ sess->pid = 0;
++
++ fdevent_event_del(srv->ev, sess->sock);
++ fdevent_unregister(srv->ev, sess->sock);
++
++ cgi_session_free(sess);
+
con->plugin_ctx[p->id] = NULL;
-
- /* cgi process exited cleanly
- *
- * check if we already got the response
-+ /* cgi process exited cleanly
-+ *
-+ * check if we already got the response
- */
+- */
-
-+
- if (!con->file_started) return HANDLER_WAIT_FOR_EVENT;
+- if (!con->file_started) return HANDLER_WAIT_FOR_EVENT;
-
++ con->file_finished = 1;
+
if (WIFEXITED(status)) {
/* nothing */
+
}
-
-+
- hctx->pid = 0;
+- hctx->pid = 0;
-
-+
- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
- fdevent_unregister(srv->ev, hctx->fd);
+- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
+- fdevent_unregister(srv->ev, hctx->fd);
-
-+
- if (close(hctx->fd)) {
- log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno));
- }
+- if (close(hctx->fd)) {
+- log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno));
+- }
-
-+
- cgi_handler_ctx_free(hctx);
+- cgi_handler_ctx_free(hctx);
-
++
++ sess->pid = 0;
++
++ fdevent_event_del(srv->ev, sess->sock);
++ fdevent_unregister(srv->ev, sess->sock);
++
++ cgi_session_free(sess);
+
con->plugin_ctx[p->id] = NULL;
return HANDLER_FINISHED;
}
-@@ -1306,8 +1302,8 @@
+@@ -1306,8 +1174,8 @@
p->init = mod_cgi_init;
p->cleanup = mod_cgi_free;
p->set_defaults = mod_fastcgi_set_defaults;
return 0;
}
--- ../lighttpd-1.4.11/src/mod_cml.c 2006-01-30 13:51:48.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_cml.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/mod_cml.c 2006-07-16 00:26:03.000000000 +0300
@@ -4,7 +4,6 @@
#include <stdlib.h>
#include <string.h>
return 0;
}
--- ../lighttpd-1.4.11/src/mod_cml.h 2006-01-30 13:51:35.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_cml.h 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/mod_cml.h 2006-07-16 00:26:03.000000000 +0300
@@ -16,10 +16,10 @@
typedef struct {
int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn);
--- ../lighttpd-1.4.11/src/mod_cml_funcs.c 2005-11-17 16:15:08.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_cml_funcs.c 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/mod_cml_funcs.c 2006-07-16 00:26:04.000000000 +0300
@@ -4,8 +4,7 @@
#include <stdlib.h>
#include <string.h>
}
#endif
--- ../lighttpd-1.4.11/src/mod_cml_lua.c 2006-01-30 13:56:40.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_cml_lua.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/mod_cml_lua.c 2006-07-16 00:26:04.000000000 +0300
@@ -23,7 +23,7 @@
#ifdef USE_OPENSSL
#define IN const
}
#else
--- ../lighttpd-1.4.11/src/mod_compress.c 2005-11-18 13:49:14.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_compress.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/mod_compress.c 2006-07-16 00:26:04.000000000 +0300
@@ -2,7 +2,6 @@
#include <sys/stat.h>
return 0;
}
--- ../lighttpd-1.4.11/src/mod_dirlisting.c 2006-01-13 00:00:45.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_dirlisting.c 2006-07-15 22:43:21.000000000 +0300
++++ lighttpd-1.4.12/src/mod_dirlisting.c 2006-07-16 00:26:04.000000000 +0300
@@ -1,11 +1,9 @@
#include <ctype.h>
#include <stdlib.h>
return 0;
}
--- ../lighttpd-1.4.11/src/mod_evasive.c 2006-01-04 15:24:51.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_evasive.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/mod_evasive.c 2006-07-16 00:26:04.000000000 +0300
@@ -31,100 +31,97 @@
typedef struct {
return 0;
}
--- ../lighttpd-1.4.11/src/mod_evhost.c 2005-08-17 10:42:03.000000000 +0300
-+++ lighttpd-1.4.12/src/mod_evhost.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/mod_evhost.c 2006-07-16 00:26:03.000000000 +0300
@@ -7,10 +7,12 @@
#include "response.h"
#include "stat_cache.h"
}
--- ../lighttpd-1.4.11/src/mod_expire.c 2005-11-03 09:52:13.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_expire.c 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/mod_expire.c 2006-07-16 00:26:04.000000000 +0300
@@ -12,8 +12,8 @@
#include "stat_cache.h"
return 0;
}
--- ../lighttpd-1.4.11/src/mod_fastcgi.c 2006-03-09 13:18:39.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_fastcgi.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/mod_fastcgi.c 2006-07-18 13:03:40.000000000 +0300
@@ -1,5 +1,4 @@
#include <sys/types.h>
-#include <unistd.h>
size_t size;
size_t used;
} char_array;
-@@ -306,44 +308,44 @@
+@@ -306,55 +308,54 @@
typedef struct {
PLUGIN_DATA;
buffer_uint fcgi_request_id;
-
+
size_t request_id;
- int fd; /* fd to the fastcgi process */
- int fde_ndx; /* index into the fd-event buffer */
-@@ -352,9 +354,9 @@
+- int fd; /* fd to the fastcgi process */
+- int fde_ndx; /* index into the fd-event buffer */
++ iosocket *sock;
+
+ pid_t pid;
int got_proc;
int send_content_body;
connection *remote_conn; /* dumb pointer */
plugin_data *plugin_data; /* dumb pointer */
} handler_ctx;
-@@ -380,7 +382,7 @@
+@@ -380,7 +381,7 @@
return di;
}
* they will be moved to a statistics.c later */
int status_counter_inc(server *srv, const char *s, size_t len) {
data_integer *di = status_counter_get_counter(srv, s, len);
-@@ -429,7 +431,7 @@
+@@ -429,7 +430,7 @@
CLEAN(".connected");
CLEAN(".load");
#define CLEAN(x) \
fastcgi_status_copy_procname(b, host, NULL); \
-@@ -438,33 +440,32 @@
+@@ -438,33 +439,30 @@
CLEAN(".load");
hctx = calloc(1, sizeof(*hctx));
assert(hctx);
-
-+
- hctx->fde_ndx = -1;
+- hctx->fde_ndx = -1;
-
- hctx->response_header = buffer_init();
-
hctx->state = FCGI_STATE_INIT;
hctx->proc = NULL;
-
-+
- hctx->fd = -1;
+- hctx->fd = -1;
-
++
++ hctx->sock = iosocket_init();
+
hctx->reconnects = 0;
hctx->send_content_body = 1;
return hctx;
}
-@@ -473,10 +474,9 @@
+@@ -473,12 +471,13 @@
hctx->host->load--;
hctx->host = NULL;
}
+ chunkqueue_free(hctx->http_rb);
chunkqueue_free(hctx->wb);
++ iosocket_free(hctx->sock);
++
free(hctx);
-@@ -488,21 +488,21 @@
+ }
+
+@@ -488,21 +487,21 @@
f = calloc(1, sizeof(*f));
f->unixsocket = buffer_init();
f->connection_name = buffer_init();
free(f);
}
-@@ -519,13 +519,13 @@
+@@ -519,13 +518,13 @@
f->bin_env = array_init();
f->bin_env_copy = array_init();
f->strip_request_uri = buffer_init();
buffer_free(h->id);
buffer_free(h->host);
buffer_free(h->unixsocket);
-@@ -534,49 +534,49 @@
+@@ -534,49 +533,49 @@
buffer_free(h->strip_request_uri);
array_free(h->bin_env);
array_free(h->bin_env_copy);
free(f);
}
-@@ -625,24 +625,25 @@
+@@ -625,24 +624,25 @@
assert(fe->hosts);
}
return p;
}
-@@ -650,81 +651,82 @@
+@@ -650,81 +650,82 @@
FREE_FUNC(mod_fastcgi_free) {
plugin_data *p = p_d;
buffer_uint *r = &(p->fcgi_request_id);
if (env->size == 0) {
env->size = 16;
env->ptr = malloc(env->size * sizeof(*env->ptr));
-@@ -732,9 +734,9 @@
+@@ -732,9 +733,9 @@
env->size += 16;
env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr));
}
return 0;
}
-@@ -753,15 +755,15 @@
+@@ -753,15 +754,15 @@
if (env->size == 0) {
env->size = 16;
env->ptr = malloc(env->size * sizeof(*env->ptr));
start = b->ptr + i + 1;
break;
default:
-@@ -794,7 +796,7 @@
+@@ -794,7 +795,7 @@
return 0;
}
plugin_data *p,
fcgi_extension_host *host,
fcgi_proc *proc) {
-@@ -806,31 +808,27 @@
+@@ -806,31 +807,27 @@
#endif
struct sockaddr_in fcgi_addr_in;
struct sockaddr *fcgi_addr;
socket_type = AF_UNIX;
fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
-@@ -844,108 +842,108 @@
+@@ -844,108 +841,108 @@
#endif
} else {
fcgi_addr_in.sin_family = AF_INET;
arg.ptr = NULL;
arg.size = 0;
arg.used = 0;
-@@ -955,18 +953,18 @@
+@@ -955,18 +952,18 @@
dup2(fcgi_fd, FCGI_LISTENSOCK_FILENO);
close(fcgi_fd);
}
if (NULL != (ge = getenv(ds->value->ptr))) {
env_add(&env, CONST_BUF_LEN(ds->value), ge, strlen(ge));
}
-@@ -974,39 +972,39 @@
+@@ -974,39 +971,39 @@
} else {
for (i = 0; environ[i]; i++) {
char *eq;
/* change to the physical directory */
if (-1 == chdir(arg.ptr[0])) {
*c = '/';
-@@ -1018,12 +1016,12 @@
+@@ -1018,12 +1015,12 @@
/* exec the cgi */
execve(arg.ptr[0], arg.ptr, env.ptr);
break;
}
case -1:
-@@ -1031,17 +1029,17 @@
+@@ -1031,17 +1028,17 @@
break;
default:
/* father */
"pid not found:", strerror(errno));
return -1;
default:
-@@ -1049,10 +1047,10 @@
+@@ -1049,10 +1046,10 @@
"the fastcgi-backend", host->bin_path, "failed to start:");
/* the child should not terminate at all */
if (WIFEXITED(status)) {
"if you try do run PHP as FastCGI backend make sure you use the FastCGI enabled version.\n"
"You can find out if it is the right one by executing 'php -v' and it should display '(cgi-fcgi)' "
"in the output, NOT (cgi) NOR (cli)\n"
-@@ -1060,8 +1058,8 @@
+@@ -1060,8 +1057,8 @@
log_error_write(srv, __FILE__, __LINE__, "s",
"If this is PHP on Gentoo add fastcgi to the USE flags");
} else if (WIFSIGNALED(status)) {
WTERMSIG(status));
if (WTERMSIG(status) == 11) {
-@@ -1071,8 +1069,8 @@
+@@ -1071,8 +1068,8 @@
"If this is PHP try to remove the byte-code caches for now and try again.");
}
} else {
status);
}
return -1;
-@@ -1082,26 +1080,26 @@
+@@ -1082,26 +1079,26 @@
proc->pid = child;
proc->last_used = srv->cur_ts;
proc->is_local = 1;
return 0;
}
-@@ -1111,93 +1109,93 @@
+@@ -1111,93 +1108,93 @@
data_unset *du;
size_t i = 0;
buffer *fcgi_mode = buffer_init();
{ "check-local", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 5 */
{ "port", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 6 */
{ "min-procs-not-working", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 7 this is broken for now */
-@@ -1205,28 +1203,28 @@
+@@ -1205,28 +1202,28 @@
{ "max-load-per-proc", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 9 */
{ "idle-timeout", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 10 */
{ "disable-time", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 11 */
buffer_copy_string_buffer(host->id, da_host->key);
host->check_local = 1;
-@@ -1238,13 +1236,13 @@
+@@ -1238,13 +1235,13 @@
host->disable_time = 60;
host->break_scriptfilename_for_php = 0;
host->allow_xsendfile = 0; /* handle X-LIGHTTPD-send-file */
fcv[5].destination = &(host->check_local);
fcv[6].destination = &(host->port);
fcv[7].destination = &(host->min_procs);
-@@ -1252,35 +1250,35 @@
+@@ -1252,35 +1249,35 @@
fcv[9].destination = &(host->max_load_per_proc);
fcv[10].destination = &(host->idle_timeout);
fcv[11].destination = &(host->disable_time);
da_ext->key, " => (",
da_host->key, " ( ...");
-@@ -1288,37 +1286,37 @@
+@@ -1288,37 +1285,37 @@
}
} else {
/* tcp/ip */
if (s->debug) {
log_error_write(srv, __FILE__, __LINE__, "ssbsdsbsdsd",
"--- fastcgi spawning local",
-@@ -1328,7 +1326,7 @@
+@@ -1328,7 +1325,7 @@
"\n\tmin-procs:", host->min_procs,
"\n\tmax-procs:", host->max_procs);
}
for (pno = 0; pno < host->min_procs; pno++) {
fcgi_proc *proc;
-@@ -1343,7 +1341,7 @@
+@@ -1343,7 +1340,7 @@
buffer_append_string(proc->unixsocket, "-");
buffer_append_long(proc->unixsocket, pno);
}
if (s->debug) {
log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd",
"--- fastcgi spawning",
-@@ -1351,7 +1349,7 @@
+@@ -1351,7 +1348,7 @@
"\n\tsocket", host->unixsocket,
"\n\tcurrent:", pno, "/", host->min_procs);
}
if (fcgi_spawn_connection(srv, p, host, proc)) {
log_error_write(srv, __FILE__, __LINE__, "s",
"[ERROR]: spawning fcgi failed.");
-@@ -1359,35 +1357,35 @@
+@@ -1359,35 +1356,35 @@
}
fastcgi_status_init(srv, p->statuskey, host, proc);
if (!buffer_is_empty(fcgi_mode)) {
if (strcmp(fcgi_mode->ptr, "responder") == 0) {
host->mode = FCGI_RESPONDER;
-@@ -1411,16 +1409,16 @@
+@@ -1411,16 +1408,16 @@
}
}
}
return 0;
}
-@@ -1429,13 +1427,13 @@
+@@ -1429,13 +1426,13 @@
size_t m = 0;
size_t i;
buffer_uint *r = &(p->fcgi_request_id);
if (r->size == 0) {
r->size = 16;
r->ptr = malloc(sizeof(*r->ptr) * r->size);
-@@ -1443,54 +1441,54 @@
+@@ -1443,54 +1440,55 @@
r->size += 16;
r->ptr = realloc(r->ptr, sizeof(*r->ptr) * r->size);
}
-
+
if (con->mode != p->id) {
- WP();
+- WP();
return;
}
-
+- if (hctx->fd != -1) {
+- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
+- fdevent_unregister(srv->ev, hctx->fd);
+- close(hctx->fd);
+- srv->cur_fds--;
+
- if (hctx->fd != -1) {
- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
- fdevent_unregister(srv->ev, hctx->fd);
- close(hctx->fd);
- srv->cur_fds--;
++ if (hctx->sock->fd != -1) {
++ fdevent_event_del(srv->ev, hctx->sock);
++ fdevent_unregister(srv->ev, hctx->sock);
++ closesocket(hctx->sock->fd);
++ hctx->sock->fd = -1;
++
++ srv->cur_fds--;
}
-
+
status_counter_dec(srv, CONST_STR_LEN("fastcgi.active-requests"));
fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
-@@ -1509,39 +1507,39 @@
+@@ -1509,101 +1507,101 @@
if (p->conf.debug) {
log_error_write(srv, __FILE__, __LINE__, "ssdsbsd",
+ *
*/
- if (hctx->fd != -1) {
-@@ -1551,59 +1549,59 @@
+- if (hctx->fd != -1) {
+- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
+- fdevent_unregister(srv->ev, hctx->fd);
+- close(hctx->fd);
++ if (hctx->sock->fd != -1) {
++ fdevent_event_del(srv->ev, hctx->sock);
++ fdevent_unregister(srv->ev, hctx->sock);
++ close(hctx->sock->fd);
srv->cur_fds--;
- hctx->fd = -1;
+- hctx->fd = -1;
++ hctx->sock->fd = -1;
}
-
+
+
fcgi_extension_host *host = hctx->host;
fcgi_proc *proc = hctx->proc;
- int fcgi_fd = hctx->fd;
+- int fcgi_fd = hctx->fd;
-
++ int fcgi_fd = hctx->sock->fd;
+
memset(&fcgi_addr, 0, sizeof(fcgi_addr));
-
/* get the server-side of the connection to the client */
our_addr_len = sizeof(our_addr);
-
+- if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) {
+
- if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) {
++ if (-1 == getsockname(con->sock->fd, &(our_addr.plain), &our_addr_len)) {
s = inet_ntop_cache_get_ip(srv, &(srv_sock->addr));
} else {
s = inet_ntop_cache_get_ip(srv, &(our_addr));
buffer_append_string_len(packet->b, c->mem->ptr + c->offset + offset, weHave);
/* we only skipped the first 8 bytes as they are the fcgi header */
-@@ -2380,65 +2278,37 @@
+@@ -2380,65 +2278,42 @@
}
chunkqueue_remove_finished_chunks(hctx->rb);
-
- /* this should be catched by the b > 0 above */
- assert(r);
++ handler_t ret;
- b->used = r + 1; /* one extra for the fake \0 */
- b->ptr[b->used - 1] = '\0';
- } else {
- log_error_write(srv, __FILE__, __LINE__, "ssdsb",
-+ switch(srv->network_backend_read(srv, con, hctx->fd, hctx->rb)) {
-+ case NETWORK_STATUS_WAIT_FOR_EVENT:
-+ /* we are only triggered when there is a event */
-+ log_error_write(srv, __FILE__, __LINE__, "ssdsb",
- "unexpected end-of-file (perhaps the fastcgi process died):",
- "pid:", proc->pid,
- "socket:", proc->connection_name);
+- "unexpected end-of-file (perhaps the fastcgi process died):",
+- "pid:", proc->pid,
+- "socket:", proc->connection_name);
-
++ /* in case we read nothing, check the return code
++ * if we got something, be happy :)
++ *
++ * Ok, to be honest:
++ * - it is fine to receive a EAGAIN on a second read() call
++ * - it might be fine they we get a con-close on a second read() call */
++ switch(srv->network_backend_read(srv, con, hctx->sock, hctx->rb)) {
++ case NETWORK_STATUS_WAIT_FOR_EVENT:
++ /* a EAGAIN after we read exactly the chunk-size */
++
++ ERROR("%s", "oops, got a EAGAIN even if we just got call for the event, wired");
+ return -1;
+ case NETWORK_STATUS_SUCCESS:
+ break;
+ default:
-+ log_error_write(srv, __FILE__, __LINE__, "s", "fastcgi-read failed");
++ ERROR("reading from fastcgi socket failed (fd=%d)", hctx->sock->fd);
return -1;
}
while (fin == 0) {
fastcgi_response_packet packet;
-@@ -2454,92 +2324,135 @@
+@@ -2454,92 +2329,136 @@
/* is the header already finished */
if (0 == con->file_started) {
- con->file_started = 1;
+ chunkqueue_remove_finished_chunks(hctx->http_rb);
++
++ con->http_status = p->resp->status;
++ hctx->send_content_body = 1;
- if (host->mode == FCGI_AUTHORIZER &&
- (con->http_status == 0 ||
- http_chunk_append_file(srv, con, ds->value, 0, sce->st.st_size);
- hctx->send_content_body = 0; /* ignore the content */
- joblist_append(srv, con);
-+ con->http_status = p->resp->status;
-+
+ /* handle the header fields */
+ if (host->mode == FCGI_AUTHORIZER) {
+ /* auth mode is a bit different */
if (host->mode != FCGI_AUTHORIZER ||
!(con->http_status == 0 ||
con->http_status == 200)) {
-@@ -2547,39 +2460,39 @@
+@@ -2547,39 +2466,39 @@
http_chunk_append_mem(srv, con, NULL, 0);
joblist_append(srv, con);
}
*/
switch (proc->state) {
case PROC_STATE_KILLED:
-@@ -2592,13 +2505,13 @@
+@@ -2592,13 +2511,13 @@
break;
case PROC_STATE_OVERLOADED:
if (srv->cur_ts <= proc->disabled_until) break;
host->unixsocket);
break;
case PROC_STATE_DIED_WAIT_FOR_PID:
-@@ -2606,7 +2519,7 @@
+@@ -2606,7 +2525,7 @@
if (!proc->is_local) break;
/* the child should not terminate at all */
switch(waitpid(proc->pid, &status, WNOHANG)) {
case 0:
/* child is still alive */
-@@ -2616,45 +2529,45 @@
+@@ -2616,45 +2535,45 @@
default:
if (WIFEXITED(status)) {
#if 0
if (fcgi_spawn_connection(srv, p, host, proc)) {
log_error_write(srv, __FILE__, __LINE__, "s",
"ERROR: spawning fcgi failed.");
-@@ -2662,18 +2575,18 @@
+@@ -2662,18 +2581,18 @@
}
} else {
if (srv->cur_ts <= proc->disabled_until) break;
return 0;
}
-@@ -2682,19 +2595,19 @@
+@@ -2682,19 +2601,19 @@
fcgi_extension_host *host= hctx->host;
connection *con = hctx->remote_conn;
fcgi_proc *proc;
hctx->proc->disabled_until = srv->cur_ts + 10;
hctx->proc->state = PROC_STATE_DIED;
-@@ -2705,12 +2618,12 @@
+@@ -2705,12 +2624,12 @@
if (hctx->state == FCGI_STATE_CONNECT_DELAYED) {
int socket_error;
socklen_t socket_error_len = sizeof(socket_error);
-
+
/* try to finish the connect() */
- if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
+- if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
- log_error_write(srv, __FILE__, __LINE__, "ss",
++ if (0 != getsockopt(hctx->sock->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
+ log_error_write(srv, __FILE__, __LINE__, "ss",
"getsockopt failed:", strerror(errno));
-
hctx->proc->disabled_until = srv->cur_ts + 10;
hctx->proc->state = PROC_STATE_DIED;
-@@ -2719,12 +2632,12 @@
+@@ -2719,12 +2638,12 @@
if (socket_error != 0) {
if (!hctx->proc->is_local || p->conf.debug) {
/* local procs get restarted */
hctx->proc->disabled_until = srv->cur_ts + 5;
if (hctx->proc->is_local) {
-@@ -2732,17 +2645,17 @@
+@@ -2732,17 +2651,17 @@
} else {
hctx->proc->state = PROC_STATE_DIED;
}
hctx->state = FCGI_STATE_PREPARE_WRITE;
}
-@@ -2755,14 +2668,14 @@
+@@ -2755,14 +2674,14 @@
/* do we have a running process for this host (max-procs) ? */
hctx->proc = NULL;
+
/* all childs are dead */
if (proc == NULL) {
- hctx->fde_ndx = -1;
+- hctx->fde_ndx = -1;
-
++ hctx->sock->fde_ndx = -1;
+
return HANDLER_ERROR;
}
-@@ -2775,50 +2688,50 @@
+@@ -2775,50 +2694,50 @@
}
ret = host->unixsocket->used ? AF_UNIX : AF_INET;
-
+- if (-1 == (hctx->fd = socket(ret, SOCK_STREAM, 0))) {
+
- if (-1 == (hctx->fd = socket(ret, SOCK_STREAM, 0))) {
++ if (-1 == (hctx->sock->fd = socket(ret, SOCK_STREAM, 0))) {
if (errno == EMFILE ||
errno == EINTR) {
- log_error_write(srv, __FILE__, __LINE__, "sd",
-+ log_error_write(srv, __FILE__, __LINE__, "sd",
- "wait for fd at connection:", con->fd);
+- "wait for fd at connection:", con->fd);
-
++ log_error_write(srv, __FILE__, __LINE__, "sd",
++ "wait for fd at connection:", con->sock->fd);
+
return HANDLER_WAIT_FOR_FD;
}
"socket failed:", strerror(errno), srv->cur_fds, srv->max_fds);
return HANDLER_ERROR;
}
- hctx->fde_ndx = -1;
+- hctx->fde_ndx = -1;
-
++ hctx->sock->fde_ndx = -1;
+
srv->cur_fds++;
-
-+
- fdevent_register(srv->ev, hctx->fd, fcgi_handle_fdevent, hctx);
+- fdevent_register(srv->ev, hctx->fd, fcgi_handle_fdevent, hctx);
-
-+
- if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) {
+- if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) {
- log_error_write(srv, __FILE__, __LINE__, "ss",
++
++ fdevent_register(srv->ev, hctx->sock, fcgi_handle_fdevent, hctx);
++
++ if (-1 == fdevent_fcntl_set(srv->ev, hctx->sock)) {
+ log_error_write(srv, __FILE__, __LINE__, "ss",
"fcntl failed:", strerror(errno));
-
case CONNECTION_DELAYED:
/* connection is in progress, wait for an event and call getsockopt() below */
-
-+
- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
+- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
-
++
++ fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
+
fcgi_set_state(srv, hctx, FCGI_STATE_CONNECT_DELAYED);
return HANDLER_WAIT_FOR_EVENT;
"backend is overloaded, we disable it for a 2 seconds and send the request to another backend instead:",
"reconnects:", hctx->reconnects,
"load:", host->load);
-@@ -2831,7 +2744,7 @@
+@@ -2831,7 +2750,7 @@
buffer_append_string(p->statuskey, ".overloaded");
status_counter_inc(srv, CONST_BUF_LEN(p->statuskey));
return HANDLER_ERROR;
case CONNECTION_DEAD:
/* we got a hard error from the backend like
-@@ -2840,19 +2753,19 @@
+@@ -2840,19 +2759,19 @@
*
* for check if the host is back in 5 seconds
* */
fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
buffer_append_string(p->statuskey, ".died");
-@@ -2863,19 +2776,19 @@
+@@ -2863,19 +2782,19 @@
/* everything is ok, go on */
fcgi_set_state(srv, hctx, FCGI_STATE_PREPARE_WRITE);
status_counter_inc(srv, CONST_STR_LEN("fastcgi.requests"));
status_counter_inc(srv, CONST_STR_LEN("fastcgi.active-requests"));
-@@ -2898,9 +2811,9 @@
+@@ -2898,9 +2817,9 @@
if (p->conf.debug) {
log_error_write(srv, __FILE__, __LINE__, "ssdsbsd",
"load:", hctx->proc->load);
}
-@@ -2908,62 +2821,63 @@
+@@ -2908,74 +2827,75 @@
if (hctx->request_id == 0) {
hctx->request_id = fcgi_requestid_new(srv, p);
} else {
/* fall through */
case FCGI_STATE_WRITE:
- ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb);
-+ ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb);
++ ret = srv->network_backend_write(srv, con, hctx->sock, hctx->wb);
chunkqueue_remove_finished_chunks(hctx->wb);
-
return HANDLER_ERROR;
case EAGAIN:
case EINTR:
- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
+- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
-
++ fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
+
return HANDLER_WAIT_FOR_EVENT;
default:
return HANDLER_ERROR;
}
}
-@@ -2975,7 +2889,7 @@
+
+ if (hctx->wb->bytes_out == hctx->wb->bytes_in) {
+ /* we don't need the out event anymore */
+- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
+- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
++ fdevent_event_del(srv->ev, hctx->sock);
++ fdevent_event_add(srv->ev, hctx->sock, FDEVENT_IN);
fcgi_set_state(srv, hctx, FCGI_STATE_READ);
} else {
- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
+- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
-
++ fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
+
return HANDLER_WAIT_FOR_EVENT;
}
-@@ -2987,7 +2901,7 @@
+@@ -2987,7 +2907,7 @@
log_error_write(srv, __FILE__, __LINE__, "s", "(debug) unknown state");
return HANDLER_ERROR;
}
return HANDLER_WAIT_FOR_EVENT;
}
-@@ -2996,18 +2910,18 @@
+@@ -2996,18 +2916,18 @@
* */
SUBREQUEST_FUNC(mod_fastcgi_handle_subrequest) {
plugin_data *p = p_d;
* and when the host died and we have to select a new one */
if (hctx->host == NULL) {
size_t k;
-@@ -3016,23 +2930,23 @@
+@@ -3016,23 +2936,23 @@
/* get best server */
for (k = 0, ndx = -1; k < hctx->ext->used; k++) {
host = hctx->ext->hosts[k];
con->http_status = 500;
con->mode = DIRECT;
-@@ -3040,16 +2954,16 @@
+@@ -3040,16 +2960,16 @@
}
host = hctx->ext->hosts[ndx];
*
* as soon as hctx->host is unassigned, decrease the load again */
hctx->host->load++;
-@@ -3063,7 +2977,7 @@
+@@ -3063,7 +2983,7 @@
case HANDLER_ERROR:
proc = hctx->proc;
host = hctx->host;
if (hctx->state == FCGI_STATE_INIT ||
hctx->state == FCGI_STATE_CONNECT_DELAYED) {
if (proc) host->active_procs--;
-@@ -3078,7 +2992,7 @@
+@@ -3078,7 +2998,7 @@
return HANDLER_WAIT_FOR_FD;
} else {
fcgi_connection_close(srv, hctx);
buffer_reset(con->physical.path);
con->mode = DIRECT;
con->http_status = 500;
-@@ -3088,12 +3002,12 @@
+@@ -3088,12 +3008,12 @@
}
} else {
fcgi_connection_close(srv, hctx);
return HANDLER_FINISHED;
}
case HANDLER_WAIT_FOR_EVENT:
-@@ -3115,7 +3029,7 @@
+@@ -3115,7 +3035,7 @@
handler_ctx *hctx = ctx;
connection *con = hctx->remote_conn;
plugin_data *p = hctx->plugin_data;
fcgi_proc *proc = hctx->proc;
fcgi_extension_host *host= hctx->host;
-@@ -3125,8 +3039,8 @@
+@@ -3125,8 +3045,8 @@
case 0:
break;
case 1:
(con->http_status == 200 ||
con->http_status == 0)) {
/*
-@@ -3136,26 +3050,26 @@
+@@ -3136,26 +3056,26 @@
*/
buffer_copy_string_buffer(con->physical.doc_root, host->docroot);
switch(waitpid(proc->pid, &status, WNOHANG)) {
case 0:
/* child is still alive */
-@@ -3165,60 +3079,61 @@
+@@ -3165,60 +3085,61 @@
default:
/* the child should not terminate at all */
if (WIFEXITED(status)) {
connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
buffer_reset(con->physical.path);
con->http_status = 500;
-@@ -3226,76 +3141,76 @@
+@@ -3226,76 +3147,76 @@
} else {
/* response might have been already started, kill the connection */
fcgi_connection_close(srv, hctx);
"fcgi: got a FDEVENT_ERR. Don't know why.");
/* kill all connections to the fastcgi process */
-@@ -3304,45 +3219,42 @@
+@@ -3304,45 +3225,42 @@
fcgi_connection_close(srv, hctx);
joblist_append(srv, con);
}
static handler_t fcgi_check_extension(server *srv, connection *con, void *p_d, int uri_path_handler) {
plugin_data *p = p_d;
-@@ -3351,16 +3263,16 @@
+@@ -3351,16 +3269,16 @@
buffer *fn;
fcgi_extension *extension = NULL;
fcgi_extension_host *host = NULL;
fcgi_patch_connection(srv, con, p);
/* fastcgi.map-extensions maps extensions to existing fastcgi.server entries
-@@ -3368,24 +3280,24 @@
+@@ -3368,24 +3286,24 @@
* fastcgi.map-extensions = ( ".php3" => ".php" )
*
* fastcgi.server = ( ".php" => ... )
/* we can reuse k here */
for (k = 0; k < p->conf.exts->used; k++) {
extension = p->conf.exts->exts[k];
-@@ -3407,15 +3319,15 @@
+@@ -3407,15 +3325,15 @@
/* check if extension matches */
for (k = 0; k < p->conf.exts->used; k++) {
size_t ct_len; /* length of the config entry */
/* check extension in the form "/fcgi_pattern" */
if (*(extension->key->ptr) == '/' && strncmp(fn->ptr, extension->key->ptr, ct_len) == 0) {
break;
-@@ -3441,10 +3353,10 @@
+@@ -3441,10 +3359,10 @@
continue;
}
if (!host) {
/* sorry, we don't have a server alive for this ext */
buffer_reset(con->physical.path);
-@@ -3459,72 +3371,72 @@
+@@ -3459,72 +3377,72 @@
"on", extension->key,
"are down.");
}
con->uri.path->used -= con->request.pathinfo->used - 1;
con->uri.path->ptr[con->uri.path->used - 1] = '\0';
}
-@@ -3532,19 +3444,19 @@
+@@ -3532,19 +3450,19 @@
} else {
handler_ctx *hctx;
hctx = handler_ctx_init();
if (con->conf.log_request_handling) {
log_error_write(srv, __FILE__, __LINE__, "s", "handling it in mod_fastcgi");
}
-@@ -3566,19 +3478,19 @@
+@@ -3566,19 +3484,19 @@
JOBLIST_FUNC(mod_fastcgi_handle_joblist) {
plugin_data *p = p_d;
handler_ctx *hctx = con->plugin_ctx[p->id];
+
if (hctx == NULL) return HANDLER_GO_ON;
- if (hctx->fd != -1) {
+- if (hctx->fd != -1) {
++ if (hctx->sock->fd != -1) {
switch (hctx->state) {
case FCGI_STATE_READ:
- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
+- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
-
++ fdevent_event_add(srv->ev, hctx->sock, FDEVENT_IN);
+
break;
case FCGI_STATE_CONNECT_DELAYED:
case FCGI_STATE_WRITE:
- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
+- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
-
++ fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
+
break;
case FCGI_STATE_INIT:
/* at reconnect */
-@@ -3595,7 +3507,7 @@
+@@ -3595,7 +3513,7 @@
static handler_t fcgi_connection_close_callback(server *srv, connection *con, void *p_d) {
plugin_data *p = p_d;
fcgi_connection_close(srv, con->plugin_ctx[p->id]);
return HANDLER_GO_ON;
-@@ -3604,16 +3516,39 @@
+@@ -3604,16 +3522,39 @@
TRIGGER_FUNC(mod_fastcgi_handle_trigger) {
plugin_data *p = p_d;
size_t i, j, n;
/* check all childs if they are still up */
for (i = 0; i < srv->config_context->used; i++) {
-@@ -3628,45 +3563,45 @@
+@@ -3628,45 +3569,45 @@
fcgi_extension *ex;
ex = exts->exts[j];
if (buffer_is_empty(host->unixsocket)) {
proc->port = host->port + proc->id;
} else {
-@@ -3674,13 +3609,13 @@
+@@ -3674,13 +3615,13 @@
buffer_append_string(proc->unixsocket, "-");
buffer_append_long(proc->unixsocket, proc->id);
}
proc->prev = NULL;
proc->next = host->first;
if (host->first) {
-@@ -3688,56 +3623,56 @@
+@@ -3688,56 +3629,56 @@
}
host->first = proc;
}
switch (waitpid(proc->pid, &status, WNOHANG)) {
case 0:
/* child still running after timeout, good */
-@@ -3745,10 +3680,10 @@
+@@ -3745,10 +3686,10 @@
case -1:
if (errno != EINTR) {
/* no PID found ? should never happen */
#if 0
if (errno == ECHILD) {
/* someone else has cleaned up for us */
-@@ -3762,25 +3697,26 @@
+@@ -3762,25 +3703,26 @@
/* the child should not terminate at all */
if (WIFEXITED(status)) {
if (proc->state != PROC_STATE_KILLED) {
}
}
}
-@@ -3804,8 +3740,8 @@
+@@ -3804,8 +3746,8 @@
p->handle_subrequest = mod_fastcgi_handle_subrequest;
p->handle_joblist = mod_fastcgi_handle_joblist;
p->handle_trigger = mod_fastcgi_handle_trigger;
return 0;
}
--- ../lighttpd-1.4.11/src/mod_flv_streaming.c 2006-03-07 14:06:26.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_flv_streaming.c 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/mod_flv_streaming.c 2006-07-16 00:26:04.000000000 +0300
@@ -23,35 +23,35 @@
typedef struct {
return 0;
}
--- ../lighttpd-1.4.11/src/mod_indexfile.c 2005-09-30 01:08:53.000000000 +0300
-+++ lighttpd-1.4.12/src/mod_indexfile.c 2006-07-15 22:43:21.000000000 +0300
++++ lighttpd-1.4.12/src/mod_indexfile.c 2006-07-16 00:26:04.000000000 +0300
@@ -12,6 +12,8 @@
#include "stat_cache.h"
return 0;
}
--- ../lighttpd-1.4.11/src/mod_mysql_vhost.c 2006-01-14 20:35:10.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_mysql_vhost.c 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/mod_mysql_vhost.c 2006-07-16 00:26:04.000000000 +0300
@@ -1,13 +1,18 @@
-#include <unistd.h>
#include <stdio.h>
}
#else
--- ../lighttpd-1.4.11/src/mod_proxy.c 2006-01-31 13:01:22.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_proxy.c 2006-07-15 22:43:21.000000000 +0300
++++ lighttpd-1.4.12/src/mod_proxy.c 2006-07-18 13:03:40.000000000 +0300
@@ -1,6 +1,5 @@
#include <sys/types.h>
} proxy_connection_state_t;
enum { PROXY_STDOUT, PROXY_END_REQUEST };
-@@ -93,19 +107,17 @@
+@@ -93,19 +107,16 @@
typedef struct {
proxy_connection_state_t state;
time_t state_timestamp;
chunkqueue *wb;
-
+- int fd; /* fd to the proxy process */
+- int fde_ndx; /* index into the fd-event buffer */
+ chunkqueue *rb;
+
- int fd; /* fd to the proxy process */
- int fde_ndx; /* index into the fd-event buffer */
++ iosocket *fd; /* fd to the proxy process */
size_t path_info_offset; /* start of path_info in uri.path */
-
connection *remote_conn; /* dump pointer */
plugin_data *plugin_data; /* dump pointer */
} handler_ctx;
-@@ -116,69 +128,88 @@
+@@ -116,69 +127,89 @@
static handler_ctx * handler_ctx_init() {
handler_ctx * hctx;
hctx->wb = chunkqueue_init();
+ hctx->rb = chunkqueue_init();
++
++ hctx->fd = iosocket_init();
- hctx->fd = -1;
- hctx->fde_ndx = -1;
+- hctx->fd = -1;
+- hctx->fde_ndx = -1;
-
-+
return hctx;
}
chunkqueue_free(hctx->wb);
-
+ chunkqueue_free(hctx->rb);
++
++ iosocket_free(hctx->fd);
+
free(hctx);
}
array_insert_unique(dfa->value, (data_unset *)df);
array_insert_unique(s->extensions, (data_unset *)dfa);
} else {
-@@ -328,19 +360,19 @@
+@@ -328,67 +360,76 @@
}
}
}
-
+
if (hctx->fd != -1) {
- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
+- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
++ fdevent_event_del(srv->ev, hctx->fd);
fdevent_unregister(srv->ev, hctx->fd);
-@@ -348,47 +380,56 @@
- close(hctx->fd);
+
+- close(hctx->fd);
++ close(hctx->fd->fd);
srv->cur_fds--;
}
-
+
plugin_data *p = hctx->plugin_data;
data_proxy *host= hctx->host;
- int proxy_fd = hctx->fd;
+- int proxy_fd = hctx->fd;
-
++ int proxy_fd = hctx->fd->fd;
+
memset(&proxy_addr, 0, sizeof(proxy_addr));
-
+
+ if (buffer_is_empty(ds->value) || buffer_is_empty(ds->key)) continue;
+
-+ if (!buffer_is_equal_string(ds->key, CONST_STR_LEN("Connection"))) continue;
-+ if (!buffer_is_equal_string(ds->key, CONST_STR_LEN("Keep-Alive"))) continue;
++ if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Connection"))) continue;
++ if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Keep-Alive"))) continue;
+
+ buffer_append_string_buffer(b, ds->key);
+ BUFFER_APPEND_STRING_CONST(b, ": ");
switch (req_c->type) {
case FILE_CHUNK:
-@@ -507,223 +550,161 @@
+@@ -507,223 +550,150 @@
req_c->offset += weHave;
req_cq->bytes_out += weHave;
hctx->state = state;
hctx->state_timestamp = srv->cur_ts;
-
-+
- return 0;
- }
-
+- return 0;
+-}
+-
-static int proxy_response_parse(server *srv, connection *con, plugin_data *p, buffer *in) {
- char *s, *ns;
- int http_response_status = -1;
-
- UNUSED(srv);
-+static void chunkqueue_print(chunkqueue *cq) {
-+ chunk *c;
-
+-
- /* \r\n -> \0\0 */
-
- buffer_copy_string_buffer(p->parse_response, in);
-
- array_insert_unique(con->response.headers, (data_unset *)ds);
- }
-+ for (c = cq->first; c; c = c->next) {
-+ fprintf(stderr, "%s", c->mem->ptr + c->offset);
- }
+- }
-
-- return 0;
-+ fprintf(stderr, "\r\n");
+ return 0;
}
--
+
static int proxy_demux_response(server *srv, handler_ctx *hctx) {
- int fin = 0;
- int b;
-
plugin_data *p = hctx->plugin_data;
connection *con = hctx->remote_conn;
- int proxy_fd = hctx->fd;
+- int proxy_fd = hctx->fd;
-
- /* check how much we have to read */
- if (ioctl(hctx->fd, FIONREAD, &b)) {
+ chunkqueue *next_queue = NULL;
+ chunk *c = NULL;
+
-+ switch(srv->network_backend_read(srv, con, proxy_fd, hctx->rb)) {
++ switch(srv->network_backend_read(srv, con, hctx->fd, hctx->rb)) {
+ case NETWORK_STATUS_SUCCESS:
+ /* we got content */
+ break;
+ case NETWORK_STATUS_WAIT_FOR_EVENT:
-+ /* the ioctl will return WAIT_FOR_EVENT on a read */
-+ if (0 == con->file_started) return -1;
++ return 0;
+ case NETWORK_STATUS_CONNECTION_CLOSE:
+ /* we are done, get out of here */
+ con->file_finished = 1;
+ /* some headers are ignored by default */
+ for (j = 0; ign[j]; j++) {
+ if (0 == strcasecmp(ign[j], header->key->ptr)) break;
- }
--
-- con->file_started = 1;
-- if (blen) {
-- http_chunk_append_mem(srv, con, c + 4, blen + 1);
-- joblist_append(srv, con);
++ }
+ if (ign[j]) continue;
+
+ if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Location"))) {
+ } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Content-Length"))) {
+ have_content_length = 1;
}
-- hctx->response->used = 0;
+-
+- con->file_started = 1;
+- if (blen) {
+- http_chunk_append_mem(srv, con, c + 4, blen + 1);
+- joblist_append(srv, con);
+
+ if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
+ ds = data_response_init();
-+ }
+ }
+- hctx->response->used = 0;
+ buffer_copy_string_buffer(ds->key, header->key);
+ buffer_copy_string_buffer(ds->value, header->value);
+
}
-@@ -731,12 +712,12 @@
+@@ -731,32 +701,32 @@
data_proxy *host= hctx->host;
plugin_data *p = hctx->plugin_data;
connection *con = hctx->remote_conn;
+
switch(hctx->state) {
case PROXY_STATE_INIT:
- if (-1 == (hctx->fd = socket(AF_INET, SOCK_STREAM, 0))) {
-@@ -744,19 +725,19 @@
+- if (-1 == (hctx->fd = socket(AF_INET, SOCK_STREAM, 0))) {
++ if (-1 == (hctx->fd->fd = socket(AF_INET, SOCK_STREAM, 0))) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed: ", strerror(errno));
return HANDLER_ERROR;
}
- hctx->fde_ndx = -1;
+- hctx->fde_ndx = -1;
-
++ hctx->fd->fde_ndx = -1;
+
srv->cur_fds++;
-
case PROXY_STATE_CONNECT:
/* try to finish the connect() */
if (hctx->state == PROXY_STATE_INIT) {
-@@ -764,16 +745,16 @@
+@@ -764,16 +734,16 @@
switch (proxy_establish_connection(srv, hctx)) {
case 1:
proxy_set_state(srv, hctx, PROXY_STATE_CONNECT);
+
/* connection is in progress, wait for an event and call getsockopt() below */
-
-+
- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
+- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
-
++
++ fdevent_event_add(srv->ev, hctx->fd, FDEVENT_OUT);
+
return HANDLER_WAIT_FOR_EVENT;
case -1:
/* if ECONNREFUSED choose another connection -> FIXME */
- hctx->fde_ndx = -1;
+- hctx->fde_ndx = -1;
-
++ hctx->fd->fde_ndx = -1;
+
return HANDLER_ERROR;
default:
/* everything is ok, go on */
-@@ -782,152 +763,152 @@
+@@ -782,152 +752,152 @@
} else {
int socket_error;
socklen_t socket_error_len = sizeof(socket_error);
-
- /* we don't need it anymore */
+- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
+
+ /* we don't need it anymore */
- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
++ fdevent_event_del(srv->ev, hctx->fd);
/* try to finish the connect() */
- if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
+- if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
- log_error_write(srv, __FILE__, __LINE__, "ss",
++ if (0 != getsockopt(hctx->fd->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
+ log_error_write(srv, __FILE__, __LINE__, "ss",
"getsockopt failed:", strerror(errno));
-
+ return HANDLER_ERROR;
+ case NETWORK_STATUS_WAIT_FOR_EVENT:
+
-+ fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
++ fdevent_event_add(srv->ev, hctx->fd, FDEVENT_OUT);
+
+ return HANDLER_WAIT_FOR_EVENT;
}
- proxy_set_state(srv, hctx, PROXY_STATE_READ);
+ proxy_set_state(srv, hctx, PROXY_STATE_RESPONSE_HEADER);
- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
+- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
+- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
++ fdevent_event_del(srv->ev, hctx->fd);
++ fdevent_event_add(srv->ev, hctx->fd, FDEVENT_IN);
} else {
- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
+- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
-
++ fdevent_event_add(srv->ev, hctx->fd, FDEVENT_OUT);
+
return HANDLER_WAIT_FOR_EVENT;
}
+ log_error_write(srv, __FILE__, __LINE__, "sbdd", "proxy-server disabled:",
host->host,
host->port,
- hctx->fd);
+- hctx->fd);
-
++ hctx->fd->fd);
+
/* disable this server */
host->is_disabled = 1;
*/
return HANDLER_WAIT_FOR_FD;
-@@ -938,7 +919,7 @@
+@@ -938,7 +908,7 @@
default:
break;
}
if (con->file_started == 1) {
return HANDLER_FINISHED;
} else {
-@@ -951,13 +932,14 @@
+@@ -951,13 +921,14 @@
handler_ctx *hctx = ctx;
connection *con = hctx->remote_conn;
plugin_data *p = hctx->plugin_data;
"proxy: fdevent-in", hctx->state);
}
-@@ -965,11 +947,15 @@
+@@ -965,11 +936,15 @@
case 0:
break;
case 1:
+ log_error_write(srv, __FILE__, __LINE__, "sd",
-+ "proxy: request done", hctx->fd);
++ "proxy: request done", hctx->fd->fd);
hctx->host->usage--;
-
+
joblist_append(srv, con);
return HANDLER_FINISHED;
case -1:
-@@ -982,53 +968,53 @@
+@@ -982,53 +957,53 @@
/* response might have been already started, kill the connection */
connection_set_state(srv, con, CON_STATE_ERROR);
}
return HANDLER_FINISHED;
}
-@@ -1038,13 +1024,13 @@
+@@ -1038,13 +1013,13 @@
joblist_append(srv, con);
} else if (revents & FDEVENT_ERR) {
/* kill all connections to the proxy process */
return HANDLER_FINISHED;
}
-@@ -1058,44 +1044,48 @@
+@@ -1058,44 +1033,48 @@
buffer *fn;
data_array *extension = NULL;
size_t path_info_offset;
if (0 != (pi_offset = strchr(fn->ptr + ct_len + 1, '/'))) {
path_info_offset = pi_offset - fn->ptr;
}
-@@ -1106,12 +1096,14 @@
+@@ -1106,12 +1085,14 @@
break;
}
}
log_error_write(srv, __FILE__, __LINE__, "s", "proxy - ext found");
}
-@@ -1120,34 +1112,34 @@
+@@ -1120,34 +1101,34 @@
/* hash balancing */
if (p->conf.debug) {
}
}
-@@ -1155,19 +1147,20 @@
+@@ -1155,19 +1136,20 @@
case PROXY_BALANCE_FAIR:
/* fair balancing */
if (p->conf.debug) {
}
}
-@@ -1175,89 +1168,100 @@
+@@ -1175,89 +1157,100 @@
case PROXY_BALANCE_RR:
/* round robin */
if (p->conf.debug) {
proxy_connection_close(srv, con->plugin_ctx[p->id]);
return HANDLER_GO_ON;
-@@ -1276,11 +1280,11 @@
+@@ -1276,11 +1269,11 @@
size_t i, n, k;
for (i = 0; i < srv->config_context->used; i++) {
plugin_config *s = p->config_storage[i];
for (k = 0; k < s->extensions->used; k++) {
data_array *extension = (data_array *)s->extensions->data[k];
-@@ -1290,8 +1294,8 @@
+@@ -1290,8 +1283,8 @@
if (!host->is_disabled ||
srv->cur_ts - host->disable_ts < 5) continue;
"proxy - re-enabled:",
host->host, host->port);
-@@ -1317,8 +1321,8 @@
+@@ -1317,8 +1310,8 @@
p->handle_uri_clean = mod_proxy_check_extension;
p->handle_subrequest = mod_proxy_handle_subrequest;
p->handle_trigger = mod_proxy_trigger;
+
return 0;
}
---- ../lighttpd-1.4.11/src/mod_redirect.c 2006-02-08 15:38:06.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_redirect.c 2006-07-11 22:07:52.000000000 +0300
-@@ -22,35 +22,35 @@
- PLUGIN_DATA;
- buffer *match_buf;
- buffer *location;
--
+--- ../lighttpd-1.4.11/src/mod_proxy_core.c 1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/mod_proxy_core.c 2006-07-18 13:03:40.000000000 +0300
+@@ -0,0 +1,1451 @@
++#include <string.h>
++#include <stdlib.h>
++#include <fcntl.h>
++#include <errno.h>
+
- plugin_config **config_storage;
--
-- plugin_config conf;
++#include "buffer.h"
++#include "array.h"
++#include "log.h"
++
++#include "base.h"
++#include "plugin.h"
++#include "joblist.h"
++#include "sys-files.h"
++#include "inet_ntop_cache.h"
++#include "http_resp.h"
++#include "http_chunk.h"
++#include "crc32.h"
++
++#include "mod_proxy_core_pool.h"
++#include "mod_proxy_core_backend.h"
++#include "mod_proxy_core_backlog.h"
++
++typedef enum {
++ PROXY_PROTOCOL_UNSET,
++ PROXY_PROTOCOL_HTTP,
++ PROXY_PROTOCOL_HTTPS,
++ PROXY_PROTOCOL_FASTCGI,
++ PROXY_PROTOCOL_SCGI
++} proxy_protocol_t;
++
++typedef struct {
++ proxy_backends *backends;
++
++ proxy_backlog *backlog;
++
++ int debug;
++
++ proxy_balance_t balancer;
++ proxy_protocol_t protocol;
++} plugin_config;
++
++typedef struct {
++ PLUGIN_DATA;
++
++ http_resp *resp;
++
++ array *possible_balancers;
++ array *possible_protocols;
++
++ /* for parsing only */
++ array *backends_arr;
++ buffer *protocol_buf;
++ buffer *balance_buf;
++
++ plugin_config **config_storage;
+
+ plugin_config conf;
- } plugin_data;
-
- INIT_FUNC(mod_redirect_init) {
- plugin_data *p;
--
++} plugin_data;
+
- p = calloc(1, sizeof(*p));
--
++int array_insert_int(array *a, const char *key, int val) {
++ data_integer *di;
+
- p->match_buf = buffer_init();
- p->location = buffer_init();
--
++ if (NULL == (di = (data_integer *)array_get_unused_element(a, TYPE_INTEGER))) {
++ di = data_integer_init();
++ }
+
- return p;
- }
-
- FREE_FUNC(mod_redirect_free) {
- plugin_data *p = p_d;
--
++ buffer_copy_string(di->key, key);
++ di->value = val;
++ array_insert_unique(a, (data_unset *)di);
+
- if (!p) return HANDLER_GO_ON;
-
- if (p->config_storage) {
- size_t i;
- for (i = 0; i < srv->config_context->used; i++) {
- plugin_config *s = p->config_storage[i];
--
++ return 0;
++}
+
- pcre_keyvalue_buffer_free(s->redirect);
--
++INIT_FUNC(mod_proxy_core_init) {
++ plugin_data *p;
+
- free(s);
- }
- free(p->config_storage);
-@@ -59,9 +59,9 @@
-
- buffer_free(p->match_buf);
- buffer_free(p->location);
--
++ p = calloc(1, sizeof(*p));
+
- free(p);
--
++ /* create some backends as long as we don't have the config-parser */
+
- return HANDLER_GO_ON;
- }
-
-@@ -69,195 +69,137 @@
- plugin_data *p = p_d;
- data_unset *du;
- size_t i = 0;
--
-- config_values_t cv[] = {
++ p->possible_balancers = array_init();
++ array_insert_int(p->possible_balancers, "fair", PROXY_BALANCE_FAIR);
++ array_insert_int(p->possible_balancers, "hash", PROXY_BALANCE_RR);
++ array_insert_int(p->possible_balancers, "round-robin", PROXY_BALANCE_HASH);
++
++ p->possible_protocols = array_init();
++ array_insert_int(p->possible_protocols, "http", PROXY_PROTOCOL_HTTP);
++ array_insert_int(p->possible_protocols, "fastcgi", PROXY_PROTOCOL_FASTCGI);
++ array_insert_int(p->possible_protocols, "scgi", PROXY_PROTOCOL_SCGI);
++ array_insert_int(p->possible_protocols, "https", PROXY_PROTOCOL_HTTPS);
++
++ p->balance_buf = buffer_init();
++ p->protocol_buf = buffer_init();
++ p->backends_arr = array_init();
++
++ p->resp = http_response_init();
++
++ return p;
++}
++
++FREE_FUNC(mod_proxy_core_free) {
++ plugin_data *p = p_d;
++
++ if (!p) return HANDLER_GO_ON;
++
++ if (p->config_storage) {
++ size_t i;
++ for (i = 0; i < srv->config_context->used; i++) {
++ plugin_config *s = p->config_storage[i];
++
++ if (!s) continue;
++
++ proxy_backends_free(s->backends);
++ proxy_backlog_free(s->backlog);
++
++
++ free(s);
++ }
++ free(p->config_storage);
++ }
++
++ array_free(p->possible_protocols);
++ array_free(p->possible_balancers);
++ array_free(p->backends_arr);
++
++ buffer_free(p->balance_buf);
++ buffer_free(p->protocol_buf);
++
++ http_response_free(p->resp);
++
++ free(p);
++
++ return HANDLER_GO_ON;
++}
++
++SETDEFAULTS_FUNC(mod_proxy_core_set_defaults) {
++ plugin_data *p = p_d;
++ size_t i, j;
+
+ config_values_t cv[] = {
- { "url.redirect", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
- { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
- };
--
++ { "proxy-core.backends", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
++ { "proxy-core.debug", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
++ { "proxy-core.balancer", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
++ { "proxy-core.protocol", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 3 */
++ { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
++ };
+
- if (!p) return HANDLER_ERROR;
--
++ p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
+
- /* 0 */
- p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
--
++ for (i = 0; i < srv->config_context->used; i++) {
++ plugin_config *s;
++ array *ca;
++ proxy_backend *backend;
+
- for (i = 0; i < srv->config_context->used; i++) {
- plugin_config *s;
- size_t j;
- array *ca;
- data_array *da = (data_array *)du;
--
++ array_reset(p->backends_arr);
++ buffer_reset(p->balance_buf);
++ buffer_reset(p->protocol_buf);
+
- s = calloc(1, sizeof(plugin_config));
- s->redirect = pcre_keyvalue_buffer_init();
--
++ s = malloc(sizeof(plugin_config));
++ s->debug = 0;
++ s->balancer = PROXY_BALANCE_UNSET;
++ s->protocol = PROXY_PROTOCOL_UNSET;
++ s->backends = proxy_backends_init();
++ s->backlog = proxy_backlog_init();
+
- cv[0].destination = s->redirect;
--
++ cv[0].destination = p->backends_arr;
++ cv[1].destination = &(s->debug);
++ cv[2].destination = p->balance_buf; /* parse into a constant */
++ cv[3].destination = p->protocol_buf; /* parse into a constant */
+
- p->config_storage[i] = s;
- ca = ((data_config *)srv->config_context->data[i])->value;
--
++ buffer_reset(p->balance_buf);
+
- if (0 != config_insert_values_global(srv, ca, cv)) {
- return HANDLER_ERROR;
- }
--
++ p->config_storage[i] = s;
++ ca = ((data_config *)srv->config_context->data[i])->value;
+
- if (NULL == (du = array_get_element(ca, "url.redirect"))) {
- /* no url.redirect defined */
- continue;
- }
--
++ if (0 != config_insert_values_global(srv, ca, cv)) {
++ return HANDLER_ERROR;
++ }
+
- if (du->type != TYPE_ARRAY) {
-- log_error_write(srv, __FILE__, __LINE__, "sss",
-+ log_error_write(srv, __FILE__, __LINE__, "sss",
- "unexpected type for key: ", "url.redirect", "array of strings");
--
++ if (!buffer_is_empty(p->balance_buf)) {
++ data_integer *di;
++
++ if (NULL == (di = (data_integer *)array_get_element(p->possible_balancers, BUF_STR(p->balance_buf)))) {
++ ERROR("proxy.balance has to be on of 'fair', 'round-robin', 'hash', got %s", BUF_STR(p->balance_buf));
+
- return HANDLER_ERROR;
- }
--
++ return HANDLER_ERROR;
++ }
+
- da = (data_array *)du;
--
++ s->balancer = di->value;
++ }
+
- for (j = 0; j < da->value->used; j++) {
- if (da->value->data[j]->type != TYPE_STRING) {
-- log_error_write(srv, __FILE__, __LINE__, "sssbs",
-- "unexpected type for key: ",
-- "url.redirect",
-+ log_error_write(srv, __FILE__, __LINE__, "sssbs",
-+ "unexpected type for key: ",
-+ "url.redirect",
- "[", da->value->data[j]->key, "](string)");
--
++ if (!buffer_is_empty(p->protocol_buf)) {
++ data_integer *di;
++
++ if (NULL == (di = (data_integer *)array_get_element(p->possible_protocols, BUF_STR(p->protocol_buf)))) {
++ ERROR("proxy.balance has to be on of 'fair', 'round-robin', 'hash', got %s", BUF_STR(p->protocol_buf));
+
- return HANDLER_ERROR;
- }
--
-- if (0 != pcre_keyvalue_buffer_append(s->redirect,
++ return HANDLER_ERROR;
++ }
+
-+ if (0 != pcre_keyvalue_buffer_append(s->redirect,
- ((data_string *)(da->value->data[j]))->key->ptr,
- ((data_string *)(da->value->data[j]))->value->ptr)) {
--
-- log_error_write(srv, __FILE__, __LINE__, "sb",
++ s->protocol = di->value;
++ }
+
-+ log_error_write(srv, __FILE__, __LINE__, "sb",
- "pcre-compile failed for", da->value->data[j]->key);
- }
- }
- }
--
++ backend = proxy_backend_init();
+
- return HANDLER_GO_ON;
- }
- #ifdef HAVE_PCRE_H
- static int mod_redirect_patch_connection(server *srv, connection *con, plugin_data *p) {
- size_t i, j;
- plugin_config *s = p->config_storage[0];
--
++ /* check if the backends have a valid host-name */
++ for (j = 0; j < p->backends_arr->used; j++) {
++ data_string *ds = (data_string *)p->backends_arr->data[j];
+
- p->conf.redirect = s->redirect;
--
++ /* the values should be ips or hostnames */
++ if (0 != proxy_address_pool_add_string(backend->address_pool, ds->value)) {
++ return HANDLER_ERROR;
++ }
++ }
+
- /* skip the first, the global context */
- for (i = 1; i < srv->config_context->used; i++) {
- data_config *dc = (data_config *)srv->config_context->data[i];
- s = p->config_storage[i];
--
++ proxy_backends_add(s->backends, backend);
++ }
+
- /* condition didn't match */
- if (!config_check_cond(srv, con, dc)) continue;
--
++ return HANDLER_GO_ON;
++}
+
- /* merge config */
- for (j = 0; j < dc->value->used; j++) {
- data_unset *du = dc->value->data[j];
--
+
- if (0 == strcmp(du->key->ptr, "url.redirect")) {
- p->conf.redirect = s->redirect;
- p->conf.context = dc;
- }
- }
- }
--
++typedef enum {
++ PROXY_STATE_UNSET,
++ PROXY_STATE_CONNECTING,
++ PROXY_STATE_CONNECTED,
++ PROXY_STATE_WRITE_REQUEST_HEADER,
++ PROXY_STATE_WRITE_REQUEST_BODY,
++ PROXY_STATE_READ_RESPONSE_HEADER,
++ PROXY_STATE_READ_RESPONSE_BODY
++} proxy_state_t;
+
- return 0;
- }
- #endif
- static handler_t mod_redirect_uri_handler(server *srv, connection *con, void *p_data) {
- #ifdef HAVE_PCRE_H
- plugin_data *p = p_data;
-- size_t i;
-+ int i;
-
-- /*
-+ /*
- * REWRITE URL
-- *
-+ *
- * e.g. redirect /base/ to /index.php?section=base
-- *
++typedef struct {
++ proxy_connection *proxy_con;
++ proxy_backend *proxy_backend;
++
++ connection *remote_con;
++
++ array *request_headers;
++
++ int is_chunked;
++
++ /**
++ * chunkqueues
++ * - the encoded_rb is the raw network stuff
++ * - the rb is filtered through the stream decoder
+ *
- */
--
++ * - wb is the normal bytes stream
++ * - encoded_wb is encoded for the network by the stream encoder
++ */
++ chunkqueue *recv;
++ chunkqueue *recv_raw;
++ chunkqueue *send_raw;
++ chunkqueue *send;
++
++ off_t bytes_read;
++ off_t content_length;
+
- mod_redirect_patch_connection(srv, con, p);
--
++ proxy_state_t state;
++} proxy_session;
+
- buffer_copy_string_buffer(p->match_buf, con->request.uri);
--
-- for (i = 0; i < p->conf.redirect->used; i++) {
-- pcre *match;
-- pcre_extra *extra;
-- const char *pattern;
-- size_t pattern_len;
-- int n;
-- pcre_keyvalue *kv = p->conf.redirect->kv[i];
--# define N 10
-- int ovec[N * 3];
--
-- match = kv->key;
-- extra = kv->key_extra;
-- pattern = kv->value->ptr;
-- pattern_len = kv->value->used - 1;
--
-- if ((n = pcre_exec(match, extra, p->match_buf->ptr, p->match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) {
-- if (n != PCRE_ERROR_NOMATCH) {
-- log_error_write(srv, __FILE__, __LINE__, "sd",
-- "execution error while matching: ", n);
++proxy_session *proxy_session_init(void) {
++ proxy_session *sess;
++
++ sess = calloc(1, sizeof(*sess));
++
++ sess->state = PROXY_STATE_UNSET;
++ sess->request_headers = array_init();
++
++ sess->recv = chunkqueue_init();
++ sess->recv_raw = chunkqueue_init();
++ sess->send_raw = chunkqueue_init();
++ sess->send = chunkqueue_init();
++
++ sess->is_chunked = 0;
++
++ return sess;
++}
++
++void proxy_session_free(proxy_session *sess) {
++ if (!sess) return;
++
++ array_free(sess->request_headers);
++
++ chunkqueue_free(sess->recv);
++ chunkqueue_free(sess->recv_raw);
++ chunkqueue_free(sess->send_raw);
++ chunkqueue_free(sess->send);
++
++ free(sess);
++}
++
++handler_t proxy_connection_connect(proxy_connection *con) {
++ int fd;
++
++ if (-1 == (fd = socket(con->address->addr.plain.sa_family, SOCK_STREAM, 0))) {
++ }
++
++ fcntl(fd, F_SETFL, O_NONBLOCK | O_RDWR);
++
++ con->sock->fd = fd;
++ con->sock->fde_ndx = -1;
++ con->sock->type = IOSOCKET_TYPE_SOCKET;
++
++ if (-1 == connect(fd, &(con->address->addr.plain), sizeof(con->address->addr))) {
++ switch(errno) {
++ case EINPROGRESS:
++ case EALREADY:
++ case EINTR:
++ return HANDLER_WAIT_FOR_EVENT;
++ default:
++ close(fd);
++ con->sock->fd = -1;
++
++ return HANDLER_ERROR;
++ }
++ }
++
++ return HANDLER_GO_ON;
++}
++
++/**
++ * event-handler for idling connections
++ *
++ * unused (idling) keep-alive connections are not bound to a session
++ * and need their own event-handler
++ *
++ * if the connection closes (we get a FDEVENT_IN), close our side too and
++ * let the trigger-func handle the cleanup
++ *
++ * @see proxy_trigger
++ */
++
++
++static handler_t proxy_handle_fdevent_idle(void *s, void *ctx, int revents) {
++ server *srv = (server *)s;
++ proxy_connection *proxy_con = ctx;
++
++ if (revents & FDEVENT_IN) {
++ switch (proxy_con->state) {
++ case PROXY_CONNECTION_STATE_IDLE:
++ proxy_con->state = PROXY_CONNECTION_STATE_CLOSED;
++
++ /* close + unregister have to be in the same call,
++ * otherwise we get a events for a re-opened fd */
++
++ fdevent_event_del(srv->ev, proxy_con->sock);
++
++ break;
++ case PROXY_CONNECTION_STATE_CLOSED:
++ /* poll() is state-driven, we will get events as long as it isn't disabled
++ * the close() above should disable the events too */
++ ERROR("%s", "hurry up buddy, I got another event for a closed idle-connection");
++ break;
++ default:
++ ERROR("invalid connection state: %d, should be idle", proxy_con->state);
++ break;
++ }
++ }
++
++ return HANDLER_GO_ON;
++}
++
++void chunkqueue_skip(chunkqueue *cq, off_t skip) {
++ chunk *c;
++
++ for (c = cq->first; c && skip; c = c->next) {
++ if (skip > c->mem->used - c->offset - 1) {
++ skip -= c->mem->used - c->offset - 1;
++ } else {
++ c->offset += skip;
++ skip = 0;
++ }
++ }
++
++ return;
++}
++
++int proxy_http_stream_decoder(server *srv, proxy_session *sess, chunkqueue *raw, chunkqueue *decoded) {
++ chunk *c;
++
++ if (sess->is_chunked) {
++ do {
++ /* the start should always be a chunk-length */
++ off_t chunk_len = 0;
++ char *err = NULL;
++ int chunklen_strlen = 0;
++ char ch;
++ off_t we_have = 0, we_need = 0;
++
++ c = raw->first;
++
++ chunk_len = strtol(BUF_STR(c->mem) + c->offset, &err, 16);
++ if (!(*err == ' ' || *err == '\r' || *err == ';')) {
++ if (*err == '\0') {
++ /* we just need more data */
++ return 0;
++ }
++ return -1;
++ }
++
++ if (chunk_len < 0) {
++ ERROR("chunk_len is negative: %Ld", chunk_len);
++ return -1;
++ }
++
++ chunklen_strlen = err - (BUF_STR(c->mem) + c->offset);
++ chunklen_strlen++; /* skip the err-char */
++
++ do {
++ ch = BUF_STR(c->mem)[c->offset + chunklen_strlen];
++
++ switch (ch) {
++ case '\n':
++ case '\0':
++ /* bingo, chunk-header is finished */
++ break;
++ default:
++ break;
++ }
++ chunklen_strlen++;
++ } while (ch != '\n' && c != '\0');
++
++ if (ch != '\n') {
++ ERROR("%s", "missing the CRLF");
++ return 0;
++ }
++
++ we_need = chunk_len + chunklen_strlen + 2;
++ /* do we have the full chunk ? */
++ for (c = raw->first; c; c = c->next) {
++ we_have += c->mem->used - 1 - c->offset;
++
++ /* we have enough, jump out */
++ if (we_have > we_need) break;
++ }
++
++ /* get more data */
++ if (we_have < we_need) {
++ return 0;
++ }
++
++ /* skip the chunk-header */
++ chunkqueue_skip(raw, chunklen_strlen);
++
++ /* final chunk */
++ if (chunk_len == 0) {
++ chunkqueue_skip(raw, 2);
++
++ return 1;
++ }
++
++ /* we have enough, copy the data */
++ for (c = raw->first; c && chunk_len; c = c->next) {
++ off_t we_want = 0;
++ buffer *b = chunkqueue_get_append_buffer(decoded);
++
++ we_want = chunk_len > (c->mem->used - c->offset - 1) ? c->mem->used - c->offset - 1: chunk_len;
++
++ buffer_copy_string_len(b, c->mem->ptr + c->offset, we_want);
++
++ c->offset += we_want;
++ chunk_len -= we_want;
++ }
++
++ /* skip the \r\n */
++ chunkqueue_skip(raw, 2);
++
++ /* we are done, give the connection to someone else */
++ chunkqueue_remove_finished_chunks(raw);
++ } while (1);
++ } else {
++ /* no chunked encoding, ok, perhaps a content-length ? */
++
++ TRACE("content-lenght: %d", sess->content_length);
++
++ chunkqueue_remove_finished_chunks(raw);
++ for (c = raw->first; c; c = c->next) {
++ buffer *b;
++
++ if (c->mem->used == 0) continue;
++
++ b = chunkqueue_get_append_buffer(decoded);
++
++ sess->bytes_read += c->mem->used - c->offset - 1;
++
++ buffer_copy_string_len(b, c->mem->ptr + c->offset, c->mem->used - c->offset - 1);
++
++ c->offset = c->mem->used - 1;
++
++ if (sess->bytes_read == sess->content_length) {
++ break;
++ }
++
++ }
++ if (sess->bytes_read == sess->content_length) {
++ return 1; /* finished */
++ }
++ }
++
++ return 0;
++}
++/* don't call any proxy functions directly */
++static handler_t proxy_handle_fdevent(void *s, void *ctx, int revents) {
++ server *srv = (server *)s;
++ proxy_session *sess = ctx;
++
++ if (revents & FDEVENT_OUT) {
++ switch (sess->state) {
++ case PROXY_STATE_CONNECTING: /* delayed connect */
++ case PROXY_STATE_WRITE_REQUEST_HEADER:
++ case PROXY_STATE_WRITE_REQUEST_BODY:
++ /* we are still connection */
++
++ joblist_append(srv, sess->remote_con);
++ break;
++ default:
++ ERROR("oops, unexpected state for fdevent-out %d", sess->state);
++ break;
++ }
++ } else if (revents & FDEVENT_IN) {
++ chunk *c;
++
++ switch (sess->state) {
++ case PROXY_STATE_READ_RESPONSE_HEADER:
++ /* call our header parser */
++ joblist_append(srv, sess->remote_con);
++ break;
++ case PROXY_STATE_READ_RESPONSE_BODY:
++ /* we should be in the WRITE state now,
++ * just read in the content and forward it to the outgoing connection
++ * */
++
++ chunkqueue_remove_finished_chunks(sess->recv_raw);
++ switch (srv->network_backend_read(srv, sess->remote_con, sess->proxy_con->sock, sess->recv_raw)) {
++ case NETWORK_STATUS_CONNECTION_CLOSE:
++ fdevent_event_del(srv->ev,sess->proxy_con->sock);
++
++ /* the connection is gone
++ * make the connect */
++ sess->remote_con->file_finished = 1;
++ sess->proxy_con->state = PROXY_CONNECTION_STATE_CLOSED;
++
++ case NETWORK_STATUS_SUCCESS:
++ /* read even more, do we have all the content */
++
++ /* how much do we want to read ? */
++
++ /* call stream-decoder (HTTP-chunked, FastCGI, ... ) */
++
++ switch (proxy_http_stream_decoder(srv, sess, sess->recv_raw, sess->recv)) {
++ case 0:
++ /* need more */
++ break;
++ case -1:
++ /* error */
++ break;
++ case 1:
++ /* we are done */
++ sess->remote_con->file_finished = 1;
++
++ break;
++ }
++ chunkqueue_remove_finished_chunks(sess->recv_raw);
++
++ /* copy the content to the next cq */
++ for (c = sess->recv->first; c; c = c->next) {
++ if (c->mem->used == 0) continue;
++
++ http_chunk_append_mem(srv, sess->remote_con, c->mem->ptr + c->offset, c->mem->used - c->offset);
++
++ c->offset = c->mem->used - 1;
++
++ }
++ chunkqueue_remove_finished_chunks(sess->recv);
++
++ if (sess->remote_con->file_finished) {
++ /* send final HTTP-Chunk packet */
++ http_chunk_append_mem(srv, sess->remote_con, NULL, 0);
++ }
++
++ break;
++ default:
++ ERROR("%s", "oops, we failed to read");
++ break;
++ }
++
++ joblist_append(srv, sess->remote_con);
++ break;
++ default:
++ ERROR("oops, unexpected state for fdevent-in %d", sess->state);
++ break;
++ }
++ }
++
++ if (revents & FDEVENT_HUP) {
++ /* someone closed our connection */
++ switch (sess->state) {
++ case PROXY_STATE_CONNECTING:
++ /* let the getsockopt() catch this */
++ joblist_append(srv, sess->remote_con);
++ break;
++ default:
++ ERROR("oops, unexpected state for fdevent-hup %d", sess->state);
++ break;
++ }
++ }
++
++ return HANDLER_GO_ON;
++}
++
++/**
++ * generate a HTTP/1.1 proxy request from the set of request-headers
++ *
++ * TODO: this is HTTP-proxy specific and will be moved moved into a separate backed
++ *
++ */
++int proxy_get_request_chunk(server *srv, connection *con, proxy_session *sess, chunkqueue *cq) {
++ buffer *b;
++ size_t i;
++
++ b = chunkqueue_get_append_buffer(cq);
++
++ /* request line */
++ buffer_copy_string(b, get_http_method_name(con->request.http_method));
++ BUFFER_APPEND_STRING_CONST(b, " ");
++
++ buffer_append_string_buffer(b, con->request.uri);
++ BUFFER_APPEND_STRING_CONST(b, " HTTP/1.1\r\n");
++
++ for (i = 0; i < sess->request_headers->used; i++) {
++ data_string *ds;
++
++ ds = (data_string *)sess->request_headers->data[i];
++
++ buffer_append_string_buffer(b, ds->key);
++ BUFFER_APPEND_STRING_CONST(b, ": ");
++ buffer_append_string_buffer(b, ds->value);
++ BUFFER_APPEND_STRING_CONST(b, "\r\n");
++ }
++
++ BUFFER_APPEND_STRING_CONST(b, "\r\n");
++
++ return 0;
++}
++
++void proxy_set_header(array *hdrs, const char *key, size_t key_len, const char *value, size_t val_len) {
++ data_string *ds_dst;
++
++ if (NULL == (ds_dst = (data_string *)array_get_unused_element(hdrs, TYPE_STRING))) {
++ ds_dst = data_string_init();
++ }
++
++ buffer_copy_string_len(ds_dst->key, key, key_len);
++ buffer_copy_string_len(ds_dst->value, value, val_len);
++ array_insert_unique(hdrs, (data_unset *)ds_dst);
++}
++
++void proxy_append_header(array *hdrs, const char *key, size_t key_len, const char *value, size_t val_len) {
++ data_string *ds_dst;
++
++ if (NULL == (ds_dst = (data_string *)array_get_unused_element(hdrs, TYPE_STRING))) {
++ ds_dst = data_string_init();
++ }
++
++ buffer_copy_string_len(ds_dst->key, key, key_len);
++ buffer_append_string_len(ds_dst->value, value, val_len);
++ array_insert_unique(hdrs, (data_unset *)ds_dst);
++}
++
++
++/**
++ * build the request-header array and call the backend specific request formater
++ * to fill the chunkqueue
++ */
++int proxy_get_request_header(server *srv, connection *con, proxy_session *sess) {
++ /* request line */
++ const char *remote_ip;
++ size_t i;
++
++ remote_ip = inet_ntop_cache_get_ip(srv, &(con->dst_addr));
++ proxy_append_header(sess->request_headers, CONST_STR_LEN("X-Forwarded-For"), remote_ip, strlen(remote_ip));
++
++ /* http_host is NOT is just a pointer to a buffer
++ * which is NULL if it is not set */
++ if (con->request.http_host &&
++ !buffer_is_empty(con->request.http_host)) {
++ proxy_set_header(sess->request_headers, CONST_STR_LEN("X-Host"), CONST_BUF_LEN(con->request.http_host));
++ }
++ if (con->conf.is_ssl) {
++ proxy_set_header(sess->request_headers, CONST_STR_LEN("X-Forwarded-Proto"), CONST_STR_LEN("https"));
++ } else {
++ proxy_set_header(sess->request_headers, CONST_STR_LEN("X-Forwarded-Proto"), CONST_STR_LEN("http"));
++ }
++
++ /* request header */
++ for (i = 0; i < con->request.headers->used; i++) {
++ data_string *ds;
++
++ ds = (data_string *)con->request.headers->data[i];
++
++ if (buffer_is_empty(ds->value) || buffer_is_empty(ds->key)) continue;
++
++ if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Connection"))) continue;
++ if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Keep-Alive"))) continue;
++
++ proxy_set_header(sess->request_headers, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value));
++ }
++
++ proxy_get_request_chunk(srv, con, sess, sess->send_raw);
++
++ return 0;
++}
++
++/**
++ * parse the response header
++ *
++ * NOTE: this can be used by all backends as they all send a HTTP-Response a clean block
++ * - fastcgi needs some decoding for the protocol
++ */
++parse_status_t proxy_parse_response_header(server *srv, connection *con, plugin_data *p, proxy_session *sess, chunkqueue *cq) {
++ int have_content_length = 0;
++ size_t i;
++
++ http_response_reset(p->resp);
++
++ switch (http_response_parse_cq(cq, p->resp)) {
++ case PARSE_ERROR:
++ /* parsing failed */
++
++ return PARSE_ERROR;
++ case PARSE_NEED_MORE:
++ return PARSE_NEED_MORE;
++ case PARSE_SUCCESS:
++ con->http_status = p->resp->status;
++
++ chunkqueue_remove_finished_chunks(cq);
++
++ sess->content_length = -1;
++
++ /* copy the http-headers */
++ for (i = 0; i < p->resp->headers->used; i++) {
++ const char *ign[] = { "Status", "Connection", NULL };
++ size_t j;
++ data_string *ds;
++
++ data_string *header = (data_string *)p->resp->headers->data[i];
++
++ /* some headers are ignored by default */
++ for (j = 0; ign[j]; j++) {
++ if (0 == strcasecmp(ign[j], header->key->ptr)) break;
++ }
++ if (ign[j]) continue;
++
++ if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Location"))) {
++ /* CGI/1.1 rev 03 - 7.2.1.2 */
++ if (con->http_status == 0) con->http_status = 302;
++ } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Content-Length"))) {
++ have_content_length = 1;
++
++ sess->content_length = strtol(header->value->ptr, NULL, 10);
++
++ if (sess->content_length < 0) {
++ return PARSE_ERROR;
++ }
++ } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Transfer-Encoding"))) {
++ if (strstr(header->value->ptr, "chunked")) {
++ sess->is_chunked = 1;
++ }
++ /* ignore the header */
++ continue;
++ }
++
++ if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
++ ds = data_response_init();
++ }
++ buffer_copy_string_buffer(ds->key, header->key);
++ buffer_copy_string_buffer(ds->value, header->value);
++
++ array_insert_unique(con->response.headers, (data_unset *)ds);
++ }
++
++ /* does the client allow us to send chunked encoding ? */
++ if (con->request.http_version == HTTP_VERSION_1_1 &&
++ !have_content_length) {
++ con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
++ }
++
++ break;
++ }
++
++ return PARSE_SUCCESS; /* we have a full header */
++}
++
++/* we are event-driven
++ *
++ * the first entry is connect() call, if the doesn't need a event
++ *
++ * a bit boring
++ * - connect (+ delayed connect)
++ * - write header + content
++ * - read header + content
++ *
++ * as soon as have read the response header we switch con->file_started and return HANDLER_GO_ON to
++ * tell the core we are ready to stream out the content.
++ * */
++handler_t proxy_state_engine(server *srv, connection *con, plugin_data *p, proxy_session *sess) {
++ /* do we have a connection ? */
++
++ if (sess->state == PROXY_STATE_UNSET) {
++ /* we are not started yet */
++ switch(proxy_connection_connect(sess->proxy_con)) {
++ case HANDLER_WAIT_FOR_EVENT:
++ /* waiting on the connect call */
++
++ fdevent_register(srv->ev, sess->proxy_con->sock, proxy_handle_fdevent, sess);
++ fdevent_event_add(srv->ev, sess->proxy_con->sock, FDEVENT_OUT);
++
++ sess->state = PROXY_STATE_CONNECTING;
++ sess->proxy_con->state = PROXY_CONNECTION_STATE_CONNECTING;
++
++ return HANDLER_WAIT_FOR_EVENT;
++ case HANDLER_GO_ON:
++ /* we are connected */
++ sess->state = PROXY_STATE_CONNECTED;
++ sess->proxy_con->state = PROXY_CONNECTION_STATE_CONNECTED;
++ fdevent_register(srv->ev, sess->proxy_con->sock, proxy_handle_fdevent, sess);
++
++ break;
++ case HANDLER_ERROR:
++ default:
++ /* not good, something failed */
++ return HANDLER_ERROR;
++
++ }
++ } else if (sess->state == PROXY_STATE_CONNECTING) {
++ int socket_error;
++ socklen_t socket_error_len = sizeof(socket_error);
++
++ fdevent_event_del(srv->ev, sess->proxy_con->sock);
++
++ if (0 != getsockopt(sess->proxy_con->sock->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
++ ERROR("getsockopt failed:", strerror(errno));
++
++ return HANDLER_ERROR;
++ }
++ if (socket_error != 0) {
++ switch (socket_error) {
++ case ECONNREFUSED:
++ /* there is no-one on the other side */
++ sess->proxy_con->address->disabled_until = srv->cur_ts + 2;
++
++ TRACE("address %s refused us, disabling for 2 sec", sess->proxy_con->address->name->ptr);
++ break;
++ case EHOSTUNREACH:
++ /* there is no-one on the other side */
++ sess->proxy_con->address->disabled_until = srv->cur_ts + 60;
++
++ TRACE("host %s is unreachable, disabling for 60 sec", sess->proxy_con->address->name->ptr);
++ break;
++ default:
++ sess->proxy_con->address->disabled_until = srv->cur_ts + 60;
++
++ TRACE("connected finally failed: %s (%d)", strerror(socket_error), socket_error);
++
++ TRACE("connect to address %s failed and I don't know why, disabling for 10 sec", sess->proxy_con->address->name->ptr);
++
++ break;
++ }
++
++ sess->proxy_con->address->state = PROXY_ADDRESS_STATE_DISABLED;
++
++ sess->proxy_con->state = PROXY_CONNECTION_STATE_CLOSED;
++ return HANDLER_COMEBACK;
++ }
++
++ sess->state = PROXY_STATE_CONNECTED;
++ sess->proxy_con->state = PROXY_CONNECTION_STATE_CONNECTED;
++ }
++
++ if (sess->state == PROXY_STATE_CONNECTED) {
++ /* build the header */
++ proxy_get_request_header(srv, con, sess);
++
++ sess->state = PROXY_STATE_WRITE_REQUEST_HEADER;
++ }
++
++ switch (sess->state) {
++ case PROXY_STATE_WRITE_REQUEST_HEADER:
++ /* create the request-packet */
++ fdevent_event_del(srv->ev, sess->proxy_con->sock);
++
++ switch (srv->network_backend_write(srv, con, sess->proxy_con->sock, sess->send_raw)) {
++ case NETWORK_STATUS_SUCCESS:
++ sess->state = PROXY_STATE_WRITE_REQUEST_BODY;
++ break;
++ case NETWORK_STATUS_WAIT_FOR_EVENT:
++ fdevent_event_add(srv->ev, sess->proxy_con->sock, FDEVENT_OUT);
++
++ return HANDLER_WAIT_FOR_EVENT;
++ case NETWORK_STATUS_CONNECTION_CLOSE:
++ sess->proxy_con->state = PROXY_CONNECTION_STATE_CLOSED;
++
++ /* this connection is closed, restart the request with a new connection */
++
++ return HANDLER_COMEBACK;
++ default:
++ return HANDLER_ERROR;
++ }
++ /* fall through */
++ case PROXY_STATE_WRITE_REQUEST_BODY:
++ fdevent_event_del(srv->ev, sess->proxy_con->sock);
++ sess->state = PROXY_STATE_READ_RESPONSE_HEADER;
++
++ case PROXY_STATE_READ_RESPONSE_HEADER:
++ fdevent_event_del(srv->ev, sess->proxy_con->sock);
++
++ chunkqueue_remove_finished_chunks(sess->recv_raw);
++
++ switch (srv->network_backend_read(srv, con, sess->proxy_con->sock, sess->recv_raw)) {
++ case NETWORK_STATUS_SUCCESS:
++ /* we read everything from the socket, do we have a full header ? */
++
++ switch (proxy_parse_response_header(srv, con, p, sess, sess->recv_raw)) {
++ case PARSE_ERROR:
++ con->http_status = 502; /* bad gateway */
++
++ return HANDLER_FINISHED;
++ case PARSE_NEED_MORE:
++ /* we need more */
++ fdevent_event_add(srv->ev, sess->proxy_con->sock, FDEVENT_IN);
++
++ return HANDLER_WAIT_FOR_EVENT;
++ case PARSE_SUCCESS:
++ break;
++ default:
++ return HANDLER_ERROR;
++ }
++
++ con->file_started = 1;
++
++ sess->state = PROXY_STATE_READ_RESPONSE_BODY;
++
++ /**
++ * set the event to pass the content through to the server
++ *
++ * this triggers the event-handler
++ * @see proxy_handle_fdevent
++ */
++ fdevent_event_add(srv->ev, sess->proxy_con->sock, FDEVENT_IN);
++
++ return HANDLER_GO_ON; /* tell http_response_prepare that we are done with the header */
++ case NETWORK_STATUS_WAIT_FOR_EVENT:
++ fdevent_event_add(srv->ev, sess->proxy_con->sock, FDEVENT_IN);
++ return HANDLER_WAIT_FOR_EVENT;
++ case NETWORK_STATUS_CONNECTION_CLOSE:
++ if (chunkqueue_length(sess->recv_raw) == 0) {
++ /* the connection went away before we got something back */
++ sess->proxy_con->state = PROXY_CONNECTION_STATE_CLOSED;
++
++ /**
++ * we might run into a 'race-condition'
++ *
++ * 1. proxy-con is keep-alive, idling and just being closed (FDEVENT_IN) [fd=27]
++ * 2. new connection comes in, we use the idling connection [fd=14]
++ * 3. we write(), successful [to fd=27]
++ * 3. we read() ... and finally receive the close-event for the connection
++ */
++
++ con->http_status = 500;
++
++ ERROR("++ %s", "oops, connection got closed while we were reading from it");
++ return HANDLER_FINISHED;
++ }
++
++ ERROR("%s", "conn-close after header-read");
++
++ break;
++ default:
++ ERROR("++ %s", "oops, something went wrong while reading");
++ return HANDLER_ERROR;
++ }
++ case PROXY_STATE_READ_RESPONSE_BODY:
++ /* if we do everything right, we won't get call for this state-anymore */
++
++ ERROR("%s", "PROXY_STATE_READ_RESPONSE_BODY");
++
++ break;
++ }
++
++ return HANDLER_GO_ON;
++}
++
++proxy_backend *proxy_get_backend(server *srv, connection *con, plugin_data *p, buffer *uri) {
++ size_t i;
++
++ for (i = 0; i < p->conf.backends->used; i++) {
++ proxy_backend *backend = p->conf.backends->ptr[i];
++
++ return backend;
++ }
++
++ return NULL;
++}
++
++/**
++ * choose a available address from the address-pool
++ *
++ * the backend has different balancers
++ */
++proxy_address *proxy_backend_balance(server *srv, connection *con, proxy_backend *backend) {
++ size_t i;
++ proxy_address_pool *address_pool = backend->address_pool;
++ unsigned long last_max; /* for the HASH balancer */
++ proxy_address *address = NULL, *cur_address = NULL;
++ int active_addresses = 0, rand_ndx;
++
++ switch(backend->balancer) {
++ case PROXY_BALANCE_HASH:
++ /* hash balancing */
++
++ for (i = 0, last_max = ULONG_MAX; i < address_pool->used; i++) {
++ unsigned long cur_max;
++
++ cur_address = address_pool->ptr[i];
++
++ if (cur_address->state != PROXY_ADDRESS_STATE_ACTIVE) continue;
++
++ cur_max = generate_crc32c(CONST_BUF_LEN(con->uri.path)) +
++ generate_crc32c(CONST_BUF_LEN(cur_address->name)) + /* we can cache this */
++ generate_crc32c(CONST_BUF_LEN(con->uri.authority));
++
++ TRACE("hash-election: %s - %s - %s: %ld",
++ con->uri.path->ptr,
++ cur_address->name->ptr,
++ con->uri.authority->ptr,
++ cur_max);
++
++ if (address == NULL || (cur_max > last_max)) {
++ last_max = cur_max;
++
++ address = cur_address;
++ }
++ }
++
++ break;
++ case PROXY_BALANCE_FAIR:
++ /* fair balancing */
++
++ for (i = 0; i < address_pool->used; i++) {
++ cur_address = address_pool->ptr[i];
++
++ if (cur_address->state != PROXY_ADDRESS_STATE_ACTIVE) continue;
++
++ /* the address is up, use it */
++
++ address = cur_address;
++
++ break;
++ }
++
++ break;
++ case PROXY_BALANCE_RR:
++ /* round robin */
++
++ /**
++ * instead of real RoundRobin we just do a RandomSelect
++ *
++ * it is state-less and has the same distribution
++ */
++
++ active_addresses = 0;
++
++ for (i = 0; i < address_pool->used; i++) {
++ cur_address = address_pool->ptr[i];
++
++ if (cur_address->state != PROXY_ADDRESS_STATE_ACTIVE) continue;
++
++ active_addresses++;
++ }
++
++ rand_ndx = (int) (1.0 * active_addresses * rand()/(RAND_MAX));
++
++ active_addresses = 0;
++ for (i = 0; i < address_pool->used; i++) {
++ cur_address = address_pool->ptr[i];
++
++ if (cur_address->state != PROXY_ADDRESS_STATE_ACTIVE) continue;
++
++ address = cur_address;
++
++ if (rand_ndx == active_addresses++) break;
++ }
++
++ break;
++ default:
++ break;
++ }
++
++ return address;
++}
++
++static int mod_proxy_core_patch_connection(server *srv, connection *con, plugin_data *p) {
++ size_t i, j;
++ plugin_config *s = p->config_storage[0];
++
++ /* global defaults */
++ PATCH_OPTION(balancer);
++ PATCH_OPTION(debug);
++ PATCH_OPTION(backends);
++ PATCH_OPTION(backlog);
++ PATCH_OPTION(protocol);
++
++ /* skip the first, the global context */
++ for (i = 1; i < srv->config_context->used; i++) {
++ data_config *dc = (data_config *)srv->config_context->data[i];
++ s = p->config_storage[i];
++
++ /* condition didn't match */
++ if (!config_check_cond(srv, con, dc)) continue;
++
++ /* merge config */
++ for (j = 0; j < dc->value->used; j++) {
++ data_unset *du = dc->value->data[j];
++
++ if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.backends"))) {
++ PATCH_OPTION(backends);
++ PATCH_OPTION(backlog);
++ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.debug"))) {
++ PATCH_OPTION(debug);
++ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.balancer"))) {
++ PATCH_OPTION(balancer);
++ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.protocol"))) {
++ PATCH_OPTION(protocol);
++ }
++ }
++ }
++
++ return 0;
++}
++
++
++SUBREQUEST_FUNC(mod_proxy_core_check_extension) {
++ plugin_data *p = p_d;
++ proxy_session *sess = con->plugin_ctx[p->id]; /* if this is the second round, sess is already prepared */
++
++ /* check if we have a matching conditional for this request */
++
++ if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON;
++
++ mod_proxy_core_patch_connection(srv, con, p);
++
++ /*
++ * 0. build session
++ * 1. get a proxy connection
++ * 2. create the http-request header
++ * 3. stream the content to the backend
++ * 4. wait for http-response header
++ * 5. decode the response + parse the response
++ * 6. stream the response-content to the client
++ * 7. kill session
++ * */
++
++ if (!sess) {
++ /* a session lives for a single request */
++ sess = proxy_session_init();
++
++ con->plugin_ctx[p->id] = sess;
++ con->mode = p->id;
++
++ sess->remote_con = con;
++ }
++
++ switch (sess->state) {
++ case PROXY_STATE_CONNECTING:
++ /* this connections is waited 10 seconds to connect to the backend
++ * and didn't got a successful connection yet, sending timeout */
++ if (srv->cur_ts - con->request_start > 10) {
++ con->http_status = 504; /* gateway timeout */
++
++ if (sess->proxy_con) {
++ /* if we are waiting for a proxy-connection right now, close it */
++ proxy_connection_pool_remove_connection(sess->proxy_backend->pool, sess->proxy_con);
++
++ fdevent_event_del(srv->ev, sess->proxy_con->sock);
++ fdevent_unregister(srv->ev, sess->proxy_con->sock);
++
++ proxy_connection_free(sess->proxy_con);
++
++ sess->proxy_con = NULL;
++ }
++
++ return HANDLER_FINISHED;
++ }
++ default:
++ /* handle-request-timeout, */
++ if (srv->cur_ts - con->request_start > 60) {
++ TRACE("request runs longer than 60sec: current state: %d", sess->state);
++ }
++ break;
++ }
++
++ /* if the WRITE fails from the start, restart the connection */
++ while (1) {
++ if (sess->proxy_con == NULL) {
++ proxy_address *address = NULL;
++ if (NULL == (sess->proxy_backend = proxy_get_backend(srv, con, p, con->uri.path))) {
++ /* no connection pool for this location */
++ SEGFAULT();
++ }
++
++ /**
++ * ask the balancer for the next address and
++ * check the connection pool if we have a connection open
++ * for that address
++ */
++ if (NULL == (address = proxy_backend_balance(srv, con, sess->proxy_backend))) {
++ /* we don't have any backends to connect to */
++ proxy_request *req;
++
++ /* connection pool is full, queue the request for now */
++ req = proxy_request_init();
++ req->added_ts = srv->cur_ts;
++ req->con = con;
++
++ TRACE("backlog: all backends are down, putting %s (%d) into the backlog", BUF_STR(con->uri.path), con->sock->fd);
++ proxy_backlog_push(p->conf.backlog, req);
++
++ /* no, not really a event,
++ * we just want to block the outer loop from stepping forward
++ *
++ * the trigger will bring this connection back into the game
++ * */
++ return HANDLER_WAIT_FOR_EVENT;
++ }
++
++ if (PROXY_CONNECTIONPOOL_FULL == proxy_connection_pool_get_connection(
++ sess->proxy_backend->pool,
++ address,
++ &(sess->proxy_con))) {
++ proxy_request *req;
++
++ /* connection pool is full, queue the request for now */
++ req = proxy_request_init();
++ req->added_ts = srv->cur_ts;
++ req->con = con;
++
++ TRACE("backlog: the con-pool is full, putting %s (%d) into the backlog", con->uri.path->ptr, con->sock->fd);
++ proxy_backlog_push(p->conf.backlog, req);
++
++ /* no, not really a event,
++ * we just want to block the outer loop from stepping forward
++ *
++ * the trigger will bring this connection back into the game
++ * */
++ return HANDLER_WAIT_FOR_EVENT;
++ }
++
++ /* a fresh connection, we need address for it */
++ if (sess->proxy_con->state == PROXY_CONNECTION_STATE_CONNECTING) {
++ sess->state = PROXY_STATE_UNSET;
++ sess->bytes_read = 0;
++ } else {
++ /* we are already connected */
++ sess->state = PROXY_STATE_CONNECTED;
++
++ /* the connection was idling and using the fdevent_idle-handler
++ * switch it back to the normal proxy-event-handler */
++ fdevent_event_del(srv->ev, sess->proxy_con->sock);
++ fdevent_unregister(srv->ev, sess->proxy_con->sock);
++
++ fdevent_register(srv->ev, sess->proxy_con->sock, proxy_handle_fdevent, sess);
++ fdevent_event_add(srv->ev, sess->proxy_con->sock, FDEVENT_IN);
++ }
++ }
++
++ switch (proxy_state_engine(srv, con, p, sess)) {
++ case HANDLER_WAIT_FOR_EVENT:
++ return HANDLER_WAIT_FOR_EVENT;
++ case HANDLER_COMEBACK:
++ proxy_connection_pool_remove_connection(sess->proxy_backend->pool, sess->proxy_con);
++
++ fdevent_event_del(srv->ev, sess->proxy_con->sock);
++ fdevent_unregister(srv->ev, sess->proxy_con->sock);
++
++ proxy_connection_free(sess->proxy_con);
++
++ sess->proxy_con = NULL;
++ /* restart the connection to the backend */
++ TRACE("%s", "write failed, restarting request");
++ break;
++ case HANDLER_GO_ON:
++ return HANDLER_GO_ON;
++ default:
++ return HANDLER_ERROR;
++ }
++ }
++
++ /* should not be reached */
++ return HANDLER_ERROR;
++}
++
++/**
++ * end of the connection to the client
++ */
++REQUESTDONE_FUNC(mod_proxy_connection_close_callback) {
++ plugin_data *p = p_d;
++
++ if (con->mode != p->id) return HANDLER_GO_ON;
++
++ return HANDLER_GO_ON;
++}
++
++/**
++ * end of a request
++ */
++CONNECTION_FUNC(mod_proxy_connection_reset) {
++ plugin_data *p = p_d;
++ proxy_session *sess = con->plugin_ctx[p->id];
++
++ if (con->mode != p->id) return HANDLER_GO_ON;
++
++ if (sess->proxy_con) {
++ switch (sess->proxy_con->state) {
++ case PROXY_CONNECTION_STATE_CONNECTED:
++ sess->proxy_con->state = PROXY_CONNECTION_STATE_IDLE;
++
++ /* ignore events as the FD is idle, we might get a HUP as the remote connection might close */
++ fdevent_event_del(srv->ev, sess->proxy_con->sock);
++ fdevent_unregister(srv->ev, sess->proxy_con->sock);
++
++ fdevent_register(srv->ev, sess->proxy_con->sock, proxy_handle_fdevent_idle, sess->proxy_con);
++ fdevent_event_add(srv->ev, sess->proxy_con->sock, FDEVENT_IN);
++
++ break;
++ case PROXY_CONNECTION_STATE_CLOSED:
++ proxy_connection_pool_remove_connection(sess->proxy_backend->pool, sess->proxy_con);
++
++ fdevent_event_del(srv->ev, sess->proxy_con->sock);
++ fdevent_unregister(srv->ev, sess->proxy_con->sock);
++
++ proxy_connection_free(sess->proxy_con);
++ break;
++ case PROXY_CONNECTION_STATE_IDLE:
++ TRACE("%s", "... connection is already back in the pool");
++ break;
++ default:
++ ERROR("connection is in a unexpected state at close-time: %d", sess->proxy_con->state);
++ break;
++ }
++ } else {
++ /* if we have the connection in the backlog, remove it */
++ proxy_backlog_remove_connection(p->conf.backlog, con);
++ }
++
++
++ proxy_session_free(sess);
++
++ con->plugin_ctx[p->id] = NULL;
++
++ return HANDLER_GO_ON;
++}
++
++
++
++/**
++ * cleanup dead connections once a second
++ *
++ * the idling event-handler can't cleanup connections itself and has to wait until the
++ * trigger cleans up
++ */
++handler_t mod_proxy_trigger_context(server *srv, plugin_config *p) {
++ size_t i, j;
++ proxy_request *req;
++
++ for (i = 0; i < p->backends->used; i++) {
++ proxy_backend *backend = p->backends->ptr[i];
++ proxy_connection_pool *pool = backend->pool;
++ proxy_address_pool *address_pool = backend->address_pool;
++
++ for (j = 0; j < pool->used; ) {
++ proxy_connection *proxy_con = pool->ptr[j];
++
++ /* remove-con is removing the current con and moves the good connections to the left
++ * no need to increment i */
++ if (proxy_con->state == PROXY_CONNECTION_STATE_CLOSED) {
++ proxy_connection_pool_remove_connection(backend->pool, proxy_con);
++
++ fdevent_event_del(srv->ev, proxy_con->sock);
++ fdevent_unregister(srv->ev, proxy_con->sock);
++
++ proxy_connection_free(proxy_con);
++ } else {
++ j++;
++ }
++ }
++
++ /* active the disabled addresses again */
++ for (j = 0; j < address_pool->used; j++) {
++ proxy_address *address = address_pool->ptr[j];
++
++ if (address->state != PROXY_ADDRESS_STATE_DISABLED) continue;
++
++ if (srv->cur_ts > address->disabled_until) {
++ address->disabled_until = 0;
++ address->state = PROXY_ADDRESS_STATE_ACTIVE;
++ }
++ }
++ }
++
++ /* wake up the connections from the backlog */
++ while ((req = proxy_backlog_shift(p->backlog))) {
++ connection *con = req->con;
++
++ joblist_append(srv, con);
++
++ proxy_request_free(req);
++ }
++
++ return HANDLER_GO_ON;
++}
++
++TRIGGER_FUNC(mod_proxy_trigger) {
++ plugin_data *p = p_d;
++ size_t i;
++
++ for (i = 0; i < srv->config_context->used; i++) {
++ mod_proxy_trigger_context(srv, p->config_storage[i]);
++ }
++
++ return HANDLER_GO_ON;
++}
++
++int mod_proxy_core_plugin_init(plugin *p) {
++ p->version = LIGHTTPD_VERSION_ID;
++ p->name = buffer_init_string("mod_proxy_core");
++
++ p->init = mod_proxy_core_init;
++ p->cleanup = mod_proxy_core_free;
++ p->set_defaults = mod_proxy_core_set_defaults;
++ p->handle_uri_clean = mod_proxy_core_check_extension;
++ p->handle_subrequest_start = mod_proxy_core_check_extension;
++ p->handle_subrequest = mod_proxy_core_check_extension;
++ p->connection_reset = mod_proxy_connection_reset;
++ p->handle_connection_close = mod_proxy_connection_close_callback;
++ p->handle_trigger = mod_proxy_trigger;
++
++ p->data = NULL;
++
++ return 0;
++}
+--- ../lighttpd-1.4.11/src/mod_proxy_core.h 1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/mod_proxy_core.h 2006-07-18 13:03:40.000000000 +0300
+@@ -0,0 +1,18 @@
++#ifndef _MOD_PROXY_CORE_H_
++#define _MOD_PROXY_CORE_H_
++
++#include "buffer.h"
++#include "base.h"
++
++#define PROXY_BACKEND_CONNECT_PARAMS \
++ (server *srv, connection *con, void *p_d)
++
++#define PROXY_BACKEND_CONNECT_RETVAL handler_t
++
++#define PROXY_BACKEND_CONNECT(name) \
++ PROXY_BACKEND_CONNECT_RETVAL name PROXY_BACKEND_CONNECT_PARAMS
++
++#define PROXY_BACKEND_CONNECT_PTR(name) \
++ PROXY_BACKEND_CONNECT_RETVAL (* name)PROXY_BACKEND_CONNECT_PARAMS
++
++#endif
+--- ../lighttpd-1.4.11/src/mod_proxy_core_address.c 1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/mod_proxy_core_address.c 2006-07-18 13:03:40.000000000 +0300
+@@ -0,0 +1,85 @@
++#include <stdlib.h>
++#include <string.h>
++
++#include "log.h"
++#include "sys-socket.h"
++#include "mod_proxy_core_address.h"
++
++proxy_address *proxy_address_init(void) {
++ proxy_address *address;
++
++ address = calloc(1, sizeof(*address));
++
++ address->name = buffer_init();
++
++ return address;
++}
++
++void proxy_address_free(proxy_address *address) {
++ if (!address) return;
++
++ buffer_free(address->name);
++
++ free(address);
++}
++
++
++proxy_address_pool *proxy_address_pool_init(void) {
++ proxy_address_pool *address_pool;
++
++ address_pool = calloc(1, sizeof(*address_pool));
++
++ return address_pool;
++}
++
++void proxy_address_pool_free(proxy_address_pool *address_pool) {
++ if (!address_pool) return;
++
++ FOREACH(address_pool, element, proxy_address_free(element))
++
++ free(address_pool);
++}
++
++void proxy_address_pool_add(proxy_address_pool *address_pool, proxy_address *address) {
++ ARRAY_STATIC_PREPARE_APPEND(address_pool);
++
++ address_pool->ptr[address_pool->used++] = address;
++}
++
++int proxy_address_pool_add_string(proxy_address_pool *address_pool, buffer *name) {
++ struct addrinfo *res = NULL, pref, *cur;
++ int ret;
++
++ pref.ai_flags = 0;
++ pref.ai_family = PF_UNSPEC;
++ pref.ai_socktype = SOCK_STREAM;
++ pref.ai_protocol = 0;
++ pref.ai_addrlen = 0;
++ pref.ai_addr = NULL;
++ pref.ai_canonname = NULL;
++ pref.ai_next = NULL;
++
++ if (0 != (ret = getaddrinfo(name->ptr, "80", &pref, &res))) {
++ ERROR("getaddrinfo failed: %s", gai_strerror(ret));
++
++ return -1;
++ }
++
++ for (cur = res; cur; cur = cur->ai_next) {
++ proxy_address *a = proxy_address_init();
++
++ memcpy(&(a->addr), cur->ai_addr, cur->ai_addrlen);
++
++ a->state = PROXY_ADDRESS_STATE_ACTIVE;
++
++ buffer_copy_string(a->name, inet_ntoa(a->addr.ipv4.sin_addr));
++
++ proxy_address_pool_add(address_pool, a);
++ }
++
++ freeaddrinfo(res);
++
++ return 0;
++}
++
++
+--- ../lighttpd-1.4.11/src/mod_proxy_core_address.h 1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/mod_proxy_core_address.h 2006-07-18 13:03:40.000000000 +0300
+@@ -0,0 +1,33 @@
++#ifndef _MOD_PROXY_CORE_ADDRESS_H_
++#define _MOD_PROXY_CORE_ADDRESS_H_
++
++#include <time.h>
++#include "buffer.h"
++#include "sys-socket.h"
++#include "array-static.h"
++
++typedef enum {
++ PROXY_ADDRESS_STATE_UNSET,
++ PROXY_ADDRESS_STATE_ACTIVE,
++ PROXY_ADDRESS_STATE_DISABLED,
++} proxy_address_state_t;
++
++typedef struct {
++ sock_addr addr;
++
++ buffer *name; /* a inet_ntoa() prepresentation of the address */
++
++ time_t last_used;
++ time_t disabled_until;
++
++ proxy_address_state_t state;
++} proxy_address;
++
++ARRAY_STATIC_DEF(proxy_address_pool, proxy_address, );
++
++proxy_address_pool *proxy_address_pool_init(void);
++void proxy_address_pool_free(proxy_address_pool *address_pool);
++void proxy_address_pool_add(proxy_address_pool *address_pool, proxy_address *address);
++int proxy_address_pool_add_string(proxy_address_pool *address_pool, buffer *address);
++
++#endif
+--- ../lighttpd-1.4.11/src/mod_proxy_core_backend.c 1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/mod_proxy_core_backend.c 2006-07-18 13:03:40.000000000 +0300
+@@ -0,0 +1,45 @@
++#include <stdlib.h>
++
++#include "mod_proxy_core_backend.h"
++#include "mod_proxy_core_pool.h"
++#include "mod_proxy_core_address.h"
++
++proxy_backend *proxy_backend_init(void) {
++ proxy_backend *backend;
++
++ backend = calloc(1, sizeof(*backend));
++ backend->pool = proxy_connection_pool_init();
++ backend->address_pool = proxy_address_pool_init();
++ backend->balancer = PROXY_BALANCE_RR;
++
++ return backend;
++}
++
++void proxy_backend_free(proxy_backend *backend) {
++ if (!backend) return;
++
++ proxy_address_pool_free(backend->address_pool);
++ proxy_connection_pool_free(backend->pool);
++
++ free(backend);
++}
++
++proxy_backends *proxy_backends_init(void) {
++ proxy_backends *backends;
++
++ backends = calloc(1, sizeof(*backends));
++
++ return backends;
++}
++
++void proxy_backends_free(proxy_backends *backends) {
++ FOREACH(backends, element, proxy_backend_free(element))
++
++ free(backends);
++}
++
++void proxy_backends_add(proxy_backends *backends, proxy_backend *backend) {
++ ARRAY_STATIC_PREPARE_APPEND(backends);
++
++ backends->ptr[backends->used++] = backend;
++}
+--- ../lighttpd-1.4.11/src/mod_proxy_core_backend.h 1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/mod_proxy_core_backend.h 2006-07-18 13:03:40.000000000 +0300
+@@ -0,0 +1,54 @@
++#ifndef _MOD_PROXY_CORE_BACKEND_H_
++#define _MOD_PROXY_CORE_BACKEND_H_
++
++#include "array-static.h"
++#include "buffer.h"
++#include "mod_proxy_core_address.h"
++#include "mod_proxy_core_pool.h"
++#include "sys-socket.h"
++
++/**
++ * a single DNS name might explode to several IP addresses
++ *
++ * url:
++ * - http://foo.bar/suburl/
++ * - https://foo.bar/suburl/
++ * - unix:/tmp/socket
++ * - tcp://foobar:1025/
++ *
++ * backend:
++ * - scgi
++ * - http
++ * - fastcgi
++ *
++ * request-url-rewrite
++ * response-url-rewrite
++ */
++typedef enum {
++ PROXY_BALANCE_UNSET,
++ PROXY_BALANCE_FAIR,
++ PROXY_BALANCE_HASH,
++ PROXY_BALANCE_RR
++} proxy_balance_t;
++
++typedef struct {
++ buffer *url;
++
++ proxy_connection_pool *pool; /* pool of active connections */
++ int use_keepalive;
++
++ proxy_address_pool *address_pool; /* possible destination-addresses, disabling is done here */
++ proxy_balance_t balancer; /* how to choose a address from the address-pool */
++} proxy_backend;
++
++ARRAY_STATIC_DEF(proxy_backends, proxy_backend, );
++
++proxy_backend *proxy_backend_init(void);
++void proxy_backend_free(proxy_backend *backend);
++
++proxy_backends *proxy_backends_init(void);
++void proxy_backends_free(proxy_backends *backends);
++void proxy_backends_add(proxy_backends *backends, proxy_backend *backend);
++
++#endif
++
+--- ../lighttpd-1.4.11/src/mod_proxy_core_backlog.c 1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/mod_proxy_core_backlog.c 2006-07-18 13:03:40.000000000 +0300
+@@ -0,0 +1,109 @@
++#include <stdlib.h>
++
++#include "mod_proxy_core_backlog.h"
++#include "array-static.h"
++
++proxy_backlog *proxy_backlog_init(void) {
++ STRUCT_INIT(proxy_backlog, backlog);
++
++ return backlog;
++}
++
++void proxy_backlog_free(proxy_backlog *backlog) {
++ if (!backlog) return;
++
++ free(backlog);
++}
++
++int proxy_backlog_push(proxy_backlog *backlog, proxy_request *req) {
++ /* first entry */
++ if (NULL == backlog->first) {
++ backlog->first = backlog->last = req;
++ } else {
++ backlog->last->next = req;
++ backlog->last = req;
++ }
++ backlog->length++;
++
++ return 0;
++}
++
++/**
++ * remove the first element from the backlog
++ */
++proxy_request *proxy_backlog_shift(proxy_backlog *backlog) {
++ proxy_request *req = NULL;
++
++ if (!backlog->first) return req;
++
++ backlog->length--;
++
++ req = backlog->first;
++
++ backlog->first = req->next;
++
++ /* the backlog is empty */
++ if (backlog->first == NULL) backlog->last = NULL;
++
++ return req;
++}
++
++int proxy_backlog_remove_connection(proxy_backlog *backlog, void *con) {
++ proxy_request *req = NULL;
++
++ if (!backlog->first) return -1;
++ if (!con) return -1;
++
++ /* the first element is what we look for */
++ if (backlog->first->con == con) {
++ req = backlog->first;
++
++ backlog->first = req->next;
++ if (backlog->first == NULL) backlog->last = NULL;
++
++ backlog->length--;
++
++ proxy_request_free(req);
++
++ return 0;
++ }
++
++
++ for (req = backlog->first; req && req->next; req = req->next) {
++ proxy_request *cur;
++
++ if (req->next->con != con) continue;
++
++ backlog->length--;
++ /* the next node is our searched connection */
++
++ cur = req->next;
++ req->next = cur->next;
++
++ /* the next node is the last one, make the current the new last */
++ if (cur == backlog->last) {
++ backlog->last = req;
++ }
++ cur->next = NULL;
++
++ proxy_request_free(req);
++
++ return 0;
++ }
++
++ return -1;
++}
++
++proxy_request *proxy_request_init(void) {
++ STRUCT_INIT(proxy_request, request);
++
++ return request;
++}
++
++void proxy_request_free(proxy_request *request) {
++ if (!request) return;
++
++ free(request);
++}
++
++
+--- ../lighttpd-1.4.11/src/mod_proxy_core_backlog.h 1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/mod_proxy_core_backlog.h 2006-07-18 13:03:40.000000000 +0300
+@@ -0,0 +1,56 @@
++#ifndef _MOD_PROXY_CORE_BACKLOG_H_
++#define _MOD_PROXY_CORE_BACKLOG_H_
++
++#include <sys/types.h>
++#include <sys/time.h>
++
++typedef struct _proxy_request {
++ void *con; /* a pointer to the client-connection, (type: connection) */
++
++ time_t added_ts; /* when was the entry added (for timeout handling) */
++
++ struct _proxy_request *next;
++} proxy_request;
++
++/**
++ * a we can't get a connection from the pool, queue the request in the
++ * request queue (FIFO)
++ *
++ * - the queue is infinite
++ * - entries are removed after a timeout (status 504)
++ */
++typedef struct {
++ proxy_request *first; /* pull() does q->first = q->first->next */
++ proxy_request *last; /* push() does q->last = r */
++
++ size_t length;
++} proxy_backlog;
++
++proxy_backlog *proxy_backlog_init(void);
++void proxy_backlog_free(proxy_backlog *backlog);
++
++/**
++ * append a request to the end
++ *
++ * @return 0 in success, -1 if full
++ */
++int proxy_backlog_push(proxy_backlog *backlog, proxy_request *req);
++
++/**
++ * remove the first request from the backlog
++ *
++ * @return NULL if backlog is empty, the request otherwise
++ */
++proxy_request *proxy_backlog_shift(proxy_backlog *backlog);
++/**
++ * remove the request with the connection 'con' from the backlog
++ *
++ * @return -1 if not found, 0 otherwise
++ */
++int proxy_backlog_remove_connection(proxy_backlog *backlog, void *con);
++
++proxy_request *proxy_request_init(void);
++void proxy_request_free(proxy_request *req);
++
++#endif
++
+--- ../lighttpd-1.4.11/src/mod_proxy_core_pool.c 1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/mod_proxy_core_pool.c 2006-07-18 13:03:40.000000000 +0300
+@@ -0,0 +1,127 @@
++
++#include <stdlib.h>
++
++#include "array-static.h"
++#include "sys-files.h"
++#include "log.h"
++#include "mod_proxy_core_pool.h"
++
++proxy_connection * proxy_connection_init(void) {
++ proxy_connection *con;
++
++ con = calloc(1, sizeof(*con));
++
++ con->sock = iosocket_init();
++
++ return con;
++}
++
++void proxy_connection_free(proxy_connection *con) {
++ if (!con) return;
++
++ iosocket_free(con->sock);
++
++ free(con);
++}
++
++proxy_connection_pool *proxy_connection_pool_init(void) {
++ proxy_connection_pool *pool;
++
++ pool = calloc(1, sizeof(*pool));
++
++ /* default: max parallel connections to the backend
++ *
++ * this should match max-procs if we manage the procs ourself
++ */
++
++ pool->max_size = 8;
++
++ return pool;
++}
++
++void proxy_connection_pool_free(proxy_connection_pool *pool) {
++ size_t i;
++
++ if (!pool) return;
++
++ for (i = 0; i < pool->used; i++) {
++ proxy_connection_free(pool->ptr[i]);
++ }
++
++ if (pool->size) free(pool->ptr);
++
++ free(pool);
++}
++
++void proxy_connection_pool_add_connection(proxy_connection_pool *pool, proxy_connection *c) {
++ ARRAY_STATIC_PREPARE_APPEND(pool);
++
++ pool->ptr[pool->used++] = c;
++}
++/**
++ * remove the connection from the pool
++ *
++ * usually called on conn-shutdown
++ */
++int proxy_connection_pool_remove_connection(proxy_connection_pool *pool, proxy_connection *c) {
++ size_t i;
++
++ if (pool->used == 0) return -1; /* empty */
++
++ for (i = 0; i < pool->used; i++) {
++ if (pool->ptr[i] == c) {
++ break;
++ }
++ }
++
++ if (i == pool->used) return -1; /* not found */
++
++ /**
++ * move all elements one to the left
++ *
++ * if the last element is going to be removed, skip the loop
++ */
++ for (; i < pool->used - 1; i++) {
++ pool->ptr[i] = pool->ptr[i + 1];
++ }
++
++ pool->used--;
++
++ return 0;
++}
++
++proxy_connection_pool_t proxy_connection_pool_get_connection(proxy_connection_pool *pool, proxy_address *address, proxy_connection **rcon) {
++ proxy_connection *proxy_con = NULL;
++ size_t i;
++
++ /* search for a idling proxy connection with the given address */
++ for (i = 0; i < pool->used; i++) {
++ proxy_con = pool->ptr[i];
++
++ if (proxy_con->address == address &&
++ proxy_con->state == PROXY_CONNECTION_STATE_IDLE) {
++ break;
++ }
++ }
++
++ if (i == pool->used) {
++ /* no idling connection found */
++
++ if (pool->used == pool->max_size) return PROXY_CONNECTIONPOOL_FULL;
++
++ proxy_con = proxy_connection_init();
++
++ proxy_con->state = PROXY_CONNECTION_STATE_CONNECTING;
++ proxy_con->address = address;
++
++ proxy_connection_pool_add_connection(pool, proxy_con);
++ } else {
++ proxy_con->state = PROXY_CONNECTION_STATE_CONNECTED;
++ }
++
++ *rcon = proxy_con;
++
++ return PROXY_CONNECTIONPOOL_GOT_CONNECTION;
++}
++
++
+--- ../lighttpd-1.4.11/src/mod_proxy_core_pool.h 1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/mod_proxy_core_pool.h 2006-07-18 13:03:40.000000000 +0300
+@@ -0,0 +1,52 @@
++#ifndef _MOD_PROXY_CORE_POOL_H_
++#define _MOD_PROXY_CORE_POOL_H_
++
++#include <sys/time.h>
++
++#include "iosocket.h"
++#include "array-static.h"
++#include "mod_proxy_core_address.h"
++
++typedef enum {
++ PROXY_CONNECTION_STATE_UNSET,
++ PROXY_CONNECTION_STATE_CONNECTING,
++ PROXY_CONNECTION_STATE_CONNECTED,
++ PROXY_CONNECTION_STATE_IDLE,
++ PROXY_CONNECTION_STATE_CLOSED,
++} proxy_connection_state_t;
++
++/**
++ * a connection to a proxy backend
++ *
++ * the connection is independent of the incoming request to allow keep-alive
++ */
++typedef struct {
++ iosocket *sock;
++
++ time_t last_read; /* timeout handling for keep-alive connections */
++ time_t last_write;
++
++ proxy_address *address; /* the struct sock_addr for the sock */
++
++ proxy_connection_state_t state;
++} proxy_connection;
++
++ARRAY_STATIC_DEF(proxy_connection_pool, proxy_connection, size_t max_size;);
++
++typedef enum {
++ PROXY_CONNECTIONPOOL_UNSET,
++ PROXY_CONNECTIONPOOL_FULL,
++ PROXY_CONNECTIONPOOL_GOT_CONNECTION,
++} proxy_connection_pool_t;
++
++proxy_connection_pool *proxy_connection_pool_init(void);
++void proxy_connection_pool_free(proxy_connection_pool *pool);
++
++proxy_connection_pool_t proxy_connection_pool_get_connection(proxy_connection_pool *pool, proxy_address *address, proxy_connection **rcon);
++int proxy_connection_pool_remove_connection(proxy_connection_pool *pool, proxy_connection *c);
++
++proxy_connection * proxy_connection_init(void);
++void proxy_connection_free(proxy_connection *pool);
++
++#endif
++
+--- ../lighttpd-1.4.11/src/mod_redirect.c 2006-02-08 15:38:06.000000000 +0200
++++ lighttpd-1.4.12/src/mod_redirect.c 2006-07-16 00:26:04.000000000 +0300
+@@ -22,35 +22,35 @@
+ PLUGIN_DATA;
+ buffer *match_buf;
+ buffer *location;
+-
++
+ plugin_config **config_storage;
+-
+- plugin_config conf;
++
++ plugin_config conf;
+ } plugin_data;
+
+ INIT_FUNC(mod_redirect_init) {
+ plugin_data *p;
+-
++
+ p = calloc(1, sizeof(*p));
+-
++
+ p->match_buf = buffer_init();
+ p->location = buffer_init();
+-
++
+ return p;
+ }
+
+ FREE_FUNC(mod_redirect_free) {
+ plugin_data *p = p_d;
+-
++
+ if (!p) return HANDLER_GO_ON;
+
+ if (p->config_storage) {
+ size_t i;
+ for (i = 0; i < srv->config_context->used; i++) {
+ plugin_config *s = p->config_storage[i];
+-
++
+ pcre_keyvalue_buffer_free(s->redirect);
+-
++
+ free(s);
+ }
+ free(p->config_storage);
+@@ -59,9 +59,9 @@
+
+ buffer_free(p->match_buf);
+ buffer_free(p->location);
+-
++
+ free(p);
+-
++
+ return HANDLER_GO_ON;
+ }
+
+@@ -69,195 +69,137 @@
+ plugin_data *p = p_d;
+ data_unset *du;
+ size_t i = 0;
+-
+- config_values_t cv[] = {
++
++ config_values_t cv[] = {
+ { "url.redirect", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
+ { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
+ };
+-
++
+ if (!p) return HANDLER_ERROR;
+-
++
+ /* 0 */
+ p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
+-
++
+ for (i = 0; i < srv->config_context->used; i++) {
+ plugin_config *s;
+ size_t j;
+ array *ca;
+ data_array *da = (data_array *)du;
+-
++
+ s = calloc(1, sizeof(plugin_config));
+ s->redirect = pcre_keyvalue_buffer_init();
+-
++
+ cv[0].destination = s->redirect;
+-
++
+ p->config_storage[i] = s;
+ ca = ((data_config *)srv->config_context->data[i])->value;
+-
++
+ if (0 != config_insert_values_global(srv, ca, cv)) {
+ return HANDLER_ERROR;
+ }
+-
++
+ if (NULL == (du = array_get_element(ca, "url.redirect"))) {
+ /* no url.redirect defined */
+ continue;
+ }
+-
++
+ if (du->type != TYPE_ARRAY) {
+- log_error_write(srv, __FILE__, __LINE__, "sss",
++ log_error_write(srv, __FILE__, __LINE__, "sss",
+ "unexpected type for key: ", "url.redirect", "array of strings");
+-
++
+ return HANDLER_ERROR;
+ }
+-
++
+ da = (data_array *)du;
+-
++
+ for (j = 0; j < da->value->used; j++) {
+ if (da->value->data[j]->type != TYPE_STRING) {
+- log_error_write(srv, __FILE__, __LINE__, "sssbs",
+- "unexpected type for key: ",
+- "url.redirect",
++ log_error_write(srv, __FILE__, __LINE__, "sssbs",
++ "unexpected type for key: ",
++ "url.redirect",
+ "[", da->value->data[j]->key, "](string)");
+-
++
+ return HANDLER_ERROR;
+ }
+-
+- if (0 != pcre_keyvalue_buffer_append(s->redirect,
++
++ if (0 != pcre_keyvalue_buffer_append(s->redirect,
+ ((data_string *)(da->value->data[j]))->key->ptr,
+ ((data_string *)(da->value->data[j]))->value->ptr)) {
+-
+- log_error_write(srv, __FILE__, __LINE__, "sb",
++
++ log_error_write(srv, __FILE__, __LINE__, "sb",
+ "pcre-compile failed for", da->value->data[j]->key);
+ }
+ }
+ }
+-
++
+ return HANDLER_GO_ON;
+ }
+ #ifdef HAVE_PCRE_H
+ static int mod_redirect_patch_connection(server *srv, connection *con, plugin_data *p) {
+ size_t i, j;
+ plugin_config *s = p->config_storage[0];
+-
++
+ p->conf.redirect = s->redirect;
+-
++
+ /* skip the first, the global context */
+ for (i = 1; i < srv->config_context->used; i++) {
+ data_config *dc = (data_config *)srv->config_context->data[i];
+ s = p->config_storage[i];
+-
++
+ /* condition didn't match */
+ if (!config_check_cond(srv, con, dc)) continue;
+-
++
+ /* merge config */
+ for (j = 0; j < dc->value->used; j++) {
+ data_unset *du = dc->value->data[j];
+-
++
+ if (0 == strcmp(du->key->ptr, "url.redirect")) {
+ p->conf.redirect = s->redirect;
+ p->conf.context = dc;
+ }
+ }
+ }
+-
++
+ return 0;
+ }
+ #endif
+ static handler_t mod_redirect_uri_handler(server *srv, connection *con, void *p_data) {
+ #ifdef HAVE_PCRE_H
+ plugin_data *p = p_data;
+- size_t i;
++ int i;
+
+- /*
++ /*
+ * REWRITE URL
+- *
++ *
+ * e.g. redirect /base/ to /index.php?section=base
+- *
++ *
+ */
+-
++
+ mod_redirect_patch_connection(srv, con, p);
+-
++
+ buffer_copy_string_buffer(p->match_buf, con->request.uri);
+-
+- for (i = 0; i < p->conf.redirect->used; i++) {
+- pcre *match;
+- pcre_extra *extra;
+- const char *pattern;
+- size_t pattern_len;
+- int n;
+- pcre_keyvalue *kv = p->conf.redirect->kv[i];
+-# define N 10
+- int ovec[N * 3];
+-
+- match = kv->key;
+- extra = kv->key_extra;
+- pattern = kv->value->ptr;
+- pattern_len = kv->value->used - 1;
+-
+- if ((n = pcre_exec(match, extra, p->match_buf->ptr, p->match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) {
+- if (n != PCRE_ERROR_NOMATCH) {
+- log_error_write(srv, __FILE__, __LINE__, "sd",
+- "execution error while matching: ", n);
- return HANDLER_ERROR;
- }
- } else {
return 0;
}
--- ../lighttpd-1.4.11/src/mod_rewrite.c 2005-09-29 20:59:10.000000000 +0300
-+++ lighttpd-1.4.12/src/mod_rewrite.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/mod_rewrite.c 2006-07-16 00:26:03.000000000 +0300
@@ -13,24 +13,8 @@
#endif
return 0;
}
--- ../lighttpd-1.4.11/src/mod_rrdtool.c 2005-08-22 01:52:24.000000000 +0300
-+++ lighttpd-1.4.12/src/mod_rrdtool.c 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/mod_rrdtool.c 2006-07-18 13:03:40.000000000 +0300
@@ -5,7 +5,6 @@
#include <stdlib.h>
#include <stdio.h>
/* fork, execve */
switch (pid = fork()) {
case 0: {
-@@ -117,33 +120,33 @@
+@@ -117,33 +120,28 @@
int argc;
int i = 0;
char *dash = "-";
+
close(STDERR_FILENO);
-
-+
- if (srv->errorlog_mode == ERRORLOG_FILE) {
- dup2(srv->errorlog_fd, STDERR_FILENO);
- close(srv->errorlog_fd);
- }
+- if (srv->errorlog_mode == ERRORLOG_FILE) {
+- dup2(srv->errorlog_fd, STDERR_FILENO);
+- close(srv->errorlog_fd);
+- }
-
+
/* set up args */
args[i++] = p->conf.path_rrdtool_bin->ptr;
args[i++] = dash;
args[i++] = NULL;
-@@ -152,12 +155,12 @@
+@@ -152,12 +150,12 @@
for (i = 3; i < 256; i++) {
close(i);
}
/* */
SEGFAULT();
break;
-@@ -168,19 +171,19 @@
+@@ -168,19 +166,19 @@
break;
default: {
/* father */
return 0;
#else
return -1;
-@@ -189,19 +192,19 @@
+@@ -189,19 +187,19 @@
static int mod_rrdtool_create_rrd(server *srv, plugin_data *p, plugin_config *s) {
struct stat st;
BUFFER_COPY_STRING_CONST(p->cmd, "create ");
buffer_append_string_buffer(p->cmd, s->path_rrd);
buffer_append_string(p->cmd, " --step 60 ");
-@@ -220,158 +223,155 @@
+@@ -220,158 +218,155 @@
buffer_append_string(p->cmd, "RRA:MIN:0.5:6:700 ");
buffer_append_string(p->cmd, "RRA:MIN:0.5:24:775 ");
buffer_append_string(p->cmd, "RRA:MIN:0.5:288:797\n");
BUFFER_COPY_STRING_CONST(p->cmd, "update ");
buffer_append_string_buffer(p->cmd, s->path_rrd);
BUFFER_APPEND_STRING_CONST(p->cmd, " N:");
-@@ -381,69 +381,69 @@
+@@ -381,69 +376,69 @@
BUFFER_APPEND_STRING_CONST(p->cmd, ":");
buffer_append_long(p->cmd, s->requests);
BUFFER_APPEND_STRING_CONST(p->cmd, "\n");
return 0;
}
--- ../lighttpd-1.4.11/src/mod_scgi.c 2006-03-04 17:15:26.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_scgi.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/mod_scgi.c 2006-07-18 13:03:40.000000000 +0300
@@ -1,5 +1,4 @@
#include <sys/types.h>
-#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
-@@ -30,7 +29,9 @@
+@@ -18,6 +17,7 @@
+ #include "connections.h"
+ #include "response.h"
+ #include "joblist.h"
++#include "http_resp.h"
+
+ #include "plugin.h"
+
+@@ -30,7 +30,9 @@
#endif
#include "sys-socket.h"
#ifndef UNIX_PATH_MAX
# define UNIX_PATH_MAX 108
-@@ -46,30 +47,29 @@
+@@ -46,30 +48,29 @@
enum {EOL_UNSET, EOL_N, EOL_RN};
/*
int is_local;
enum { PROC_STATE_UNSET, /* init-phase */
-@@ -78,7 +78,7 @@
+@@ -78,7 +79,7 @@
PROC_STATE_KILLED, /* was killed as we don't have the load anymore */
PROC_STATE_DIED, /* marked as dead, should be restarted */
PROC_STATE_DISABLED /* proc disabled as it resulted in an error */
} scgi_proc;
typedef struct {
-@@ -86,20 +86,20 @@
+@@ -86,20 +87,20 @@
* sorted by lowest load
*
* whenever a job is done move it up in the list
*/
unsigned short min_procs;
-@@ -111,44 +111,44 @@
+@@ -111,44 +112,44 @@
/*
* kick the process from the list if it was not
unsigned short port;
/*
-@@ -161,7 +161,7 @@
+@@ -161,7 +162,7 @@
*/
buffer *unixsocket;
* process ourself
*
* bin-path is the path to the binary
-@@ -169,19 +169,19 @@
+@@ -169,19 +170,19 @@
* check min_procs and max_procs for the number
* of process to start-up
*/
* remote host
*
* reasons:
-@@ -192,7 +192,7 @@
+@@ -192,7 +193,7 @@
buffer *docroot;
/*
* or not. FastCGI doesn't care if the service is
* remote. If the web-server side doesn't contain
* the scgi-files we should not stat() for them
-@@ -202,33 +202,33 @@
+@@ -202,33 +203,33 @@
/*
* append PATH_INFO to SCRIPT_FILENAME
*
* in case of PHP and FCGI_CHILDREN we have again a procs
* but we don't control it directly.
-@@ -239,7 +239,7 @@
+@@ -239,7 +240,7 @@
buffer *key; /* like .php */
scgi_extension_host **hosts;
size_t used;
size_t size;
} scgi_extension;
-@@ -253,14 +253,14 @@
+@@ -253,14 +254,14 @@
typedef struct {
size_t size;
size_t used;
} char_array;
-@@ -268,52 +268,51 @@
+@@ -268,52 +269,51 @@
/* generic plugin data, shared between all connections */
typedef struct {
PLUGIN_DATA;
-
+
buffer *path;
- buffer *parse_response;
+- buffer *parse_response;
-
++
++ http_resp *resp;
+
plugin_config **config_storage;
-
/* connection specific data */
-typedef enum { FCGI_STATE_INIT, FCGI_STATE_CONNECT, FCGI_STATE_PREPARE_WRITE,
- FCGI_STATE_WRITE, FCGI_STATE_READ
-+typedef enum { FCGI_STATE_INIT, FCGI_STATE_CONNECT, FCGI_STATE_PREPARE_WRITE,
-+ FCGI_STATE_WRITE, FCGI_STATE_READ
++typedef enum {
++ SCGI_STATE_INIT,
++ SCGI_STATE_CONNECT,
++ SCGI_STATE_PREPARE_WRITE,
++ SCGI_STATE_WRITE,
++ SCGI_STATE_RESPONSE_HEADER,
++ SCGI_STATE_RESPONSE_CONTENT,
++ SCGI_STATE_ERROR
} scgi_connection_state_t;
typedef struct {
- buffer *response;
-+ buffer *response;
- size_t response_len;
- int response_type;
- int response_padding;
+- size_t response_len;
+- int response_type;
+- int response_padding;
-
-+
scgi_proc *proc;
scgi_extension_host *host;
-
+
int reconnects; /* number of reconnect attempts */
-
+- read_buffer *rb;
+
- read_buffer *rb;
++ chunkqueue *rb;
chunkqueue *wb;
-
-+
- buffer *response_header;
+- buffer *response_header;
-
+
int delayed; /* flag to mark that the connect() is delayed */
-
+
size_t request_id;
- int fd; /* fd to the scgi process */
- int fde_ndx; /* index into the fd-event buffer */
--
+- int fd; /* fd to the scgi process */
+- int fde_ndx; /* index into the fd-event buffer */
++ iosocket *sock; /* fd to the scgi process */
+
pid_t pid;
int got_proc;
-
connection *remote_conn; /* dumb pointer */
plugin_data *plugin_data; /* dumb pointer */
} handler_ctx;
-@@ -328,28 +327,28 @@
+@@ -328,42 +328,30 @@
static handler_ctx * handler_ctx_init() {
handler_ctx * hctx;
hctx = calloc(1, sizeof(*hctx));
assert(hctx);
-
-+
- hctx->fde_ndx = -1;
+- hctx->fde_ndx = -1;
-
-+
- hctx->response = buffer_init();
- hctx->response_header = buffer_init();
+- hctx->response = buffer_init();
+- hctx->response_header = buffer_init();
-
++
++ hctx->sock = iosocket_init();;
+
hctx->request_id = 0;
- hctx->state = FCGI_STATE_INIT;
+- hctx->state = FCGI_STATE_INIT;
++ hctx->state = SCGI_STATE_INIT;
hctx->proc = NULL;
-
-+
- hctx->response_len = 0;
- hctx->response_type = 0;
- hctx->response_padding = 0;
- hctx->fd = -1;
+- hctx->response_len = 0;
+- hctx->response_type = 0;
+- hctx->response_padding = 0;
+- hctx->fd = -1;
-
+
hctx->reconnects = 0;
hctx->wb = chunkqueue_init();
-
++ hctx->rb = chunkqueue_init();
+
return hctx;
}
-@@ -358,12 +357,12 @@
- buffer_free(hctx->response_header);
-
+ static void handler_ctx_free(handler_ctx *hctx) {
+- buffer_free(hctx->response);
+- buffer_free(hctx->response_header);
+-
chunkqueue_free(hctx->wb);
-
-+
- if (hctx->rb) {
- if (hctx->rb->ptr) free(hctx->rb->ptr);
- free(hctx->rb);
- }
+- if (hctx->rb) {
+- if (hctx->rb->ptr) free(hctx->rb->ptr);
+- free(hctx->rb);
+- }
-
++ chunkqueue_free(hctx->rb);
++
++ iosocket_free(hctx->sock);
+
free(hctx);
}
-@@ -372,20 +371,20 @@
+@@ -372,20 +360,20 @@
f = calloc(1, sizeof(*f));
f->socket = buffer_init();
free(f);
}
-@@ -400,62 +399,62 @@
+@@ -400,62 +388,62 @@
f->bin_path = buffer_init();
f->bin_env = array_init();
f->bin_env_copy = array_init();
free(f);
}
-@@ -504,99 +503,103 @@
+@@ -504,99 +492,103 @@
assert(fe->hosts);
}
-
+
p->path = buffer_init();
- p->parse_response = buffer_init();
+- p->parse_response = buffer_init();
-
++ p->resp = http_response_init();
+
return p;
}
buffer_free(p->scgi_env);
buffer_free(p->path);
- buffer_free(p->parse_response);
+- buffer_free(p->parse_response);
-
++ http_response_free(p->resp);
+
if (p->config_storage) {
size_t i, j, n;
if (env->size == 0) {
env->size = 16;
env->ptr = malloc(env->size * sizeof(*env->ptr));
-@@ -604,13 +607,13 @@
+@@ -604,13 +596,13 @@
env->size += 16;
env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr));
}
plugin_data *p,
scgi_extension_host *host,
scgi_proc *proc) {
-@@ -622,31 +625,27 @@
+@@ -622,31 +614,27 @@
#endif
struct sockaddr_in scgi_addr_in;
struct sockaddr *scgi_addr;
socket_type = AF_UNIX;
scgi_addr = (struct sockaddr *) &scgi_addr_un;
#else
-@@ -656,115 +655,115 @@
+@@ -656,115 +644,115 @@
#endif
} else {
scgi_addr_in.sin_family = AF_INET;
if (NULL != (ge = getenv(ds->value->ptr))) {
env_add(&env, CONST_BUF_LEN(ds->value), ge, strlen(ge));
}
-@@ -772,44 +771,44 @@
+@@ -772,44 +760,44 @@
} else {
for (i = 0; environ[i]; i++) {
char *eq;
break;
}
case -1:
-@@ -817,32 +816,32 @@
+@@ -817,32 +805,32 @@
break;
default:
/* father */
status);
}
return -1;
-@@ -852,26 +851,26 @@
+@@ -852,26 +840,26 @@
proc->pid = child;
proc->last_used = srv->cur_ts;
proc->is_local = 1;
return 0;
}
-@@ -880,89 +879,89 @@
+@@ -880,89 +868,89 @@
plugin_data *p = p_d;
data_unset *du;
size_t i = 0;
{ "check-local", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 4 */
{ "port", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 5 */
{ "min-procs-not-working", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 7 this is broken for now */
-@@ -970,37 +969,37 @@
+@@ -970,37 +958,37 @@
{ "max-load-per-proc", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
{ "idle-timeout", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 9 */
{ "disable-time", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 10 */
fcv[4].destination = &(df->check_local);
fcv[5].destination = &(df->port);
fcv[6].destination = &(df->min_procs);
-@@ -1008,47 +1007,47 @@
+@@ -1008,47 +996,47 @@
fcv[8].destination = &(df->max_load_per_proc);
fcv[9].destination = &(df->idle_timeout);
fcv[10].destination = &(df->disable_time);
da->key,
da_ext->key,
da_host->key,
-@@ -1056,14 +1055,14 @@
+@@ -1056,14 +1044,14 @@
return HANDLER_ERROR;
}
}
if (s->debug) {
log_error_write(srv, __FILE__, __LINE__, "ssbsdsbsdsd",
"--- scgi spawning local",
-@@ -1073,7 +1072,7 @@
+@@ -1073,7 +1061,7 @@
"\n\tmin-procs:", df->min_procs,
"\n\tmax-procs:", df->max_procs);
}
for (pno = 0; pno < df->min_procs; pno++) {
scgi_proc *proc;
-@@ -1088,7 +1087,7 @@
+@@ -1088,7 +1076,7 @@
buffer_append_string(proc->socket, "-");
buffer_append_long(proc->socket, pno);
}
if (s->debug) {
log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd",
"--- scgi spawning",
-@@ -1096,53 +1095,53 @@
+@@ -1096,53 +1084,53 @@
"\n\tsocket", df->unixsocket,
"\n\tcurrent:", pno, "/", df->min_procs);
}
return 0;
}
-@@ -1150,34 +1149,34 @@
+@@ -1150,35 +1138,35 @@
void scgi_connection_cleanup(server *srv, handler_ctx *hctx) {
plugin_data *p;
connection *con;
-
+
if (con->mode != p->id) {
- WP();
+- WP();
return;
}
-
+- if (hctx->fd != -1) {
+- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
+- fdevent_unregister(srv->ev, hctx->fd);
+- close(hctx->fd);
+
- if (hctx->fd != -1) {
- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
- fdevent_unregister(srv->ev, hctx->fd);
- close(hctx->fd);
++ if (hctx->sock->fd != -1) {
++ fdevent_event_del(srv->ev, hctx->sock);
++ fdevent_unregister(srv->ev, hctx->sock);
++ closesocket(hctx->sock->fd);
++ hctx->sock->fd = -1;
srv->cur_fds--;
}
-
if (p->conf.debug) {
log_error_write(srv, __FILE__, __LINE__, "sddb",
- "release proc:",
+- hctx->fd,
+ "release proc:",
- hctx->fd,
++ hctx->sock->fd,
hctx->proc->pid, hctx->proc->socket);
}
-@@ -1186,87 +1185,87 @@
+ }
+@@ -1186,87 +1174,87 @@
scgi_proclist_sort_down(srv, hctx->host, hctx->proc);
}
+ *
*/
-
+- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
+- fdevent_unregister(srv->ev, hctx->fd);
+- close(hctx->fd);
+
- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
- fdevent_unregister(srv->ev, hctx->fd);
- close(hctx->fd);
++ fdevent_event_del(srv->ev, hctx->sock);
++ fdevent_unregister(srv->ev, hctx->sock);
++ closesocket(hctx->sock->fd);
srv->cur_fds--;
-
-+
- scgi_set_state(srv, hctx, FCGI_STATE_INIT);
+- scgi_set_state(srv, hctx, FCGI_STATE_INIT);
-
++
++ scgi_set_state(srv, hctx, SCGI_STATE_INIT);
+
hctx->request_id = 0;
hctx->reconnects++;
if (p->conf.debug) {
log_error_write(srv, __FILE__, __LINE__, "sddb",
- "release proc:",
+- hctx->fd,
+ "release proc:",
- hctx->fd,
++ hctx->sock->fd,
hctx->proc->pid, hctx->proc->socket);
}
-
* returns
* -1 error
* 0 connected
-@@ -1280,24 +1279,21 @@
+@@ -1280,24 +1268,21 @@
struct sockaddr_un scgi_addr_un;
#endif
socklen_t servlen;
+
scgi_extension_host *host = hctx->host;
scgi_proc *proc = hctx->proc;
- int scgi_fd = hctx->fd;
+- int scgi_fd = hctx->fd;
-
++ int scgi_fd = hctx->sock->fd;
+
memset(&scgi_addr, 0, sizeof(scgi_addr));
-
scgi_addr = (struct sockaddr *) &scgi_addr_un;
#else
return -1;
-@@ -1305,105 +1301,105 @@
+@@ -1305,105 +1290,105 @@
} else {
scgi_addr_in.sin_family = AF_INET;
if (0 == inet_aton(host->host->ptr, &(scgi_addr_in.sin_addr))) {
return 0;
}
-@@ -1415,20 +1411,20 @@
+@@ -1415,20 +1400,20 @@
char b2[INET6_ADDRSTRLEN + 1];
#endif
buffer *b;
/* request.content_length < SSIZE_MAX, see request.c */
ltostr(buf, con->request.content_length);
scgi_env_add(p->scgi_env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf));
-@@ -1436,13 +1432,13 @@
+@@ -1436,13 +1421,13 @@
scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION));
(const void *) &(srv_sock->addr.ipv6.sin6_addr) :
(const void *) &(srv_sock->addr.ipv4.sin_addr),
b2, sizeof(b2)-1);
-@@ -1451,47 +1447,47 @@
+@@ -1451,47 +1436,47 @@
#endif
scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_NAME"), s, strlen(s));
}
/* get the server-side of the connection to the client */
our_addr_len = sizeof(our_addr);
-
+- if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) {
+
- if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) {
++ if (-1 == getsockname(con->sock->fd, &(our_addr.plain), &our_addr_len)) {
s = inet_ntop_cache_get_ip(srv, &(srv_sock->addr));
} else {
s = inet_ntop_cache_get_ip(srv, &(our_addr));
/*
* SCRIPT_NAME, PATH_INFO and PATH_TRANSLATED according to
-@@ -1500,12 +1496,12 @@
+@@ -1500,12 +1485,12 @@
*/
scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
if (!buffer_is_empty(host->docroot)) {
buffer_copy_string_buffer(p->path, host->docroot);
} else {
-@@ -1526,19 +1522,19 @@
+@@ -1526,19 +1511,19 @@
*/
if (!buffer_is_empty(host->docroot)) {
scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path));
scgi_env_add(p->scgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.doc_root));
}
-@@ -1551,30 +1547,30 @@
+@@ -1551,30 +1536,30 @@
} else {
scgi_env_add(p->scgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN(""));
}
if (con->request.content_length) {
chunkqueue *req_cq = con->request_content_queue;
chunk *req_c;
-@@ -1587,7 +1583,7 @@
+@@ -1587,7 +1572,7 @@
/* we announce toWrite octects
* now take all the request_content chunk that we need to fill this request
switch (req_c->type) {
case FILE_CHUNK:
-@@ -1615,32 +1611,32 @@
+@@ -1615,293 +1600,170 @@
req_c->offset += weHave;
req_cq->bytes_out += weHave;
}
#endif
-
-+
- return 0;
- }
+- return 0;
+-}
-@@ -1648,32 +1644,32 @@
- char *ns;
- const char *s;
- int line = 0;
+-static int scgi_response_parse(server *srv, connection *con, plugin_data *p, buffer *in, int eol) {
+- char *ns;
+- const char *s;
+- int line = 0;
-
-+
- UNUSED(srv);
+- UNUSED(srv);
-
-+
- buffer_copy_string_buffer(p->parse_response, in);
+- buffer_copy_string_buffer(p->parse_response, in);
-
- for (s = p->parse_response->ptr;
- NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n')));
-+
-+ for (s = p->parse_response->ptr;
-+ NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n')));
- s = ns + (eol == EOL_RN ? 2 : 1), line++) {
- const char *key, *value;
- int key_len;
- data_string *ds;
+- s = ns + (eol == EOL_RN ? 2 : 1), line++) {
+- const char *key, *value;
+- int key_len;
+- data_string *ds;
-
-+
- ns[0] = '\0';
+- ns[0] = '\0';
-
- if (line == 0 &&
-+
-+ if (line == 0 &&
- 0 == strncmp(s, "HTTP/1.", 7)) {
- /* non-parsed header ... we parse them anyway */
--
-+
- if ((s[7] == '1' ||
- s[7] == '0') &&
- s[8] == ' ') {
- int status;
- /* after the space should be a status code for us */
--
-+
- status = strtol(s+9, NULL, 10);
--
-+
- if (con->http_status >= 100 &&
- con->http_status < 1000) {
- /* we expected 3 digits and didn't got them */
-@@ -1682,27 +1678,27 @@
- }
- }
- } else {
+- 0 == strncmp(s, "HTTP/1.", 7)) {
+- /* non-parsed header ... we parse them anyway */
+-
+- if ((s[7] == '1' ||
+- s[7] == '0') &&
+- s[8] == ' ') {
+- int status;
+- /* after the space should be a status code for us */
+-
+- status = strtol(s+9, NULL, 10);
+-
+- if (con->http_status >= 100 &&
+- con->http_status < 1000) {
+- /* we expected 3 digits and didn't got them */
+- con->parsed_response |= HTTP_STATUS;
+- con->http_status = status;
+- }
+- }
+- } else {
-
-+
- key = s;
- if (NULL == (value = strchr(s, ':'))) {
- /* we expect: "<key>: <value>\r\n" */
- continue;
- }
+- key = s;
+- if (NULL == (value = strchr(s, ':'))) {
+- /* we expect: "<key>: <value>\r\n" */
+- continue;
+- }
-
-+
- key_len = value - key;
- value += 1;
+- key_len = value - key;
+- value += 1;
-
-+
- /* skip LWS */
- while (*value == ' ' || *value == '\t') value++;
+- /* skip LWS */
+- while (*value == ' ' || *value == '\t') value++;
-
-+
- if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
- ds = data_response_init();
- }
- buffer_copy_string_len(ds->key, key, key_len);
- buffer_copy_string(ds->value, value);
+- if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
+- ds = data_response_init();
+- }
+- buffer_copy_string_len(ds->key, key, key_len);
+- buffer_copy_string(ds->value, value);
-
-+
- array_insert_unique(con->response.headers, (data_unset *)ds);
+- array_insert_unique(con->response.headers, (data_unset *)ds);
-
-+
- switch(key_len) {
- case 4:
- if (0 == strncasecmp(key, "Date", key_len)) {
-@@ -1737,13 +1733,13 @@
- }
- }
- }
+- switch(key_len) {
+- case 4:
+- if (0 == strncasecmp(key, "Date", key_len)) {
+- con->parsed_response |= HTTP_DATE;
+- }
+- break;
+- case 6:
+- if (0 == strncasecmp(key, "Status", key_len)) {
+- con->http_status = strtol(value, NULL, 10);
+- con->parsed_response |= HTTP_STATUS;
+- }
+- break;
+- case 8:
+- if (0 == strncasecmp(key, "Location", key_len)) {
+- con->parsed_response |= HTTP_LOCATION;
+- }
+- break;
+- case 10:
+- if (0 == strncasecmp(key, "Connection", key_len)) {
+- con->response.keep_alive = (0 == strcasecmp(value, "Keep-Alive")) ? 1 : 0;
+- con->parsed_response |= HTTP_CONNECTION;
+- }
+- break;
+- case 14:
+- if (0 == strncasecmp(key, "Content-Length", key_len)) {
+- con->response.content_length = strtol(value, NULL, 10);
+- con->parsed_response |= HTTP_CONTENT_LENGTH;
+- }
+- break;
+- default:
+- break;
+- }
+- }
+- }
-
-+
- /* CGI/1.1 rev 03 - 7.2.1.2 */
- if ((con->parsed_response & HTTP_LOCATION) &&
- !(con->parsed_response & HTTP_STATUS)) {
- con->http_status = 302;
- }
+- /* CGI/1.1 rev 03 - 7.2.1.2 */
+- if ((con->parsed_response & HTTP_LOCATION) &&
+- !(con->parsed_response & HTTP_STATUS)) {
+- con->http_status = 302;
+- }
-
-+
return 0;
}
-@@ -1751,10 +1747,10 @@
+-
static int scgi_demux_response(server *srv, handler_ctx *hctx) {
plugin_data *p = hctx->plugin_data;
connection *con = hctx->remote_conn;
-
-+
- while(1) {
- int n;
+- while(1) {
+- int n;
-
-+
- buffer_prepare_copy(hctx->response, 1024);
- if (-1 == (n = read(hctx->fd, hctx->response->ptr, hctx->response->size - 1))) {
- if (errno == EAGAIN || errno == EINTR) {
-@@ -1765,143 +1761,143 @@
- log_error_write(srv, __FILE__, __LINE__, "sdd", strerror(errno), con->fd, hctx->fd);
- return -1;
- }
+- buffer_prepare_copy(hctx->response, 1024);
+- if (-1 == (n = read(hctx->fd, hctx->response->ptr, hctx->response->size - 1))) {
+- if (errno == EAGAIN || errno == EINTR) {
+- /* would block, wait for signal */
+- return 0;
+- }
+- /* error */
+- log_error_write(srv, __FILE__, __LINE__, "sdd", strerror(errno), con->fd, hctx->fd);
+- return -1;
+- }
-
-+
- if (n == 0) {
- /* read finished */
+- if (n == 0) {
+- /* read finished */
-
-+
- con->file_finished = 1;
+- con->file_finished = 1;
-
-+
- /* send final chunk */
- http_chunk_append_mem(srv, con, NULL, 0);
- joblist_append(srv, con);
+- /* send final chunk */
+- http_chunk_append_mem(srv, con, NULL, 0);
+- joblist_append(srv, con);
-
++ chunk *c;
+
- return 1;
- }
--
++ switch(srv->network_backend_read(srv, con, hctx->sock, hctx->rb)) {
++ case NETWORK_STATUS_SUCCESS:
++ /* we got content */
++ break;
++ case NETWORK_STATUS_WAIT_FOR_EVENT:
++ /* the ioctl will return WAIT_FOR_EVENT on a read */
++ if (0 == con->file_started) return -1;
++ case NETWORK_STATUS_CONNECTION_CLOSE:
++ /* we are done, get out of here */
++ con->file_finished = 1;
+
- hctx->response->ptr[n] = '\0';
- hctx->response->used = n+1;
--
++ /* close the chunk-queue with a empty chunk */
+
- /* split header from body */
--
++ return 1;
++ default:
++ /* oops */
++ return -1;
++ }
+
- if (con->file_started == 0) {
- char *c;
- int in_header = 0;
- int header_end = 0;
- int cp, eol = EOL_UNSET;
- size_t used = 0;
--
++ /* looks like we got some content
++ *
++ * split off the header from the incoming stream
++ */
+
- buffer_append_string_buffer(hctx->response_header, hctx->response);
--
++ if (hctx->state == SCGI_STATE_RESPONSE_HEADER) {
++ size_t i;
++ int have_content_length = 0;
+
- /* nph (non-parsed headers) */
- if (0 == strncmp(hctx->response_header->ptr, "HTTP/1.", 7)) in_header = 1;
--
++ http_response_reset(p->resp);
+
- /* search for the \r\n\r\n or \n\n in the string */
- for (c = hctx->response_header->ptr, cp = 0, used = hctx->response_header->used - 1; used; c++, cp++, used--) {
- if (*c == ':') in_header = 1;
- else if (*c == '\n') {
- if (in_header == 0) {
- /* got a response without a response header */
--
++ /* the response header is not fully received yet,
++ *
++ * extract the http-response header from the rb-cq
++ */
++ switch (http_response_parse_cq(hctx->rb, p->resp)) {
++ case PARSE_ERROR:
++ /* parsing failed */
+
- c = NULL;
- header_end = 1;
- break;
- }
++ con->http_status = 502; /* Bad Gateway */
+ return 1;
+- }
+-
+- hctx->response->ptr[n] = '\0';
+- hctx->response->used = n+1;
+-
+- /* split header from body */
+-
+- if (con->file_started == 0) {
+- char *c;
+- int in_header = 0;
+- int header_end = 0;
+- int cp, eol = EOL_UNSET;
+- size_t used = 0;
+-
+- buffer_append_string_buffer(hctx->response_header, hctx->response);
+-
+- /* nph (non-parsed headers) */
+- if (0 == strncmp(hctx->response_header->ptr, "HTTP/1.", 7)) in_header = 1;
+-
+- /* search for the \r\n\r\n or \n\n in the string */
+- for (c = hctx->response_header->ptr, cp = 0, used = hctx->response_header->used - 1; used; c++, cp++, used--) {
+- if (*c == ':') in_header = 1;
+- else if (*c == '\n') {
+- if (in_header == 0) {
+- /* got a response without a response header */
+-
+- c = NULL;
+- header_end = 1;
+- break;
+- }
-
-+
- if (eol == EOL_UNSET) eol = EOL_N;
+- if (eol == EOL_UNSET) eol = EOL_N;
-
-+
- if (*(c+1) == '\n') {
- header_end = 1;
- break;
- }
+- if (*(c+1) == '\n') {
+- header_end = 1;
+- break;
+- }
-
-+
- } else if (used > 1 && *c == '\r' && *(c+1) == '\n') {
- if (in_header == 0) {
- /* got a response without a response header */
+- } else if (used > 1 && *c == '\r' && *(c+1) == '\n') {
+- if (in_header == 0) {
+- /* got a response without a response header */
-
-+
- c = NULL;
- header_end = 1;
- break;
- }
+- c = NULL;
+- header_end = 1;
+- break;
+- }
-
-+
- if (eol == EOL_UNSET) eol = EOL_RN;
+- if (eol == EOL_UNSET) eol = EOL_RN;
-
-+
- if (used > 3 &&
+- if (used > 3 &&
- *(c+2) == '\r' &&
-+ *(c+2) == '\r' &&
- *(c+3) == '\n') {
- header_end = 1;
- break;
- }
+- *(c+3) == '\n') {
+- header_end = 1;
+- break;
+- }
-
+- /* skip the \n */
+- c++;
+- cp++;
+- used--;
++ case PARSE_NEED_MORE:
++ return 0;
++ case PARSE_SUCCESS:
++ con->http_status = p->resp->status;
++
++ chunkqueue_remove_finished_chunks(hctx->rb);
++
++ /* copy the http-headers */
++ for (i = 0; i < p->resp->headers->used; i++) {
++ const char *ign[] = { "Status", "Connection", NULL };
++ size_t j;
++ data_string *ds;
+
- /* skip the \n */
- c++;
- cp++;
- used--;
++ data_string *header = (data_string *)p->resp->headers->data[i];
++
++ /* some headers are ignored by default */
++ for (j = 0; ign[j]; j++) {
++ if (0 == strcasecmp(ign[j], header->key->ptr)) break;
}
- }
+- }
-
-+
- if (header_end) {
- if (c == NULL) {
- /* no header, but a body */
+- if (header_end) {
+- if (c == NULL) {
+- /* no header, but a body */
-
-+
- if (con->request.http_version == HTTP_VERSION_1_1) {
- con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
- }
+- if (con->request.http_version == HTTP_VERSION_1_1) {
+- con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
+- }
-
-+
- http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
- joblist_append(srv, con);
- } else {
- size_t hlen = c - hctx->response_header->ptr + (eol == EOL_RN ? 4 : 2);
- size_t blen = hctx->response_header->used - hlen - 1;
+- http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
+- joblist_append(srv, con);
+- } else {
+- size_t hlen = c - hctx->response_header->ptr + (eol == EOL_RN ? 4 : 2);
+- size_t blen = hctx->response_header->used - hlen - 1;
-
-+
- /* a small hack: terminate after at the second \r */
- hctx->response_header->used = hlen + 1 - (eol == EOL_RN ? 2 : 1);
- hctx->response_header->ptr[hlen - (eol == EOL_RN ? 2 : 1)] = '\0';
+- /* a small hack: terminate after at the second \r */
+- hctx->response_header->used = hlen + 1 - (eol == EOL_RN ? 2 : 1);
+- hctx->response_header->ptr[hlen - (eol == EOL_RN ? 2 : 1)] = '\0';
-
-+
- /* parse the response header */
- scgi_response_parse(srv, con, p, hctx->response_header, eol);
+- /* parse the response header */
+- scgi_response_parse(srv, con, p, hctx->response_header, eol);
-
-+
- /* enable chunked-transfer-encoding */
- if (con->request.http_version == HTTP_VERSION_1_1 &&
- !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
- con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
- }
+- /* enable chunked-transfer-encoding */
+- if (con->request.http_version == HTTP_VERSION_1_1 &&
+- !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
+- con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
+- }
-
+- if ((hctx->response->used != hlen) && blen > 0) {
+- http_chunk_append_mem(srv, con, c + (eol == EOL_RN ? 4: 2), blen + 1);
+- joblist_append(srv, con);
+- }
++ if (ign[j]) continue;
+
- if ((hctx->response->used != hlen) && blen > 0) {
- http_chunk_append_mem(srv, con, c + (eol == EOL_RN ? 4: 2), blen + 1);
- joblist_append(srv, con);
- }
++ if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Location"))) {
++ /* CGI/1.1 rev 03 - 7.2.1.2 */
++ if (con->http_status == 0) con->http_status = 302;
++ } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Content-Length"))) {
++ have_content_length = 1;
}
--
+
+- con->file_started = 1;
++ if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
++ ds = data_response_init();
++ }
++ buffer_copy_string_buffer(ds->key, header->key);
++ buffer_copy_string_buffer(ds->value, header->value);
+
- con->file_started = 1;
++ array_insert_unique(con->response.headers, (data_unset *)ds);
}
- } else {
- http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
- joblist_append(srv, con);
+- } else {
+- http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
+- joblist_append(srv, con);
++
++ con->file_started = 1;
++
++ if (con->request.http_version == HTTP_VERSION_1_1 &&
++ !have_content_length) {
++ con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
++ }
++
++ hctx->state = SCGI_STATE_RESPONSE_CONTENT;
++ break;
}
-
-#if 0
-+
-+#if 0
- log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), b->ptr);
- #endif
+- log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), b->ptr);
+-#endif
}
-
++
++ /* FIXME: pass the response-header to the other plugins to
++ * setup the filter-queue
++ *
++ * - use next-queue instead of con->write_queue
++ */
++
++ assert(hctx->state == SCGI_STATE_RESPONSE_CONTENT);
++
++ /* FIXME: if we have a content-length or chunked-encoding
++ * handle it.
++ *
++ * for now we wait for EOF on the socket */
++
++ /* copy the content to the next cq */
++ for (c = hctx->rb->first; c; c = c->next) {
++ http_chunk_append_mem(srv, con, c->mem->ptr + c->offset, c->mem->used - c->offset);
++
++ c->offset = c->mem->used - 1;
++ }
++
++ chunkqueue_remove_finished_chunks(hctx->rb);
++ joblist_append(srv, con);
+
return 0;
}
*/
/* nothing to sort, only one element */
-@@ -1909,9 +1905,9 @@
+@@ -1909,9 +1771,9 @@
for (p = proc; p->next && p->next->load < proc->load; p = p->next);
* ^
* |
* +
-@@ -1930,16 +1926,16 @@
+@@ -1930,16 +1792,16 @@
if (proc->prev) proc->prev->next = proc->next;
if (proc->next) proc->next->prev = proc->prev;
p->pid, p->load);
}
#else
-@@ -1951,21 +1947,21 @@
+@@ -1951,21 +1813,21 @@
int scgi_proclist_sort_down(server *srv, scgi_extension_host *host, scgi_proc *proc) {
scgi_proc *p;
* in ram and is not swapped out yet
* - processes that are not reused will be killed
* after some time by the trigger-handler
-@@ -1975,7 +1971,7 @@
+@@ -1975,7 +1837,7 @@
* ice-cold processes are propably unused since more
* than 'unused-timeout', are swaped out and won't be
* reused in the next seconds anyway.
*/
/* nothing to sort, only one element */
-@@ -1984,16 +1980,16 @@
+@@ -1984,16 +1846,16 @@
for (p = host->first; p != proc && p->load < proc->load; p = p->next);
/* we have to move left. If we are already the first element
* we are done */
if (host->first == proc) return 0;
-@@ -2009,9 +2005,9 @@
+@@ -2009,9 +1871,9 @@
p->prev = proc;
if (proc->prev == NULL) host->first = proc;
p->pid, p->load);
}
#else
-@@ -2023,41 +2019,42 @@
+@@ -2023,41 +1885,42 @@
static int scgi_restart_dead_procs(server *srv, plugin_data *p, scgi_extension_host *host) {
scgi_proc *proc;
switch(waitpid(proc->pid, &status, WNOHANG)) {
case 0:
/* child is still alive */
-@@ -2067,33 +2064,34 @@
+@@ -2067,33 +1930,34 @@
default:
if (WIFEXITED(status)) {
#if 0
if (p->conf.debug) {
log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd",
"--- scgi spawning",
-@@ -2101,18 +2099,18 @@
+@@ -2101,18 +1965,18 @@
"\n\tsocket", host->unixsocket,
"\n\tcurrent:", 1, "/", host->min_procs);
}
return 0;
}
-@@ -2121,13 +2119,13 @@
+@@ -2121,13 +1985,13 @@
plugin_data *p = hctx->plugin_data;
scgi_extension_host *host= hctx->host;
connection *con = hctx->remote_conn;
"write-req: error",
host,
host->host->used,
-@@ -2135,179 +2133,180 @@
+@@ -2135,259 +1999,260 @@
host->unixsocket->used);
return HANDLER_ERROR;
}
+
switch(hctx->state) {
- case FCGI_STATE_INIT:
+- case FCGI_STATE_INIT:
++ case SCGI_STATE_INIT:
ret = host->unixsocket->used ? AF_UNIX : AF_INET;
-
+- if (-1 == (hctx->fd = socket(ret, SOCK_STREAM, 0))) {
+
- if (-1 == (hctx->fd = socket(ret, SOCK_STREAM, 0))) {
++ if (-1 == (hctx->sock->fd = socket(ret, SOCK_STREAM, 0))) {
if (errno == EMFILE ||
errno == EINTR) {
- log_error_write(srv, __FILE__, __LINE__, "sd",
-+ log_error_write(srv, __FILE__, __LINE__, "sd",
- "wait for fd at connection:", con->fd);
+- "wait for fd at connection:", con->fd);
-
++ log_error_write(srv, __FILE__, __LINE__, "sd",
++ "wait for fd at connection:", con->sock->fd);
+
return HANDLER_WAIT_FOR_FD;
}
"socket failed:", strerror(errno), srv->cur_fds, srv->max_fds);
return HANDLER_ERROR;
}
- hctx->fde_ndx = -1;
+- hctx->fde_ndx = -1;
-
++ hctx->sock->fde_ndx = -1;
+
srv->cur_fds++;
-
-+
- fdevent_register(srv->ev, hctx->fd, scgi_handle_fdevent, hctx);
+- fdevent_register(srv->ev, hctx->fd, scgi_handle_fdevent, hctx);
-
-+
- if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) {
+- if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) {
- log_error_write(srv, __FILE__, __LINE__, "ss",
++
++ fdevent_register(srv->ev, hctx->sock, scgi_handle_fdevent, hctx);
++
++ if (-1 == fdevent_fcntl_set(srv->ev, hctx->sock)) {
+ log_error_write(srv, __FILE__, __LINE__, "ss",
"fcntl failed: ", strerror(errno));
-
-
+
/* fall through */
- case FCGI_STATE_CONNECT:
- if (hctx->state == FCGI_STATE_INIT) {
+- case FCGI_STATE_CONNECT:
+- if (hctx->state == FCGI_STATE_INIT) {
- for (hctx->proc = hctx->host->first;
- hctx->proc && hctx->proc->state != PROC_STATE_RUNNING;
++ case SCGI_STATE_CONNECT:
++ if (hctx->state == SCGI_STATE_INIT) {
+ for (hctx->proc = hctx->host->first;
+ hctx->proc && hctx->proc->state != PROC_STATE_RUNNING;
hctx->proc = hctx->proc->next);
+
/* all childs are dead */
if (hctx->proc == NULL) {
- hctx->fde_ndx = -1;
+- hctx->fde_ndx = -1;
-
++ hctx->sock->fde_ndx = -1;
+
return HANDLER_ERROR;
}
+
switch (scgi_establish_connection(srv, hctx)) {
case 1:
- scgi_set_state(srv, hctx, FCGI_STATE_CONNECT);
+- scgi_set_state(srv, hctx, FCGI_STATE_CONNECT);
-
++ scgi_set_state(srv, hctx, SCGI_STATE_CONNECT);
+
/* connection is in progress, wait for an event and call getsockopt() below */
-
-+
- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
+- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
-
++
++ fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
+
return HANDLER_WAIT_FOR_EVENT;
case -1:
/* if ECONNREFUSED choose another connection -> FIXME */
- hctx->fde_ndx = -1;
+- hctx->fde_ndx = -1;
-
++ hctx->sock->fde_ndx = -1;
+
return HANDLER_ERROR;
default:
-
+
/* try to finish the connect() */
- if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
+- if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
- log_error_write(srv, __FILE__, __LINE__, "ss",
++ if (0 != getsockopt(hctx->sock->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
+ log_error_write(srv, __FILE__, __LINE__, "ss",
"getsockopt failed:", strerror(errno));
-
if (p->conf.debug) {
log_error_write(srv, __FILE__, __LINE__, "sddbdd",
- "got proc:",
-+ "got proc:",
- hctx->fd,
+- hctx->fd,
- hctx->proc->pid,
- hctx->proc->socket,
++ "got proc:",
++ hctx->sock->fd,
+ hctx->proc->pid,
+ hctx->proc->socket,
hctx->proc->port,
/* move the proc-list entry down the list */
scgi_proclist_sort_up(srv, hctx->host, hctx->proc);
-
+- scgi_set_state(srv, hctx, FCGI_STATE_PREPARE_WRITE);
+
- scgi_set_state(srv, hctx, FCGI_STATE_PREPARE_WRITE);
++ scgi_set_state(srv, hctx, SCGI_STATE_PREPARE_WRITE);
/* fall through */
- case FCGI_STATE_PREPARE_WRITE:
+- case FCGI_STATE_PREPARE_WRITE:
++ case SCGI_STATE_PREPARE_WRITE:
scgi_create_env(srv, hctx);
-
-+
- scgi_set_state(srv, hctx, FCGI_STATE_WRITE);
+- scgi_set_state(srv, hctx, FCGI_STATE_WRITE);
-
++
++ scgi_set_state(srv, hctx, SCGI_STATE_WRITE);
+
/* fall through */
- case FCGI_STATE_WRITE:
+- case FCGI_STATE_WRITE:
- ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb);
-+ ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb);
++ case SCGI_STATE_WRITE:
++ ret = srv->network_backend_write(srv, con, hctx->sock, hctx->wb);
chunkqueue_remove_finished_chunks(hctx->wb);
-
+
return HANDLER_ERROR;
} else {
- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
+- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
-
++ fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
+
return HANDLER_WAIT_FOR_EVENT;
}
+
if (hctx->wb->bytes_out == hctx->wb->bytes_in) {
/* we don't need the out event anymore */
- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
-@@ -2315,10 +2314,10 @@
- scgi_set_state(srv, hctx, FCGI_STATE_READ);
+- fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
+- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
+- scgi_set_state(srv, hctx, FCGI_STATE_READ);
++ fdevent_event_del(srv->ev, hctx->sock);
++ fdevent_event_add(srv->ev, hctx->sock, FDEVENT_IN);
++ scgi_set_state(srv, hctx, SCGI_STATE_RESPONSE_HEADER);
} else {
- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
+- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
-
++ fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
+
return HANDLER_WAIT_FOR_EVENT;
}
-
+
break;
- case FCGI_STATE_READ:
+- case FCGI_STATE_READ:
++ case SCGI_STATE_RESPONSE_HEADER:
/* waiting for a response */
-@@ -2327,67 +2326,67 @@
+ break;
+ default:
log_error_write(srv, __FILE__, __LINE__, "s", "(debug) unknown state");
return HANDLER_ERROR;
}
host->active_procs--;
}
-
-+
- if (hctx->state == FCGI_STATE_INIT ||
- hctx->state == FCGI_STATE_CONNECT) {
+- if (hctx->state == FCGI_STATE_INIT ||
+- hctx->state == FCGI_STATE_CONNECT) {
- /* connect() or getsockopt() failed,
- * restart the request-handling
++
++ if (hctx->state == SCGI_STATE_INIT ||
++ hctx->state == SCGI_STATE_CONNECT) {
+ /* connect() or getsockopt() failed,
+ * restart the request-handling
*/
*/
if (proc->state == PROC_STATE_RUNNING &&
hctx->pid == proc->pid) {
-@@ -2395,25 +2394,25 @@
+@@ -2395,25 +2260,25 @@
}
}
scgi_restart_dead_procs(srv, p, host);
return HANDLER_FINISHED;
}
case HANDLER_WAIT_FOR_EVENT:
-@@ -2433,23 +2432,23 @@
+@@ -2433,23 +2298,23 @@
static handler_t scgi_connection_close(server *srv, handler_ctx *hctx) {
plugin_data *p;
connection *con;
-
- log_error_write(srv, __FILE__, __LINE__, "ssdsd",
- "emergency exit: scgi:",
-+
-+ log_error_write(srv, __FILE__, __LINE__, "ssdsd",
-+ "emergency exit: scgi:",
- "connection-fd:", con->fd,
- "fcgi-fd:", hctx->fd);
+- "connection-fd:", con->fd,
+- "fcgi-fd:", hctx->fd);
-
-
-
+
++ log_error_write(srv, __FILE__, __LINE__, "ssdsd",
++ "emergency exit: scgi:",
++ "connection-fd:", con->sock->fd,
++ "fcgi-fd:", hctx->sock->fd);
++
+
+
scgi_connection_cleanup(srv, hctx);
return HANDLER_FINISHED;
}
-@@ -2459,7 +2458,7 @@
+@@ -2459,27 +2324,28 @@
handler_ctx *hctx = ctx;
connection *con = hctx->remote_conn;
plugin_data *p = hctx->plugin_data;
scgi_proc *proc = hctx->proc;
scgi_extension_host *host= hctx->host;
-@@ -2471,15 +2470,15 @@
+ if ((revents & FDEVENT_IN) &&
+- hctx->state == FCGI_STATE_READ) {
++ (hctx->state == SCGI_STATE_RESPONSE_HEADER ||
++ hctx->state == SCGI_STATE_RESPONSE_CONTENT)) {
+ switch (scgi_demux_response(srv, hctx)) {
+ case 0:
+ break;
case 1:
/* we are done */
scgi_connection_cleanup(srv, hctx);
switch(waitpid(proc->pid, &status, WNOHANG)) {
case 0:
/* child is still alive */
-@@ -2489,19 +2488,19 @@
+@@ -2489,19 +2355,19 @@
default:
/* the child should not terminate at all */
if (WIFEXITED(status)) {
if (p->conf.debug) {
log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd",
"--- scgi spawning",
-@@ -2509,40 +2508,41 @@
+@@ -2509,40 +2375,41 @@
"\n\tsocket", host->unixsocket,
"\n\tcurrent:", 1, "/", host->min_procs);
}
+
+ log_error_write(srv, __FILE__, __LINE__, "sdsdsd",
"response not sent, request not sent, reconnection.",
- "connection-fd:", con->fd,
- "fcgi-fd:", hctx->fd);
+- "connection-fd:", con->fd,
+- "fcgi-fd:", hctx->fd);
-
++ "connection-fd:", con->sock->fd,
++ "fcgi-fd:", hctx->sock->fd);
+
return HANDLER_WAIT_FOR_FD;
}
+
+ log_error_write(srv, __FILE__, __LINE__, "sosdsd",
"response not sent, request sent:", hctx->wb->bytes_out,
- "connection-fd:", con->fd,
- "fcgi-fd:", hctx->fd);
+- "connection-fd:", con->fd,
+- "fcgi-fd:", hctx->fd);
-
++ "connection-fd:", con->sock->fd,
++ "fcgi-fd:", hctx->sock->fd);
+
scgi_connection_cleanup(srv, hctx);
-
connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
buffer_reset(con->physical.path);
con->http_status = 500;
-@@ -2550,76 +2550,76 @@
+@@ -2550,76 +2417,77 @@
} else {
/* response might have been already started, kill the connection */
scgi_connection_cleanup(srv, hctx);
+
+ log_error_write(srv, __FILE__, __LINE__, "ssdsd",
"response already sent out, termination connection",
- "connection-fd:", con->fd,
- "fcgi-fd:", hctx->fd);
+- "connection-fd:", con->fd,
+- "fcgi-fd:", hctx->fd);
-
++ "connection-fd:", con->sock->fd,
++ "fcgi-fd:", hctx->sock->fd);
+
connection_set_state(srv, con, CON_STATE_ERROR);
}
-
+
if (revents & FDEVENT_OUT) {
- if (hctx->state == FCGI_STATE_CONNECT ||
- hctx->state == FCGI_STATE_WRITE) {
+- if (hctx->state == FCGI_STATE_CONNECT ||
+- hctx->state == FCGI_STATE_WRITE) {
++ if (hctx->state == SCGI_STATE_CONNECT ||
++ hctx->state == SCGI_STATE_WRITE) {
/* we are allowed to send something out
- *
+ *
+
/* perhaps this issue is already handled */
if (revents & FDEVENT_HUP) {
- if (hctx->state == FCGI_STATE_CONNECT) {
+- if (hctx->state == FCGI_STATE_CONNECT) {
++ if (hctx->state == SCGI_STATE_CONNECT) {
/* getoptsock will catch this one (right ?)
- *
- * if we are in connect we might get a EINPROGRESS
+ *
*/
return mod_scgi_handle_subrequest(srv, con, p);
- } else if (hctx->state == FCGI_STATE_READ &&
+- } else if (hctx->state == FCGI_STATE_READ &&
++ } else if ((hctx->state == SCGI_STATE_RESPONSE_HEADER ||
++ hctx->state == SCGI_STATE_RESPONSE_CONTENT ) &&
hctx->proc->port == 0) {
/* FIXME:
- *
"fcgi: got a FDEVENT_ERR. Don't know why.");
/* kill all connections to the scgi process */
-@@ -2628,42 +2628,39 @@
+@@ -2628,42 +2496,39 @@
scgi_connection_close(srv, hctx);
joblist_append(srv, con);
}
static handler_t scgi_check_extension(server *srv, connection *con, void *p_d, int uri_path_handler) {
plugin_data *p = p_d;
-@@ -2673,30 +2670,30 @@
+@@ -2673,30 +2538,30 @@
size_t k;
buffer *fn;
scgi_extension *extension = NULL;
/* check extension in the form "/scgi_pattern" */
if (*(extension->key->ptr) == '/' && strncmp(fn->ptr, extension->key->ptr, ct_len) == 0) {
break;
-@@ -2710,17 +2707,17 @@
+@@ -2710,17 +2575,17 @@
if (k == p->conf.exts->used) {
return HANDLER_GO_ON;
}
ndx = k;
}
}
-@@ -2728,12 +2725,12 @@
+@@ -2728,12 +2593,12 @@
/* found a server */
if (ndx != -1) {
scgi_extension_host *host = extension->hosts[ndx];
/* init handler-context */
if (uri_path_handler) {
if (host->check_local == 0) {
-@@ -2741,7 +2738,7 @@
+@@ -2741,7 +2606,7 @@
char *pathinfo;
hctx = handler_ctx_init();
hctx->remote_conn = con;
hctx->plugin_data = p;
hctx->host = host;
-@@ -2749,45 +2746,45 @@
+@@ -2749,45 +2614,45 @@
hctx->conf.exts = p->conf.exts;
hctx->conf.debug = p->conf.debug;
con->uri.path->used -= con->request.pathinfo->used - 1;
con->uri.path->ptr[con->uri.path->used - 1] = '\0';
}
-@@ -2796,21 +2793,21 @@
+@@ -2796,21 +2661,21 @@
} else {
handler_ctx *hctx;
hctx = handler_ctx_init();
if (con->conf.log_request_handling) {
log_error_write(srv, __FILE__, __LINE__, "s", "handling it in mod_fastcgi");
}
-@@ -2821,11 +2818,11 @@
+@@ -2821,11 +2686,11 @@
/* no handler found */
buffer_reset(con->physical.path);
con->http_status = 500;
return HANDLER_FINISHED;
}
return HANDLER_GO_ON;
-@@ -2844,19 +2841,19 @@
+@@ -2844,21 +2709,22 @@
JOBLIST_FUNC(mod_scgi_handle_joblist) {
plugin_data *p = p_d;
handler_ctx *hctx = con->plugin_ctx[p->id];
+
if (hctx == NULL) return HANDLER_GO_ON;
- if (hctx->fd != -1) {
+- if (hctx->fd != -1) {
++ if (hctx->sock->fd != -1) {
switch (hctx->state) {
- case FCGI_STATE_READ:
- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
+- case FCGI_STATE_READ:
+- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
-
++ case SCGI_STATE_RESPONSE_HEADER:
++ case SCGI_STATE_RESPONSE_CONTENT:
++ fdevent_event_add(srv->ev, hctx->sock, FDEVENT_IN);
+
break;
- case FCGI_STATE_CONNECT:
- case FCGI_STATE_WRITE:
- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
+- case FCGI_STATE_CONNECT:
+- case FCGI_STATE_WRITE:
+- fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
-
++ case SCGI_STATE_CONNECT:
++ case SCGI_STATE_WRITE:
++ fdevent_event_add(srv->ev, hctx->sock, FDEVENT_OUT);
+
break;
- case FCGI_STATE_INIT:
+- case FCGI_STATE_INIT:
++ case SCGI_STATE_INIT:
/* at reconnect */
-@@ -2873,21 +2870,21 @@
+ break;
+ default:
+@@ -2873,21 +2739,21 @@
static handler_t scgi_connection_close_callback(server *srv, connection *con, void *p_d) {
plugin_data *p = p_d;
*/
/* check all childs if they are still up */
-@@ -2904,47 +2901,47 @@
+@@ -2904,47 +2770,47 @@
scgi_extension *ex;
ex = exts->exts[j];
if (buffer_is_empty(host->unixsocket)) {
fp->port = host->port + fp->id;
} else {
-@@ -2952,13 +2949,13 @@
+@@ -2952,13 +2818,13 @@
buffer_append_string(fp->socket, "-");
buffer_append_long(fp->socket, fp->id);
}
fp->prev = NULL;
fp->next = host->first;
if (host->first) {
-@@ -2966,56 +2963,57 @@
+@@ -2966,56 +2832,57 @@
}
host->first = fp;
}
switch (waitpid(proc->pid, &status, WNOHANG)) {
case 0:
/* child still running after timeout, good */
-@@ -3023,10 +3021,10 @@
+@@ -3023,10 +2890,10 @@
case -1:
if (errno != EINTR) {
/* no PID found ? should never happen */
#if 0
if (errno == ECHILD) {
/* someone else has cleaned up for us */
-@@ -3040,25 +3038,26 @@
+@@ -3040,25 +2907,26 @@
/* the child should not terminate at all */
if (WIFEXITED(status)) {
if (proc->state != PROC_STATE_KILLED) {
}
}
}
-@@ -3082,8 +3081,8 @@
+@@ -3082,8 +2950,8 @@
p->handle_subrequest = mod_scgi_handle_subrequest;
p->handle_joblist = mod_scgi_handle_joblist;
p->handle_trigger = mod_scgi_handle_trigger;
return 0;
}
--- ../lighttpd-1.4.11/src/mod_secure_download.c 2005-12-14 14:37:29.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_secure_download.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/mod_secure_download.c 2006-07-16 00:26:03.000000000 +0300
@@ -25,7 +25,7 @@
#ifdef USE_OPENSSL
#define IN const
return 0;
}
--- ../lighttpd-1.4.11/src/mod_setenv.c 2006-01-14 20:33:12.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_setenv.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/mod_setenv.c 2006-07-16 00:26:04.000000000 +0300
@@ -18,25 +18,25 @@
typedef struct {
array *request_header;
return 0;
}
--- ../lighttpd-1.4.11/src/mod_simple_vhost.c 2005-11-18 15:16:13.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_simple_vhost.c 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/mod_simple_vhost.c 2006-07-16 00:26:04.000000000 +0300
@@ -10,6 +10,8 @@
#include "plugin.h"
return 0;
}
--- ../lighttpd-1.4.11/src/mod_skeleton.c 2005-10-02 18:30:51.000000000 +0300
-+++ lighttpd-1.4.12/src/mod_skeleton.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/mod_skeleton.c 2006-07-16 00:26:03.000000000 +0300
@@ -14,13 +14,13 @@
/**
return 0;
}
--- ../lighttpd-1.4.11/src/mod_sql_vhost_core.c 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.4.12/src/mod_sql_vhost_core.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/mod_sql_vhost_core.c 2006-07-16 00:26:04.000000000 +0300
@@ -0,0 +1,209 @@
+#include <stdio.h>
+#include <errno.h>
+}
+
--- ../lighttpd-1.4.11/src/mod_sql_vhost_core.h 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.4.12/src/mod_sql_vhost_core.h 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/mod_sql_vhost_core.h 2006-07-16 00:26:04.000000000 +0300
@@ -0,0 +1,49 @@
+#ifndef _MOD_SQL_VHOST_CORE_H_
+#define _MOD_SQL_VHOST_CORE_H_
+
+#endif
--- ../lighttpd-1.4.11/src/mod_ssi.c 2006-03-04 17:09:48.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_ssi.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/mod_ssi.c 2006-07-16 00:26:04.000000000 +0300
@@ -6,7 +6,6 @@
#include <string.h>
#include <errno.h>
return 0;
}
--- ../lighttpd-1.4.11/src/mod_ssi.h 2005-08-11 01:26:39.000000000 +0300
-+++ lighttpd-1.4.12/src/mod_ssi.h 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/mod_ssi.h 2006-07-16 00:26:04.000000000 +0300
@@ -19,23 +19,23 @@
typedef struct {
int ssi_eval_expr(server *srv, connection *con, plugin_data *p, const char *expr);
--- ../lighttpd-1.4.11/src/mod_ssi_expr.c 2005-08-11 01:26:48.000000000 +0300
-+++ lighttpd-1.4.12/src/mod_ssi_expr.c 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/mod_ssi_expr.c 2006-07-16 00:26:04.000000000 +0300
@@ -11,9 +11,9 @@
const char *input;
size_t offset;
return context.val.bo;
}
--- ../lighttpd-1.4.11/src/mod_ssi_expr.h 2005-08-11 01:26:48.000000000 +0300
-+++ lighttpd-1.4.12/src/mod_ssi_expr.h 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/mod_ssi_expr.h 2006-07-16 00:26:04.000000000 +0300
@@ -5,16 +5,16 @@
typedef struct {
} ssi_ctx_t;
--- ../lighttpd-1.4.11/src/mod_ssi_exprparser.c 2005-10-03 00:40:25.000000000 +0300
-+++ lighttpd-1.4.12/src/mod_ssi_exprparser.c 2006-07-11 22:08:02.000000000 +0300
++++ lighttpd-1.4.12/src/mod_ssi_exprparser.c 2006-07-17 22:02:23.000000000 +0300
@@ -18,10 +18,10 @@
/* Next is all token values, in a form suitable for use by makeheaders.
** This section will be null unless lemon is run with the -m switch.
** This is what we do if the grammar does define ERROR:
**
--- ../lighttpd-1.4.11/src/mod_staticfile.c 2006-02-15 14:31:14.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_staticfile.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/mod_staticfile.c 2006-07-16 00:26:03.000000000 +0300
@@ -14,9 +14,11 @@
#include "http_chunk.h"
#include "response.h"
return 0;
}
--- ../lighttpd-1.4.11/src/mod_status.c 2006-01-10 21:45:32.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_status.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/mod_status.c 2006-07-16 00:26:04.000000000 +0300
@@ -4,7 +4,6 @@
#include <fcntl.h>
#include <stdlib.h>
return 0;
}
--- ../lighttpd-1.4.11/src/mod_trigger_b4_dl.c 2005-09-23 22:53:55.000000000 +0300
-+++ lighttpd-1.4.12/src/mod_trigger_b4_dl.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/mod_trigger_b4_dl.c 2006-07-16 00:26:03.000000000 +0300
@@ -24,18 +24,18 @@
/**
return 0;
}
--- ../lighttpd-1.4.11/src/mod_userdir.c 2005-10-28 16:48:28.000000000 +0300
-+++ lighttpd-1.4.12/src/mod_userdir.c 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/mod_userdir.c 2006-07-16 00:26:04.000000000 +0300
@@ -10,6 +10,7 @@
#include "response.h"
return 0;
}
--- ../lighttpd-1.4.11/src/mod_usertrack.c 2006-01-31 15:01:20.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_usertrack.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/mod_usertrack.c 2006-07-16 00:26:04.000000000 +0300
@@ -24,44 +24,44 @@
typedef struct {
return 0;
}
--- ../lighttpd-1.4.11/src/mod_webdav.c 2006-03-03 01:28:58.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_webdav.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/mod_webdav.c 2006-07-18 13:03:40.000000000 +0300
@@ -3,13 +3,10 @@
#include <ctype.h>
#include <stdlib.h>
if (con->request.http_version == HTTP_VERSION_1_1) {
BUFFER_COPY_STRING_CONST(b, "HTTP/1.1 ");
} else {
-@@ -458,11 +555,11 @@
+@@ -458,14 +555,13 @@
/* bind the values to the insert */
+
if (SQLITE_DONE != sqlite3_step(stmt)) {
/* */
- WP();
-@@ -493,14 +590,14 @@
+- WP();
+ }
+ }
+ #endif
+@@ -493,14 +589,14 @@
(de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')) {
continue;
/* ignore the parent dir */
buffer_append_string(d.rel_path, de->d_name);
/* stat and unlink afterwards */
-@@ -508,7 +605,7 @@
+@@ -508,7 +604,7 @@
/* don't about it yet, rmdir will fail too */
} else if (S_ISDIR(st.st_mode)) {
have_multi_status = webdav_delete_dir(srv, con, p, &d, b);
/* try to unlink it */
if (-1 == rmdir(d.path->ptr)) {
switch(errno) {
-@@ -535,11 +632,11 @@
+@@ -535,14 +631,13 @@
/* bind the values to the insert */
+
if (SQLITE_DONE != sqlite3_step(stmt)) {
/* */
- WP();
-@@ -569,7 +666,7 @@
+- WP();
+ }
+ }
+ #endif
+@@ -569,7 +664,7 @@
if (stream_open(&s, src->path)) {
return 403;
}
if (-1 == (ofd = open(dst->path->ptr, O_WRONLY|O_TRUNC|O_CREAT|(overwrite ? 0 : O_EXCL), 0600))) {
/* opening the destination failed for some reason */
switch(errno) {
-@@ -601,7 +698,7 @@
+@@ -601,7 +696,7 @@
break;
}
}
stream_close(&s);
close(ofd);
-@@ -614,16 +711,16 @@
+@@ -614,19 +709,18 @@
sqlite3_reset(stmt);
/* bind the values to the insert */
+
if (SQLITE_DONE != sqlite3_step(stmt)) {
/* */
- WP();
-@@ -655,21 +752,21 @@
+- WP();
+ }
+ }
+ }
+@@ -655,21 +749,21 @@
(de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')) {
continue;
}
buffer_append_string(d.rel_path, de->d_name);
if (-1 == stat(s.path->ptr, &st)) {
-@@ -692,16 +789,16 @@
+@@ -692,19 +786,18 @@
sqlite3_reset(stmt);
/* bind the values to the insert */
+
if (SQLITE_DONE != sqlite3_step(stmt)) {
/* */
- WP();
-@@ -721,7 +818,7 @@
+- WP();
+ }
+ }
+ #endif
+@@ -721,7 +814,7 @@
buffer_free(s.rel_path);
buffer_free(d.path);
buffer_free(d.rel_path);
closedir(srcdir);
}
-@@ -748,12 +845,12 @@
+@@ -748,12 +841,12 @@
if (S_ISDIR(sce->st.st_mode)) {
buffer_append_string(b, "<D:getcontenttype>httpd/unix-directory</D:getcontenttype>");
found = 1;
if (buffer_is_equal_right_len(dst->path, ds->key, ds->key->used - 1)) {
buffer_append_string(b,"<D:getcontenttype>");
buffer_append_string_buffer(b, ds->value);
-@@ -807,23 +904,23 @@
+@@ -807,23 +900,23 @@
/* bind the values to the insert */
found = 1;
}
}
-@@ -840,7 +937,7 @@
+@@ -840,7 +933,7 @@
char *prop;
} webdav_property;
{ "DAV:", "creationdate" },
{ "DAV:", "displayname" },
{ "DAV:", "getcontentlanguage" },
-@@ -871,8 +968,8 @@
+@@ -871,8 +964,8 @@
webdav_property *prop;
prop = props->ptr[i];
dst, prop->prop, prop->ns, b_200)) {
webdav_gen_prop_tag(srv, con, prop->prop, prop->ns, NULL, b_404);
}
-@@ -916,12 +1013,12 @@
+@@ -916,12 +1009,12 @@
if (-1 == c->file.fd && /* open the file if not already open */
-1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
strerror(errno), c->file.name, c->file.fd);
return -1;
-@@ -938,7 +1035,7 @@
+@@ -938,7 +1031,7 @@
if (XML_ERR_OK != (err = xmlParseChunk(ctxt, c->file.mmap.start + c->offset, weHave, 0))) {
log_error_write(srv, __FILE__, __LINE__, "sddd", "xmlParseChunk failed at:", cq->bytes_out, weHave, err);
}
c->offset += weHave;
cq->bytes_out += weHave;
-@@ -956,7 +1053,7 @@
+@@ -956,7 +1049,7 @@
if (XML_ERR_OK != (err = xmlParseChunk(ctxt, c->mem->ptr + c->offset, weHave, 0))) {
log_error_write(srv, __FILE__, __LINE__, "sddd", "xmlParseChunk failed at:", cq->bytes_out, weHave, err);
}
c->offset += weHave;
cq->bytes_out += weHave;
-@@ -991,6 +1088,113 @@
+@@ -991,6 +1084,113 @@
}
#endif
URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
plugin_data *p = p_d;
buffer *b;
-@@ -1001,7 +1205,8 @@
+@@ -1001,7 +1201,8 @@
buffer *prop_200;
buffer *prop_404;
webdav_properties *req_props;
UNUSED(srv);
if (!p->conf.enabled) return HANDLER_GO_ON;
-@@ -1019,7 +1224,19 @@
+@@ -1019,7 +1220,19 @@
req_props = NULL;
/* is there a content-body ? */
#ifdef USE_PROPPATCH
/* any special requests or just allprop ? */
if (con->request.content_length) {
-@@ -1087,12 +1304,12 @@
+@@ -1087,14 +1300,13 @@
/* get all property names (EMPTY) */
sqlite3_reset(stmt);
/* bind the values to the insert */
-
+
if (SQLITE_DONE != sqlite3_step(stmt)) {
- WP();
+- WP();
}
-@@ -1115,13 +1332,13 @@
+ }
+ } else if (0 == xmlStrcmp(cmd->name, BAD_CAST "allprop")) {
+@@ -1115,13 +1327,13 @@
response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
b = chunkqueue_get_append_buffer(con->write_queue);
prop_200 = buffer_init();
prop_404 = buffer_init();
-@@ -1129,7 +1346,7 @@
+@@ -1129,7 +1341,7 @@
case 0:
/* Depth: 0 */
webdav_get_props(srv, con, p, &(con->physical), req_props, prop_200, prop_404);
buffer_append_string(b,"<D:response>\n");
buffer_append_string(b,"<D:href>");
buffer_append_string_buffer(b, con->uri.scheme);
-@@ -1145,9 +1362,9 @@
+@@ -1145,9 +1357,9 @@
buffer_append_string_buffer(b, prop_200);
buffer_append_string(b,"</D:prop>\n");
buffer_append_string(b,"</D:propstat>\n");
}
if (!buffer_is_empty(prop_404)) {
-@@ -1157,16 +1374,16 @@
+@@ -1157,16 +1369,16 @@
buffer_append_string_buffer(b, prop_404);
buffer_append_string(b,"</D:prop>\n");
if (NULL != (dir = opendir(con->physical.path->ptr))) {
struct dirent *de;
physical d;
-@@ -1179,16 +1396,16 @@
+@@ -1179,16 +1391,16 @@
if (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0') {
continue;
/* ignore the parent dir */
} else {
buffer_append_string(d.path, de->d_name);
buffer_append_string(d.rel_path, de->d_name);
-@@ -1198,7 +1415,7 @@
+@@ -1198,7 +1410,7 @@
buffer_reset(prop_404);
webdav_get_props(srv, con, p, &d, req_props, prop_200, prop_404);
buffer_append_string(b,"<D:response>\n");
buffer_append_string(b,"<D:href>");
buffer_append_string_buffer(b, con->uri.scheme);
-@@ -1214,9 +1431,9 @@
+@@ -1214,9 +1426,9 @@
buffer_append_string_buffer(b, prop_200);
buffer_append_string(b,"</D:prop>\n");
buffer_append_string(b,"</D:propstat>\n");
}
if (!buffer_is_empty(prop_404)) {
-@@ -1226,9 +1443,9 @@
+@@ -1226,9 +1438,9 @@
buffer_append_string_buffer(b, prop_404);
buffer_append_string(b,"</D:prop>\n");
buffer_append_string(b,"</D:propstat>\n");
}
-@@ -1275,7 +1492,7 @@
+@@ -1275,7 +1487,7 @@
return HANDLER_FINISHED;
}
/* let's create the directory */
if (-1 == mkdir(con->physical.path->ptr, 0700)) {
-@@ -1303,7 +1520,13 @@
+@@ -1303,7 +1515,13 @@
con->http_status = 403;
return HANDLER_FINISHED;
}
/* stat and unlink afterwards */
if (-1 == stat(con->physical.path->ptr, &st)) {
/* don't about it yet, unlink will fail too */
-@@ -1323,7 +1546,7 @@
+@@ -1323,7 +1541,7 @@
response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
b = chunkqueue_get_append_buffer(con->write_queue);
buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
buffer_append_string(b,"<D:multistatus xmlns:D=\"DAV:\">\n");
-@@ -1331,7 +1554,7 @@
+@@ -1331,7 +1549,7 @@
buffer_append_string_buffer(b, multi_status_resp);
buffer_append_string(b,"</D:multistatus>\n");
if (p->conf.log_xml) {
log_error_write(srv, __FILE__, __LINE__, "sb", "XML-response-body:", b);
}
-@@ -1340,7 +1563,7 @@
+@@ -1340,7 +1558,7 @@
con->file_finished = 1;
} else {
/* everything went fine, remove the directory */
if (-1 == rmdir(con->physical.path->ptr)) {
switch(errno) {
case ENOENT:
-@@ -1375,97 +1598,174 @@
+@@ -1375,97 +1593,174 @@
case HTTP_METHOD_PUT: {
int fd;
chunkqueue *cq = con->request_content_queue;
case HTTP_METHOD_COPY: {
buffer *destination = NULL;
char *sep, *start;
-@@ -1475,7 +1775,15 @@
+@@ -1475,7 +1770,15 @@
con->http_status = 403;
return HANDLER_FINISHED;
}
if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Destination"))) {
destination = ds->value;
} else {
-@@ -1549,10 +1857,10 @@
+@@ -1549,10 +1852,10 @@
}
buffer_copy_string_buffer(p->physical.path, p->physical.doc_root);
if (p->physical.rel_path->ptr[0] == '/') {
buffer_append_string_len(p->physical.path, p->physical.rel_path->ptr + 1, p->physical.rel_path->used - 2);
} else {
-@@ -1613,6 +1921,12 @@
+@@ -1613,6 +1916,12 @@
/* it is just a file, good */
int r;
/* destination exists */
if (0 == (r = stat(p->physical.path->ptr, &st))) {
if (S_ISDIR(st.st_mode)) {
-@@ -1636,7 +1950,7 @@
+@@ -1636,7 +1945,7 @@
return HANDLER_FINISHED;
}
} else if (overwrite == 0) {
con->http_status = 412;
return HANDLER_FINISHED;
} else {
-@@ -1655,16 +1969,16 @@
+@@ -1655,16 +1964,16 @@
sqlite3_reset(stmt);
/* bind the values to the insert */
if (SQLITE_DONE != sqlite3_step(stmt)) {
log_error_write(srv, __FILE__, __LINE__, "ss", "sql-move failed:", sqlite3_errmsg(p->conf.sql));
}
-@@ -1691,12 +2005,17 @@
+@@ -1691,12 +2000,17 @@
return HANDLER_FINISHED;
}
/* check if destination exists */
if (-1 == stat(con->physical.path->ptr, &st)) {
switch(errno) {
-@@ -1737,7 +2056,7 @@
+@@ -1737,7 +2051,7 @@
sqlite3_stmt *stmt;
p->conf.stmt_delete_prop : p->conf.stmt_update_prop;
for (props = cmd->children; props; props = props->next) {
-@@ -1762,34 +2081,35 @@
+@@ -1762,34 +2076,35 @@
/* bind the values to the insert */
}
}
}
-@@ -1804,7 +2124,7 @@
+@@ -1804,7 +2119,7 @@
goto propmatch_cleanup;
}
con->http_status = 400;
} else {
if (SQLITE_OK != sqlite3_exec(p->conf.sql, "COMMIT", NULL, NULL, &err)) {
-@@ -1821,6 +2141,7 @@
+@@ -1821,6 +2136,7 @@
}
propmatch_cleanup:
xmlFreeDoc(xml);
} else {
con->http_status = 400;
-@@ -1830,11 +2151,307 @@
+@@ -1830,11 +2146,307 @@
#endif
con->http_status = 501;
return HANDLER_FINISHED;
/* not found */
return HANDLER_GO_ON;
}
-@@ -1845,14 +2462,14 @@
+@@ -1845,14 +2457,14 @@
int mod_webdav_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("webdav");
return 0;
}
--- ../lighttpd-1.4.11/src/network.c 2006-03-04 16:45:46.000000000 +0200
-+++ lighttpd-1.4.12/src/network.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/network.c 2006-07-18 13:03:40.000000000 +0300
@@ -1,14 +1,14 @@
#include <sys/types.h>
#include <sys/stat.h>
#endif
handler_t network_server_handle_fdevent(void *s, void *context, int revents) {
-@@ -31,11 +32,11 @@
+@@ -31,25 +32,25 @@
server_socket *srv_socket = (server_socket *)context;
connection *con;
int loops = 0;
- log_error_write(srv, __FILE__, __LINE__, "sdd",
+ log_error_write(srv, __FILE__, __LINE__, "sdd",
"strange event for server socket",
- srv_socket->fd,
+- srv_socket->fd,
++ srv_socket->sock->fd,
revents);
-@@ -44,12 +45,12 @@
+ return HANDLER_ERROR;
+ }
/* accept()s at most 100 connections directly
*
-
+
srv_socket = calloc(1, sizeof(*srv_socket));
- srv_socket->fd = -1;
+- srv_socket->fd = -1;
-
++ srv_socket->sock = iosocket_init();
+
srv_socket->srv_token = buffer_init();
buffer_copy_string_buffer(srv_socket->srv_token, host_token);
port = strtol(sp, NULL, 10);
if (host[0] == '/') {
-@@ -129,17 +130,17 @@
+@@ -129,18 +130,18 @@
is_unix_domain_socket = 1;
} else if (port == 0 || port > 65535) {
log_error_write(srv, __FILE__, __LINE__, "sd", "port out of range:", port);
srv_socket->addr.plain.sa_family = AF_UNIX;
-
+- if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, 0))) {
+
- if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, 0))) {
++ if (-1 == (srv_socket->sock->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, 0))) {
log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno));
return -1;
-@@ -154,7 +155,7 @@
+ }
+@@ -154,32 +155,32 @@
#ifdef HAVE_IPV6
if (s->use_ipv6) {
srv_socket->addr.plain.sa_family = AF_INET6;
-
+- if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) {
+
- if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) {
++ if (-1 == (srv_socket->sock->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) {
log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno));
return -1;
-@@ -162,7 +163,7 @@
+ }
srv_socket->use_ipv6 = 1;
}
#endif
-
+- if (srv_socket->fd == -1) {
+
- if (srv_socket->fd == -1) {
++ if (srv_socket->sock->fd == -1) {
srv_socket->addr.plain.sa_family = AF_INET;
- if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) {
-@@ -170,16 +171,16 @@
+- if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) {
++ if (-1 == (srv_socket->sock->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno));
return -1;
}
}
-
+
/* */
- srv->cur_fds = srv_socket->fd;
+- srv->cur_fds = srv_socket->fd;
-
++ srv->cur_fds = srv_socket->sock->fd;
+
val = 1;
- if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
+- if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
++ if (setsockopt(srv_socket->sock->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
log_error_write(srv, __FILE__, __LINE__, "ss", "socketsockopt failed:", strerror(errno));
return -1;
}
#ifdef SUN_LEN
addr_len = SUN_LEN(&srv_socket->addr.un);
#else
-@@ -259,8 +261,8 @@
- if (-1 != (fd = connect(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len))) {
+@@ -256,11 +258,11 @@
+ #endif
+
+ /* check if the socket exists and try to connect to it. */
+- if (-1 != (fd = connect(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len))) {
++ if (-1 != (fd = connect(srv_socket->sock->fd, (struct sockaddr *) &(srv_socket->addr), addr_len))) {
close(fd);
- log_error_write(srv, __FILE__, __LINE__, "ss",
return -1;
}
-
+- if (0 != bind(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) {
+
- if (0 != bind(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) {
++ if (0 != bind(srv_socket->sock->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) {
switch(srv_socket->addr.plain.sa_family) {
case AF_UNIX:
- log_error_write(srv, __FILE__, __LINE__, "sds",
return -1;
}
-
+- if (-1 == listen(srv_socket->fd, 128 * 8)) {
+
- if (-1 == listen(srv_socket->fd, 128 * 8)) {
++ if (-1 == listen(srv_socket->sock->fd, 128 * 8)) {
log_error_write(srv, __FILE__, __LINE__, "ss", "listen failed: ", strerror(errno));
return -1;
}
return -1;
#endif
} else {
-@@ -390,10 +393,10 @@
+@@ -383,17 +386,16 @@
+ */
+ memset(&afa, 0, sizeof(afa));
+ strcpy(afa.af_name, "httpready");
+- if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)) < 0) {
++ if (setsockopt(srv_socket->sock->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)) < 0) {
+ if (errno != ENOENT) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "can't set accept-filter 'httpready': ", strerror(errno));
+ }
}
#endif
}
-
+
srv_socket->is_ssl = s->is_ssl;
- srv_socket->fde_ndx = -1;
+- srv_socket->fde_ndx = -1;
-
+
if (srv->srv_sockets.size == 0) {
srv->srv_sockets.size = 4;
srv->srv_sockets.used = 0;
-@@ -402,11 +405,10 @@
+@@ -402,11 +404,10 @@
srv->srv_sockets.size += 4;
srv->srv_sockets.ptr = realloc(srv->srv_sockets.ptr, srv->srv_sockets.size * sizeof(server_socket));
}
return 0;
}
-@@ -414,45 +416,58 @@
+@@ -414,45 +415,60 @@
size_t i;
for (i = 0; i < srv->srv_sockets.used; i++) {
server_socket *srv_socket = srv->srv_sockets.ptr[i];
-
+- if (srv_socket->fd != -1) {
+
- if (srv_socket->fd != -1) {
++ if (srv_socket->sock->fd != -1) {
/* check if server fd are already registered */
- if (srv_socket->fde_ndx != -1) {
- fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
- fdevent_unregister(srv->ev, srv_socket->fd);
+- if (srv_socket->fde_ndx != -1) {
+- fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
+- fdevent_unregister(srv->ev, srv_socket->fd);
++ if (srv_socket->sock->fde_ndx != -1) {
++ fdevent_event_del(srv->ev, srv_socket->sock);
++ fdevent_unregister(srv->ev, srv_socket->sock);
}
-
+- close(srv_socket->fd);
+
- close(srv_socket->fd);
- }
--
++ closesocket(srv_socket->sock->fd);
++ }
+
+ if (srv_socket->is_ssl) {
+#ifdef USE_OPENSSL
+ SSL_CTX_free(srv_socket->ssl_ctx);
+#endif
-+ }
+ }
+-
++
++ iosocket_free(srv_socket->sock);
+
buffer_free(srv_socket->srv_token);
-
/* lowest id wins */
#if defined USE_LINUX_SENDFILE
{ NETWORK_BACKEND_LINUX_SENDFILE, "linux-sendfile" },
-@@ -466,21 +481,30 @@
+@@ -466,21 +482,30 @@
#if defined USE_WRITEV
{ NETWORK_BACKEND_WRITEV, "writev" },
#endif
#ifdef USE_OPENSSL
srv->network_ssl_backend_write = network_write_chunkqueue_openssl;
#endif
-@@ -500,54 +524,80 @@
+@@ -500,54 +525,80 @@
if (NULL == network_backends[i].name) {
/* we don't know it */
return -1;
}
-@@ -558,36 +608,47 @@
+@@ -558,36 +609,47 @@
break;
}
}
for (i = 0; i < srv->srv_sockets.used; i++) {
server_socket *srv_socket = srv->srv_sockets.ptr[i];
-
- fdevent_register(srv->ev, srv_socket->fd, network_server_handle_fdevent, srv_socket);
- fdevent_event_add(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
+- fdevent_register(srv->ev, srv_socket->fd, network_server_handle_fdevent, srv_socket);
+- fdevent_event_add(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
++ fdevent_register(srv->ev, srv_socket->sock, network_server_handle_fdevent, srv_socket);
++ fdevent_event_add(srv->ev, srv_socket->sock, FDEVENT_IN);
}
return 0;
}
-int network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq) {
- int ret = -1;
+network_status_t network_read_chunkqueue(server *srv, connection *con, chunkqueue *cq) {
-+ server_socket *srv_socket = con->srv_socket;
++ server_socket *srv_socket = con->srv_socket;
+
+ if (srv_socket->is_ssl) {
+#ifdef USE_OPENSSL
-+ return srv->network_ssl_backend_read(srv, con, con->ssl, cq);
++ return srv->network_ssl_backend_read(srv, con, con->sock, cq);
+#else
+ return NETWORK_STATUS_FATAL_ERROR;
+#endif
+ } else {
-+ return srv->network_backend_read(srv, con, con->fd, cq);
++ return srv->network_backend_read(srv, con, con->sock, cq);
+ }
+}
+
int corked = 0;
#endif
server_socket *srv_socket = con->srv_socket;
-@@ -600,11 +661,11 @@
+@@ -600,37 +662,42 @@
joblist_append(srv, con);
return 1;
/* Linux: put a cork into the socket as we want to combine the write() calls
* but only if we really have multiple chunks
*/
-@@ -613,7 +674,7 @@
- setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
+ if (cq->first && cq->first->next) {
+ corked = 1;
+- setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
++ setsockopt(con->sock->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
}
#endif
-
+
if (srv_socket->is_ssl) {
#ifdef USE_OPENSSL
- ret = srv->network_ssl_backend_write(srv, con, con->ssl, cq);
-@@ -621,12 +682,17 @@
+- ret = srv->network_ssl_backend_write(srv, con, con->ssl, cq);
++ ret = srv->network_ssl_backend_write(srv, con, con->sock, cq);
+ #endif
} else {
- ret = srv->network_backend_write(srv, con, con->fd, cq);
+- ret = srv->network_backend_write(srv, con, con->fd, cq);
++ ret = srv->network_backend_write(srv, con, con->sock, cq);
}
-
- if (ret >= 0) {
#ifdef TCP_CORK
if (corked) {
corked = 0;
-@@ -639,13 +705,13 @@
+- setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
++ setsockopt(con->sock->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
+ }
+ #endif
+
+@@ -639,13 +706,13 @@
con->bytes_written_cur_second += written;
*(con->conf.global_bytes_per_second_cnt_ptr) += written;
return ret;
}
--- ../lighttpd-1.4.11/src/network.h 2005-08-11 01:26:42.000000000 +0300
-+++ lighttpd-1.4.12/src/network.h 2006-07-11 22:07:51.000000000 +0300
-@@ -3,7 +3,8 @@
++++ lighttpd-1.4.12/src/network.h 2006-07-18 13:03:40.000000000 +0300
+@@ -3,11 +3,13 @@
#include "server.h"
int network_init(server *srv);
int network_close(server *srv);
+
+ int network_register_fdevents(server *srv);
++handler_t network_server_handle_fdevent(void *s, void *context, int revents);
+
+ #endif
--- ../lighttpd-1.4.11/src/network_backends.h 2005-10-24 15:13:51.000000000 +0300
-+++ lighttpd-1.4.12/src/network_backends.h 2006-07-11 22:07:52.000000000 +0300
-@@ -43,16 +43,52 @@
++++ lighttpd-1.4.12/src/network_backends.h 2006-07-18 13:03:40.000000000 +0300
+@@ -43,16 +43,47 @@
# define USE_AIX_SENDFILE
#endif
+#include "network.h"
+
+#define NETWORK_BACKEND_WRITE_CHUNK(x) \
-+ network_status_t network_write_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq, chunk *c)
++ network_status_t network_write_chunkqueue_##x(server *srv, connection *con, iosocket *sock, chunkqueue *cq, chunk *c)
+
+#define NETWORK_BACKEND_WRITE(x) \
-+ network_status_t network_write_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq)
++ network_status_t network_write_chunkqueue_##x(server *srv, connection *con, iosocket *sock, chunkqueue *cq)
+#define NETWORK_BACKEND_READ(x) \
-+ network_status_t network_read_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq)
-
++ network_status_t network_read_chunkqueue_##x(server *srv, connection *con, iosocket *sock, chunkqueue *cq)
++
+NETWORK_BACKEND_WRITE_CHUNK(writev_mem);
+
+NETWORK_BACKEND_WRITE(write);
+
+NETWORK_BACKEND_WRITE(win32transmitfile);
+NETWORK_BACKEND_WRITE(win32send);
-+
+
+NETWORK_BACKEND_READ(read);
+NETWORK_BACKEND_READ(win32recv);
-int network_write_chunkqueue_solarissendfilev(server *srv, connection *con, int fd, chunkqueue *cq);
#ifdef USE_OPENSSL
-int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq);
-+#define NETWORK_BACKEND_WRITE_SSL(x) \
-+ network_status_t network_write_chunkqueue_##x(server *srv, connection *con, SSL *ssl, chunkqueue *cq)
-+#define NETWORK_BACKEND_READ_SSL(x) \
-+ network_status_t network_read_chunkqueue_##x(server *srv, connection *con, SSL *ssl, chunkqueue *cq)
-+
-+NETWORK_BACKEND_WRITE_SSL(openssl);
-+NETWORK_BACKEND_READ_SSL(openssl);
++NETWORK_BACKEND_WRITE(openssl);
++NETWORK_BACKEND_READ(openssl);
#endif
#endif
--- ../lighttpd-1.4.11/src/network_freebsd_sendfile.c 2005-10-22 12:28:18.000000000 +0300
-+++ lighttpd-1.4.12/src/network_freebsd_sendfile.c 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/network_freebsd_sendfile.c 2006-07-16 00:26:04.000000000 +0300
@@ -26,142 +26,61 @@
#ifndef UIO_MAXIOV
#endif
--- ../lighttpd-1.4.11/src/network_linux_sendfile.c 2006-02-15 20:02:36.000000000 +0200
-+++ lighttpd-1.4.12/src/network_linux_sendfile.c 2006-07-15 22:43:21.000000000 +0300
++++ lighttpd-1.4.12/src/network_linux_sendfile.c 2006-07-18 13:03:40.000000000 +0300
@@ -26,122 +26,54 @@
/* on linux 2.4.29 + debian/ubuntu we have crashes if this is enabled */
#undef HAVE_POSIX_FADVISE
- /* check which chunks have been written */
- cq->bytes_out += r;
+ case MEM_CHUNK:
-+ ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, c);
++ ret = network_write_chunkqueue_writev_mem(srv, con, sock, cq, c);
- for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
- if (r >= (ssize_t)chunks[i].iov_len) {
return -1;
}
#ifdef FD_CLOEXEC
-@@ -151,7 +83,7 @@
+@@ -151,14 +83,14 @@
/* tell the kernel that we want to stream the file */
if (-1 == posix_fadvise(c->file.fd, 0, 0, POSIX_FADV_SEQUENTIAL)) {
if (ENOSYS != errno) {
"posix_fadvise failed:", strerror(errno), c->file.fd);
}
}
-@@ -168,7 +100,7 @@
+ #endif
+ }
+
+- if (-1 == (r = sendfile(fd, c->file.fd, &offset, toSend))) {
++ if (-1 == (r = sendfile(sock->fd, c->file.fd, &offset, toSend))) {
+ switch (errno) {
+ case EAGAIN:
+ case EINTR:
+@@ -166,11 +98,11 @@
+ break;
+ case EPIPE:
case ECONNRESET:
- return -2;
+- return -2;
++ return NETWORK_STATUS_CONNECTION_CLOSE;
default:
- log_error_write(srv, __FILE__, __LINE__, "ssd",
+- "sendfile failed:", strerror(errno), fd);
+- return -1;
+ log_error_write(srv, __FILE__, __LINE__, "ssd",
- "sendfile failed:", strerror(errno), fd);
- return -1;
++ "sendfile failed:", strerror(errno), sock->fd);
++ return NETWORK_STATUS_FATAL_ERROR;
}
-@@ -179,7 +111,7 @@
+ }
+
+@@ -179,39 +111,39 @@
*
* - the file shrinked -> error
* - the remote side closed inbetween -> remote-close */
+
if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
/* file is gone ? */
- return -1;
-@@ -196,22 +128,22 @@
+- return -1;
++ return NETWORK_STATUS_FATAL_ERROR;
+ }
+
+ if (offset > sce->st.st_size) {
+ /* file shrinked, close the connection */
+- return -1;
++ return NETWORK_STATUS_FATAL_ERROR;
+ }
+
+- return -2;
++ return NETWORK_STATUS_CONNECTION_CLOSE;
+ }
+
#ifdef HAVE_POSIX_FADVISE
#if 0
#define K * 1024
+
log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
-
+- return -1;
+
- return -1;
++ return NETWORK_STATUS_FATAL_ERROR;
}
-
+
if (!chunk_finished) {
/* not finished yet */
-
+- break;
+
- break;
++ return NETWORK_STATUS_WAIT_FOR_EVENT;
}
}
#endif
--- ../lighttpd-1.4.11/src/network_openssl.c 2005-11-17 14:53:29.000000000 +0200
-+++ lighttpd-1.4.12/src/network_openssl.c 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/network_openssl.c 2006-07-18 13:03:40.000000000 +0300
@@ -23,17 +23,87 @@
#include "log.h"
#include "stat_cache.h"
+# include <openssl/err.h>
-int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq) {
-+NETWORK_BACKEND_READ_SSL(openssl) {
++NETWORK_BACKEND_READ(openssl) {
+ buffer *b;
+ off_t len;
+
+ b = chunkqueue_get_append_buffer(cq);
+ buffer_prepare_copy(b, 8192);
-+ len = SSL_read(ssl, b->ptr, b->size - 1);
++ len = SSL_read(sock->ssl, b->ptr, b->size - 1);
+
+ log_error_write(srv, __FILE__, __LINE__, "so", "SSL:", len);
+
+ if (len < 0) {
+ int r, ssl_err;
+
-+ switch ((r = SSL_get_error(con->ssl, len))) {
++ switch ((r = SSL_get_error(sock->ssl, len))) {
+ case SSL_ERROR_WANT_READ:
+ return NETWORK_STATUS_WAIT_FOR_EVENT;
+ case SSL_ERROR_SYSCALL:
+}
+
+
-+NETWORK_BACKEND_WRITE_SSL(openssl) {
++NETWORK_BACKEND_WRITE(openssl) {
int ssl_r;
chunk *c;
size_t chunks_written = 0;
* of SSL_write to pass the SAME parameter in case of a _WANT_WRITE
*
* the buffer is allocated once, is NOT realloced and is NOT freed at shutdown
-@@ -43,14 +113,14 @@
+@@ -43,59 +113,61 @@
* In reality we would like to use mmap() but we don't have a guarantee that
* we get the same mmap() address for each call. On openbsd the mmap() address
* even randomized.
* - wget
* if keep-alive is disabled */
-@@ -60,32 +130,34 @@
+ if (con->keep_alive == 0) {
+- SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
++ SSL_set_shutdown(sock->ssl, SSL_RECEIVED_SHUTDOWN);
+ }
for(c = cq->first; c; c = c->next) {
int chunk_finished = 0;
-
- if ((r = SSL_write(ssl, offset, toSend)) <= 0) {
+
-+ if (toSend != 0 && (r = SSL_write(ssl, offset, toSend)) <= 0) {
++ if (toSend != 0 && (r = SSL_write(sock->ssl, offset, toSend)) <= 0) {
unsigned long err;
- switch ((ssl_r = SSL_get_error(ssl, r))) {
-@@ -95,7 +167,7 @@
+- switch ((ssl_r = SSL_get_error(ssl, r))) {
++ switch ((ssl_r = SSL_get_error(sock->ssl, r))) {
+ case SSL_ERROR_WANT_WRITE:
+ break;
+ case SSL_ERROR_SYSCALL:
/* perhaps we have error waiting in our error-queue */
if (0 != (err = ERR_get_error())) {
do {
return -1;
}
-@@ -183,9 +255,9 @@
+@@ -183,13 +255,13 @@
}
s = local_send_buffer;
+
close(ifd);
-
+- if ((r = SSL_write(ssl, s, toSend)) <= 0) {
+
- if ((r = SSL_write(ssl, s, toSend)) <= 0) {
++ if ((r = SSL_write(sock->ssl, s, toSend)) <= 0) {
unsigned long err;
+- switch ((ssl_r = SSL_get_error(ssl, r))) {
++ switch ((ssl_r = SSL_get_error(sock->ssl, r))) {
+ case SSL_ERROR_WANT_WRITE:
+ write_wait = 1;
+ break;
@@ -197,7 +269,7 @@
/* perhaps we have error waiting in our error-queue */
if (0 != (err = ERR_get_error())) {
ssl_r, r,
ERR_error_string(err, NULL));
} while((err = ERR_get_error()));
-@@ -207,58 +279,58 @@
+@@ -207,62 +279,62 @@
case EPIPE:
return -2;
default:
chunks_written++;
}
+- return chunks_written;
++ return NETWORK_STATUS_SUCCESS;
+ }
+ #endif
+
--- ../lighttpd-1.4.11/src/network_solaris_sendfilev.c 2005-10-22 12:28:27.000000000 +0300
-+++ lighttpd-1.4.12/src/network_solaris_sendfilev.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/network_solaris_sendfilev.c 2006-07-16 00:26:04.000000000 +0300
@@ -29,114 +29,34 @@
#endif
#endif
--- ../lighttpd-1.4.11/src/network_write.c 2005-10-22 12:27:56.000000000 +0300
-+++ lighttpd-1.4.12/src/network_write.c 2006-07-15 22:43:21.000000000 +0300
++++ lighttpd-1.4.12/src/network_write.c 2006-07-18 13:03:40.000000000 +0300
@@ -1,11 +1,11 @@
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_SYS_FILIO_H
# include <sys/filio.h>
#endif
-@@ -24,47 +27,84 @@
+@@ -24,47 +27,92 @@
#include <sys/resource.h>
#endif
-int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq) {
++
+/**
+* fill the chunkqueue will all the data that we can get
+*
+ buffer *b;
+ off_t r;
+
++ /**
++ * a EAGAIN is a successful read if we already read something to the chunkqueue
++ */
++ int read_something = 0;
++
+ /* use a chunk-size of 8k */
+ do {
+ toread = 8192;
+
+ buffer_prepare_copy(b, toread);
+
-+ if (-1 == (r = read(fd, b->ptr, toread))) {
++ if (-1 == (r = read(sock->fd, b->ptr, toread))) {
+ switch (errno) {
+ case EAGAIN:
-+ return NETWORK_STATUS_WAIT_FOR_EVENT;
++ /* remove the last chunk from the chunkqueue */
++ chunkqueue_remove_empty_last_chunk(cq);
++ return read_something ? NETWORK_STATUS_SUCCESS : NETWORK_STATUS_WAIT_FOR_EVENT;
+ default:
-+ log_error_write(srv, __FILE__, __LINE__, "sds",
-+ "unexpected end-of-file (perhaps the proxy process died):",
-+ fd, strerror(errno));
++ ERROR("oops, read from fd=%d failed: %s (%d)", sock->fd, strerror(errno), errno );
++
+ return NETWORK_STATUS_FATAL_ERROR;
+ }
+ }
+
+ if (r == 0) {
-+ return NETWORK_STATUS_CONNECTION_CLOSE;
++ chunkqueue_remove_empty_last_chunk(cq);
++ return read_something ? NETWORK_STATUS_SUCCESS : NETWORK_STATUS_CONNECTION_CLOSE;
+ }
+
-+ /* this should be catched by the b > 0 above */
-+ assert(r);
-+ b->used += r + 1;
-+ b->ptr[b->used - 1] = '\0';
-+ } while (r == toread);
++ read_something = 1;
++
++ b->used = r;
++ b->ptr[b->used++] = '\0';
++ } while (r == toread);
+
+ return NETWORK_STATUS_SUCCESS;
+}
- return -1;
- }
-#else
-+
- if ((r = write(fd, offset, toSend)) < 0) {
- log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed: ", strerror(errno), fd);
+- if ((r = write(fd, offset, toSend)) < 0) {
+- log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed: ", strerror(errno), fd);
-
- return -1;
+
++ if ((r = write(sock->fd, offset, toSend)) < 0) {
++ log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed: ", strerror(errno), sock->fd);
++
+ return NETWORK_STATUS_FATAL_ERROR;
}
-#endif
break;
}
case FILE_CHUNK: {
-@@ -76,93 +116,89 @@
+@@ -76,93 +124,89 @@
size_t toSend;
stat_cache_entry *sce = NULL;
int ifd;
}
close(ifd);
- if ((r = write(fd, p + offset, toSend)) <= 0) {
+- if ((r = write(fd, p + offset, toSend)) <= 0) {
++ if ((r = write(sock->fd, p + offset, toSend)) <= 0) {
log_error_write(srv, __FILE__, __LINE__, "ss", "write failed: ", strerror(errno));
munmap(p, sce->st.st_size);
- return -1;
}
close(ifd);
- if (-1 == (r = send(fd, srv->tmp_buf->ptr, toSend, 0))) {
+- if (-1 == (r = send(fd, srv->tmp_buf->ptr, toSend, 0))) {
++ if (-1 == (r = send(sock->fd, srv->tmp_buf->ptr, toSend, 0))) {
log_error_write(srv, __FILE__, __LINE__, "ss", "write: ", strerror(errno));
-
- return -1;
-}
#endif
--- ../lighttpd-1.4.11/src/network_writev.c 2006-02-15 01:02:36.000000000 +0200
-+++ lighttpd-1.4.12/src/network_writev.c 2006-07-15 22:43:21.000000000 +0300
++++ lighttpd-1.4.12/src/network_writev.c 2006-07-18 13:03:40.000000000 +0300
@@ -28,10 +28,10 @@
#ifndef UIO_MAXIOV
+ }
+ }
+
-+ if ((r = writev(fd, chunks, num_chunks)) < 0) {
++ if ((r = writev(sock->fd, chunks, num_chunks)) < 0) {
+ switch (errno) {
+ case EAGAIN:
+ return NETWORK_STATUS_WAIT_FOR_EVENT;
+ return NETWORK_STATUS_CONNECTION_CLOSE;
+ default:
+ log_error_write(srv, __FILE__, __LINE__, "ssd",
-+ "writev failed:", strerror(errno), fd);
++ "writev failed:", strerror(errno), sock->fd);
+
+ return NETWORK_STATUS_FATAL_ERROR;
+ }
-
- cq->bytes_out += r;
+ case MEM_CHUNK:
-+ ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, c);
++ ret = network_write_chunkqueue_writev_mem(srv, con, sock, cq, c);
- /* check which chunks have been written */
-
assert(toSend < 0);
}
+@@ -289,7 +305,7 @@
+ start = c->file.mmap.start;
+ #endif
+
+- if ((r = write(fd, start + (abs_offset - c->file.mmap.offset), toSend)) < 0) {
++ if ((r = write(sock->fd, start + (abs_offset - c->file.mmap.offset), toSend)) < 0) {
+ switch (errno) {
+ case EAGAIN:
+ case EINTR:
@@ -297,18 +313,18 @@
break;
case EPIPE:
+ return NETWORK_STATUS_CONNECTION_CLOSE;
default:
- log_error_write(srv, __FILE__, __LINE__, "ssd",
-+ log_error_write(srv, __FILE__, __LINE__, "ssd",
- "write failed:", strerror(errno), fd);
+- "write failed:", strerror(errno), fd);
-
- return -1;
++ log_error_write(srv, __FILE__, __LINE__, "ssd",
++ "write failed:", strerror(errno), sock->fd);
+
+ return NETWORK_STATUS_FATAL_ERROR;
}
#endif
--- ../lighttpd-1.4.11/src/plugin.c 2006-02-08 14:00:54.000000000 +0200
-+++ lighttpd-1.4.12/src/plugin.c 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/plugin.c 2006-07-16 00:26:04.000000000 +0300
@@ -13,27 +13,27 @@
#include <valgrind/valgrind.h>
#endif
srv->plugins.ptr = NULL;
srv->plugins.used = 0;
--- ../lighttpd-1.4.11/src/plugin.h 2005-08-15 12:28:56.000000000 +0300
-+++ lighttpd-1.4.12/src/plugin.h 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/plugin.h 2006-07-16 00:26:04.000000000 +0300
@@ -12,6 +12,12 @@
#define INIT_FUNC(x) \
#endif
--- ../lighttpd-1.4.11/src/proc_open.c 2005-08-11 01:26:39.000000000 +0300
-+++ lighttpd-1.4.12/src/proc_open.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/proc_open.c 2006-07-16 00:26:04.000000000 +0300
@@ -13,13 +13,13 @@
#endif
for (;;) {
buffer_prepare_append(b, 512);
--- ../lighttpd-1.4.11/src/proc_open.h 2005-08-11 01:26:39.000000000 +0300
-+++ lighttpd-1.4.12/src/proc_open.h 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/proc_open.h 2006-07-16 00:26:04.000000000 +0300
@@ -1,7 +1,7 @@
#include "buffer.h"
typedef HANDLE descriptor_t;
typedef HANDLE proc_pid_t;
--- ../lighttpd-1.4.11/src/request.c 2006-03-05 11:58:09.000000000 +0200
-+++ lighttpd-1.4.12/src/request.c 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/request.c 2006-07-18 13:03:40.000000000 +0300
@@ -10,15 +10,17 @@
#include "keyvalue.h"
#include "log.h"
- "fd:", con->fd,
- "request-len:", con->request.request->used,
+ log_error_write(srv, __FILE__, __LINE__, "sdsdSb",
-+ "fd:", con->fd,
++ "fd:", con->sock->fd,
+ "request-len:", con->request.request->used,
"\n", con->request.request);
}
return 0;
}
--- ../lighttpd-1.4.11/src/response.c 2006-03-04 16:41:39.000000000 +0200
-+++ lighttpd-1.4.12/src/response.c 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/response.c 2006-07-16 00:26:04.000000000 +0300
@@ -7,7 +7,6 @@
#include <stdlib.h>
#include <string.h>
return HANDLER_COMEBACK;
}
--- ../lighttpd-1.4.11/src/server.c 2006-03-04 19:12:17.000000000 +0200
-+++ lighttpd-1.4.12/src/server.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/server.c 2006-07-18 13:03:40.000000000 +0300
@@ -1,11 +1,9 @@
#include <sys/types.h>
-#include <sys/time.h>
#endif
#ifdef HAVE_VALGRIND_VALGRIND_H
-@@ -60,8 +63,16 @@
+@@ -60,8 +63,17 @@
/* #define USE_ALARM */
#endif
+
+#include "sys-files.h"
+#include "sys-process.h"
++#include "sys-socket.h"
+
static volatile sig_atomic_t srv_shutdown = 0;
static volatile sig_atomic_t graceful_shutdown = 0;
static volatile sig_atomic_t handle_sig_alarm = 1;
static volatile sig_atomic_t handle_sig_hup = 0;
-@@ -72,9 +83,9 @@
+@@ -72,9 +84,9 @@
switch (sig) {
case SIGTERM: srv_shutdown = 1; break;
break;
case SIGALRM: handle_sig_alarm = 1; break;
-@@ -86,9 +97,9 @@
+@@ -86,9 +98,9 @@
static void signal_handler(int sig) {
switch (sig) {
case SIGTERM: srv_shutdown = 1; break;
break;
case SIGALRM: handle_sig_alarm = 1; break;
-@@ -110,25 +121,26 @@
+@@ -110,35 +122,35 @@
signal(SIGTSTP, SIG_IGN);
#endif
if (0 != fork()) exit(0);
CLEAN(response_header);
CLEAN(parse_full_path);
CLEAN(ts_debug_str);
-@@ -138,7 +150,7 @@
+ CLEAN(ts_date_str);
+- CLEAN(errorlog_buf);
+ CLEAN(response_range);
CLEAN(tmp_buf);
srv->empty_string = buffer_init_string("");
CLEAN(cond_check_buf);
CLEAN(srvconf.errorlog_file);
CLEAN(srvconf.groupname);
CLEAN(srvconf.username);
-@@ -146,58 +158,58 @@
+@@ -146,68 +158,63 @@
CLEAN(srvconf.bindhost);
CLEAN(srvconf.event_handler);
CLEAN(srvconf.pid_file);
srv->srvconf.network_backend = buffer_init();
srv->srvconf.upload_tempdirs = array_init();
-
-+
- /* use syslog */
- srv->errorlog_fd = -1;
- srv->errorlog_mode = ERRORLOG_STDERR;
+- /* use syslog */
+- srv->errorlog_fd = -1;
+- srv->errorlog_mode = ERRORLOG_STDERR;
srv->split_vals = array_init();
-
CLEAN(response_header);
CLEAN(parse_full_path);
CLEAN(ts_debug_str);
-@@ -207,7 +219,7 @@
+ CLEAN(ts_date_str);
+- CLEAN(errorlog_buf);
+ CLEAN(response_range);
CLEAN(tmp_buf);
CLEAN(empty_string);
CLEAN(cond_check_buf);
CLEAN(srvconf.errorlog_file);
CLEAN(srvconf.groupname);
CLEAN(srvconf.username);
-@@ -217,7 +229,7 @@
+@@ -217,7 +224,7 @@
CLEAN(srvconf.pid_file);
CLEAN(srvconf.modules_dir);
CLEAN(srvconf.network_backend);
CLEAN(tmp_chunk_len);
#undef CLEAN
-@@ -225,15 +237,15 @@
+@@ -225,15 +232,15 @@
fdevent_unregister(srv->ev, srv->fd);
#endif
fdevent_free(srv->ev);
buffer_free(s->document_root);
buffer_free(s->server_name);
buffer_free(s->server_tag);
-@@ -242,32 +254,32 @@
+@@ -242,32 +249,32 @@
buffer_free(s->error_handler);
buffer_free(s->errorfile_prefix);
array_free(s->mimetypes);
free(srv);
}
-@@ -281,14 +293,12 @@
+@@ -281,14 +288,12 @@
" - a light and fast webserver\n" \
"Build-Date: " __DATE__ " " __TIME__ "\n";
;
#ifdef USE_SELECT
"\t+ select (generic)\n"
#else
-@@ -355,11 +365,6 @@
+@@ -355,11 +360,6 @@
#else
"\t- crypt support\n"
#endif
#ifdef USE_OPENSSL
"\t+ SSL Support\n"
#else
-@@ -371,9 +376,9 @@
+@@ -371,9 +371,9 @@
"\t- PCRE support\n"
#endif
#ifdef HAVE_MYSQL
#endif
#if defined(HAVE_LDAP_H) && defined(HAVE_LBER_H) && defined(HAVE_LIBLDAP) && defined(HAVE_LIBLBER)
"\t+ LDAP support\n"
-@@ -410,8 +415,11 @@
+@@ -410,8 +410,11 @@
#else
"\t- GDBM support\n"
#endif
}
static void show_help (void) {
-@@ -433,12 +441,12 @@
+@@ -433,277 +436,644 @@
" -h show this help\n" \
"\n"
;
}
-int main (int argc, char **argv) {
+- server *srv = NULL;
+- int print_config = 0;
+- int test_config = 0;
+- int i_am_root;
+- int o;
+- int num_childs = 0;
+- int pid_fd = -1, fd;
+- size_t i;
+-#ifdef HAVE_SIGACTION
+- struct sigaction act;
+-#endif
+-#ifdef HAVE_GETRLIMIT
+- struct rlimit rlim;
+-#endif
+-
+-#ifdef USE_ALARM
+- struct itimerval interval;
+-
+- interval.it_interval.tv_sec = 1;
+- interval.it_interval.tv_usec = 0;
+- interval.it_value.tv_sec = 1;
+- interval.it_value.tv_usec = 0;
+-#endif
+-
+-
+- /* for nice %b handling in strfime() */
+- setlocale(LC_TIME, "C");
+-
+- if (NULL == (srv = server_init())) {
+- fprintf(stderr, "did this really happen?\n");
+- return -1;
+- }
+-
+- /* init structs done */
+-
+- srv->srvconf.port = 0;
+-#ifdef HAVE_GETUID
+- i_am_root = (getuid() == 0);
+-#else
+- i_am_root = 0;
+-#endif
+- srv->srvconf.dont_daemonize = 0;
+-
+- while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) {
+- switch(o) {
+- case 'f':
+- if (config_read(srv, optarg)) {
+- server_free(srv);
+- return -1;
+- }
+- break;
+- case 'm':
+- buffer_copy_string(srv->srvconf.modules_dir, optarg);
+- break;
+- case 'p': print_config = 1; break;
+- case 't': test_config = 1; break;
+- case 'D': srv->srvconf.dont_daemonize = 1; break;
+- case 'v': show_version(); return 0;
+- case 'V': show_features(); return 0;
+- case 'h': show_help(); return 0;
+- default:
+- show_help();
+- server_free(srv);
+- return -1;
+- }
+- }
+-
+- if (!srv->config_storage) {
+- log_error_write(srv, __FILE__, __LINE__, "s",
+- "No configuration available. Try using -f option.");
+-
+- server_free(srv);
+- return -1;
+- }
+-
+- if (print_config) {
+- data_unset *dc = srv->config_context->data[0];
+- if (dc) {
+- dc->print(dc, 0);
+- fprintf(stderr, "\n");
+- } else {
+- /* shouldn't happend */
+- fprintf(stderr, "global config not found\n");
+- }
+- }
++int lighty_mainloop(server *srv) {
++ fdevent_revents *revents = fdevent_revents_init();
+
+- if (test_config) {
+- printf("Syntax OK\n");
+- }
++ /* main-loop */
++ while (!srv_shutdown) {
++ int n;
++ size_t ndx;
++ time_t min_ts;
+
+- if (test_config || print_config) {
+- server_free(srv);
+- return 0;
+- }
+-
+- /* close stdin and stdout, as they are not needed */
+- /* move stdin to /dev/null */
+- if (-1 != (fd = open("/dev/null", O_RDONLY))) {
+- close(STDIN_FILENO);
+- dup2(fd, STDIN_FILENO);
+- close(fd);
+- }
+-
+- /* move stdout to /dev/null */
+- if (-1 != (fd = open("/dev/null", O_WRONLY))) {
+- close(STDOUT_FILENO);
+- dup2(fd, STDOUT_FILENO);
+- close(fd);
+- }
+-
+- if (0 != config_set_defaults(srv)) {
+- log_error_write(srv, __FILE__, __LINE__, "s",
+- "setting default values failed");
+- server_free(srv);
+- return -1;
+- }
+-
+- /* UID handling */
+-#ifdef HAVE_GETUID
+- if (!i_am_root && (geteuid() == 0 || getegid() == 0)) {
+- /* we are setuid-root */
+-
+- log_error_write(srv, __FILE__, __LINE__, "s",
+- "Are you nuts ? Don't apply a SUID bit to this binary");
+-
+- server_free(srv);
+- return -1;
+- }
+-#endif
+-
+- /* check document-root */
+- if (srv->config_storage[0]->document_root->used <= 1) {
+- log_error_write(srv, __FILE__, __LINE__, "s",
+- "document-root is not set\n");
+-
+- server_free(srv);
+-
+- return -1;
+- }
+-
+- if (plugins_load(srv)) {
+- log_error_write(srv, __FILE__, __LINE__, "s",
+- "loading plugins finally failed");
+-
+- plugins_free(srv);
+- server_free(srv);
+-
+- return -1;
+- }
+-
+- /* open pid file BEFORE chroot */
+- if (srv->srvconf.pid_file->used) {
+- if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
+- struct stat st;
+- if (errno != EEXIST) {
+- log_error_write(srv, __FILE__, __LINE__, "sbs",
+- "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
+- return -1;
+- }
+-
+- if (0 != stat(srv->srvconf.pid_file->ptr, &st)) {
+- log_error_write(srv, __FILE__, __LINE__, "sbs",
+- "stating existing pid-file failed:", srv->srvconf.pid_file, strerror(errno));
+- }
+-
+- if (!S_ISREG(st.st_mode)) {
+- log_error_write(srv, __FILE__, __LINE__, "sb",
+- "pid-file exists and isn't regular file:", srv->srvconf.pid_file);
+- return -1;
+- }
+-
+- if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
+- log_error_write(srv, __FILE__, __LINE__, "sbs",
+- "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
+- return -1;
++ if (handle_sig_hup) {
++ handler_t r;
++
++ /* reset notification */
++ handle_sig_hup = 0;
++
++#if 0
++ pid_t pid;
++
++ /* send the old process into a graceful-shutdown and start a
++ * new process right away
++ *
++ * BUGS:
++ * - if webserver is running on port < 1024 (e.g. 80, 433)
++ * we don't have the permissions to bind to that port anymore
++ *
++ *
++ * */
++ if (0 == (pid = fork())) {
++ execve(argv[0], argv, envp);
++
++ exit(-1);
++ } else if (pid == -1) {
++
++ } else {
++ /* parent */
++
++ graceful_shutdown = 1; /* shutdown without killing running connections */
++ graceful_restart = 1; /* don't delete pid file */
+ }
+- }
+- }
++#else
++ /* cycle logfiles */
+
+- if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
+- /* select limits itself
+- *
+- * as it is a hard limit and will lead to a segfault we add some safety
+- * */
+- srv->max_fds = FD_SETSIZE - 200;
+- } else {
+- srv->max_fds = 4096;
+- }
++ switch(r = plugins_call_handle_sighup(srv)) {
++ case HANDLER_GO_ON:
++ break;
++ default:
++ log_error_write(srv, __FILE__, __LINE__, "sd", "sighup-handler return with an error", r);
++ break;
++ }
+
+- if (i_am_root) {
+- struct group *grp = NULL;
+- struct passwd *pwd = NULL;
+- int use_rlimit = 1;
++ if (-1 == log_error_cycle()) {
++ log_error_write(srv, __FILE__, __LINE__, "s", "cycling errorlog failed, dying");
+
+-#ifdef HAVE_VALGRIND_VALGRIND_H
+- if (RUNNING_ON_VALGRIND) use_rlimit = 0;
+-#endif
+-
+-#ifdef HAVE_GETRLIMIT
+- if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
+- log_error_write(srv, __FILE__, __LINE__,
+- "ss", "couldn't get 'max filedescriptors'",
+- strerror(errno));
+- return -1;
+- }
+-
+- if (use_rlimit && srv->srvconf.max_fds) {
+- /* set rlimits */
+-
+- rlim.rlim_cur = srv->srvconf.max_fds;
+- rlim.rlim_max = srv->srvconf.max_fds;
+-
+- if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
+- log_error_write(srv, __FILE__, __LINE__,
+- "ss", "couldn't set 'max filedescriptors'",
+- strerror(errno));
+ return -1;
+ }
++#endif
+ }
+
+- /* #372: solaris need some fds extra for devpoll */
+- if (rlim.rlim_cur > 10) rlim.rlim_cur -= 10;
++ if (handle_sig_alarm) {
++ /* a new second */
+
+- if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
+- srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
+- } else {
+- srv->max_fds = rlim.rlim_cur;
+- }
++#ifdef USE_ALARM
++ /* reset notification */
++ handle_sig_alarm = 0;
++#endif
+
+- /* set core file rlimit, if enable_cores is set */
+- if (use_rlimit && srv->srvconf.enable_cores && getrlimit(RLIMIT_CORE, &rlim) == 0) {
+- rlim.rlim_cur = rlim.rlim_max;
++ /* get current time */
++ min_ts = time(NULL);
++
++ if (min_ts != srv->cur_ts) {
++ int cs = 0;
++ connections *conns = srv->conns;
++ handler_t r;
++
++ switch(r = plugins_call_handle_trigger(srv)) {
++ case HANDLER_GO_ON:
++ break;
++ case HANDLER_ERROR:
++ log_error_write(srv, __FILE__, __LINE__, "s", "one of the triggers failed");
++ break;
++ default:
++ log_error_write(srv, __FILE__, __LINE__, "d", r);
++ break;
++ }
++
++ /* trigger waitpid */
++ srv->cur_ts = min_ts;
++
++ /* cleanup stat-cache */
++ stat_cache_trigger_cleanup(srv);
++ /**
++ * check all connections for timeouts
++ *
++ */
++ for (ndx = 0; ndx < conns->used; ndx++) {
++ int changed = 0;
++ connection *con;
++ int t_diff;
++
++ con = conns->ptr[ndx];
++
++ if (con->state == CON_STATE_READ ||
++ con->state == CON_STATE_READ_POST) {
++ if (con->request_count == 1) {
++ if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
++ /* time - out */
++#if 0
++ log_error_write(srv, __FILE__, __LINE__, "sd",
++ "connection closed - read-timeout:", con->fd);
++#endif
++ connection_set_state(srv, con, CON_STATE_ERROR);
++ changed = 1;
++ }
++ } else {
++ if (srv->cur_ts - con->read_idle_ts > con->conf.max_keep_alive_idle) {
++ /* time - out */
++#if 0
++ log_error_write(srv, __FILE__, __LINE__, "sd",
++ "connection closed - read-timeout:", con->fd);
++#endif
++ connection_set_state(srv, con, CON_STATE_ERROR);
++ changed = 1;
++ }
++ }
++ }
++
++ if ((con->state == CON_STATE_WRITE) &&
++ (con->write_request_ts != 0)) {
++#if 0
++ if (srv->cur_ts - con->write_request_ts > 60) {
++ log_error_write(srv, __FILE__, __LINE__, "sdd",
++ "connection closed - pre-write-request-timeout:", con->fd, srv->cur_ts - con->write_request_ts);
++ }
++#endif
++
++ if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) {
++ /* time - out */
++#if 1
++ log_error_write(srv, __FILE__, __LINE__, "sbsosds",
++ "NOTE: a request for",
++ con->request.uri,
++ "timed out after writing",
++ con->bytes_written,
++ "bytes. We waited",
++ (int)con->conf.max_write_idle,
++ "seconds. If this a problem increase server.max-write-idle");
++#endif
++ connection_set_state(srv, con, CON_STATE_ERROR);
++ changed = 1;
++ }
++ }
++ /* we don't like div by zero */
++ if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1;
++
++ if (con->traffic_limit_reached &&
++ (con->conf.kbytes_per_second == 0 ||
++ ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) {
++ /* enable connection again */
++ con->traffic_limit_reached = 0;
++
++ changed = 1;
++ }
++
++ if (changed) {
++ connection_state_machine(srv, con);
++ }
++ con->bytes_written_cur_second = 0;
++ *(con->conf.global_bytes_per_second_cnt_ptr) = 0;
++
++#if 0
++ if (cs == 0) {
++ fprintf(stderr, "connection-state: ");
++ cs = 1;
++ }
++
++ fprintf(stderr, "c[%d,%d]: %s ",
++ con->fd,
++ con->fcgi.fd,
++ connection_get_state(con->state));
++#endif
++ }
++
++ if (cs == 1) fprintf(stderr, "\n");
++ }
++ }
++
++ if (srv->sockets_disabled) {
++ /* our server sockets are disabled, why ? */
++
++ if ((srv->cur_fds + srv->want_fds < srv->max_fds * 0.8) && /* we have enough unused fds */
++ (srv->conns->used < srv->max_conns * 0.9) &&
++ (0 == graceful_shutdown)) {
++ size_t i;
++
++ for (i = 0; i < srv->srv_sockets.used; i++) {
++ server_socket *srv_socket = srv->srv_sockets.ptr[i];
++ fdevent_event_add(srv->ev, srv_socket->sock, FDEVENT_IN);
++ }
++
++ log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again");
++
++ srv->sockets_disabled = 0;
++ }
++ } else {
++ if ((srv->cur_fds + srv->want_fds > srv->max_fds * 0.9) || /* out of fds */
++ (srv->conns->used > srv->max_conns) || /* out of connections */
++ (graceful_shutdown)) { /* graceful_shutdown */
++ size_t i;
++
++ /* disable server-fds */
++
++ for (i = 0; i < srv->srv_sockets.used; i++) {
++ server_socket *srv_socket = srv->srv_sockets.ptr[i];
++ fdevent_event_del(srv->ev, srv_socket->sock);
++
++ if (graceful_shutdown) {
++ /* we don't want this socket anymore,
++ *
++ * closing it right away will make it possible for
++ * the next lighttpd to take over (graceful restart)
++ * */
++
++ fdevent_unregister(srv->ev, srv_socket->sock);
++ closesocket(srv_socket->sock->fd);
++ srv_socket->sock->fd = -1;
++
++ /* network_close() will cleanup after us */
++ }
++ }
++
++ if (graceful_shutdown) {
++ log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
++ } else if (srv->conns->used > srv->max_conns) {
++ log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached");
++ } else {
++ log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
++ }
++
++ srv->sockets_disabled = 1;
++ }
++ }
++
++ if (graceful_shutdown && srv->conns->used == 0) {
++ /* we are in graceful shutdown phase and all connections are closed
++ * we are ready to terminate without harming anyone */
++ srv_shutdown = 1;
++ }
++
++ /* we still have some fds to share */
++ if (srv->want_fds) {
++ /* check the fdwaitqueue for waiting fds */
++ int free_fds = srv->max_fds - srv->cur_fds - 16;
++ connection *con;
++
++ for (; free_fds > 0 && NULL != (con = fdwaitqueue_unshift(srv, srv->fdwaitqueue)); free_fds--) {
++ connection_state_machine(srv, con);
++
++ srv->want_fds--;
++ }
++ }
++
++ if ((n = fdevent_poll(srv->ev, 1000)) > 0) {
++ /* n is the number of events */
++ size_t i;
++ fdevent_get_revents(srv->ev, n, revents);
++
++ /* handle client connections first
++ *
++ * this is a bit of a hack, but we have to make sure than we handle
++ * close-events before the connection is reused for a keep-alive
++ * request
++ *
++ * this is mostly an issue for mod_proxy_core, but you never know
++ *
++ */
++
++ for (i = 0; i < revents->used; i++) {
++ fdevent_revent *revent = revents->ptr[i];
++ handler_t r;
++
++ /* skip server-fds */
++ if (revent->handler == network_server_handle_fdevent) continue;
++
++ switch (r = (*(revent->handler))(srv, revent->context, revent->revents)) {
++ case HANDLER_FINISHED:
++ case HANDLER_GO_ON:
++ case HANDLER_WAIT_FOR_EVENT:
++ case HANDLER_WAIT_FOR_FD:
++ break;
++ case HANDLER_ERROR:
++ /* should never happen */
++ SEGFAULT();
++ break;
++ default:
++ log_error_write(srv, __FILE__, __LINE__, "d", r);
++ break;
++ }
++ }
++
++ for (i = 0; i < revents->used; i++) {
++ fdevent_revent *revent = revents->ptr[i];
++ handler_t r;
++
++ /* server fds only */
++ if (revent->handler != network_server_handle_fdevent) continue;
++
++ switch (r = (*(revent->handler))(srv, revent->context, revent->revents)) {
++ case HANDLER_FINISHED:
++ case HANDLER_GO_ON:
++ case HANDLER_WAIT_FOR_EVENT:
++ case HANDLER_WAIT_FOR_FD:
++ break;
++ case HANDLER_ERROR:
++ /* should never happen */
++ SEGFAULT();
++ break;
++ default:
++ log_error_write(srv, __FILE__, __LINE__, "d", r);
++ break;
++ }
++ }
++
++ } else if (n < 0 && errno != EINTR) {
++ log_error_write(srv, __FILE__, __LINE__, "ss",
++ "fdevent_poll failed:",
++ strerror(errno));
++ }
++
++ for (ndx = 0; ndx < srv->joblist->used; ndx++) {
++ connection *con = srv->joblist->ptr[ndx];
++ handler_t r;
++
++ connection_state_machine(srv, con);
++
++ switch(r = plugins_call_handle_joblist(srv, con)) {
++ case HANDLER_FINISHED:
++ case HANDLER_GO_ON:
++ break;
++ default:
++ log_error_write(srv, __FILE__, __LINE__, "d", r);
++ break;
++ }
++
++ con->in_joblist = 0;
++ }
++
++ srv->joblist->used = 0;
++ }
++
++ fdevent_revents_free(revents);
++
++ return 0;
++}
++
++
+int main (int argc, char **argv, char **envp) {
- server *srv = NULL;
- int print_config = 0;
- int test_config = 0;
-@@ -447,33 +455,37 @@
- int num_childs = 0;
- int pid_fd = -1, fd;
- size_t i;
++ server *srv = NULL;
++ int print_config = 0;
++ int test_config = 0;
++ int i_am_root;
++ int o;
++ int num_childs = 0;
++ int pid_fd = -1, fd;
++ size_t i;
+#ifdef _WIN32
+ char *optarg = NULL;
+#endif
+
- #ifdef HAVE_SIGACTION
- struct sigaction act;
- #endif
- #ifdef HAVE_GETRLIMIT
- struct rlimit rlim;
- #endif
--
++#ifdef HAVE_SIGACTION
++ struct sigaction act;
++#endif
++#ifdef HAVE_GETRLIMIT
++ struct rlimit rlim;
++#endif
+
- #ifdef USE_ALARM
- struct itimerval interval;
--
++#ifdef USE_ALARM
++ struct itimerval interval;
+
- interval.it_interval.tv_sec = 1;
- interval.it_interval.tv_usec = 0;
- interval.it_value.tv_sec = 1;
- interval.it_value.tv_usec = 0;
- #endif
--
--
++ interval.it_interval.tv_sec = 1;
++ interval.it_interval.tv_usec = 0;
++ interval.it_value.tv_sec = 1;
++ interval.it_value.tv_usec = 0;
++#endif
+
++ log_init();
+
- /* for nice %b handling in strfime() */
- setlocale(LC_TIME, "C");
--
++ /* for nice %b handling in strfime() */
++ setlocale(LC_TIME, "C");
+
- if (NULL == (srv = server_init())) {
- fprintf(stderr, "did this really happen?\n");
- return -1;
- }
--
++ if (NULL == (srv = server_init())) {
++ fprintf(stderr, "did this really happen?\n");
++ return -1;
++ }
+
- /* init structs done */
--
++ /* init structs done */
+
- srv->srvconf.port = 0;
- #ifdef HAVE_GETUID
- i_am_root = (getuid() == 0);
-@@ -481,14 +493,19 @@
- i_am_root = 0;
- #endif
- srv->srvconf.dont_daemonize = 0;
--
++ srv->srvconf.port = 0;
++#ifdef HAVE_GETUID
++ i_am_root = (getuid() == 0);
++#else
++ i_am_root = 0;
++#endif
++ srv->srvconf.dont_daemonize = 0;
+
- while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) {
- switch(o) {
-- case 'f':
-- if (config_read(srv, optarg)) {
++ while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) {
++ switch(o) {
+ case 'f':
+#ifdef _WIN32
+ /* evil HACK for windows, optarg is not set */
+ optarg = argv[optind-1];
+#endif
+ if (config_read(srv, optarg)) {
- server_free(srv);
- return -1;
- }
++ server_free(srv);
++ return -1;
++ }
+
- break;
- case 'm':
- buffer_copy_string(srv->srvconf.modules_dir, optarg);
-@@ -497,23 +514,23 @@
- case 't': test_config = 1; break;
- case 'D': srv->srvconf.dont_daemonize = 1; break;
- case 'v': show_version(); return 0;
-- case 'V': show_features(); return 0;
++ break;
++ case 'm':
++ buffer_copy_string(srv->srvconf.modules_dir, optarg);
++ break;
++ case 'p': print_config = 1; break;
++ case 't': test_config = 1; break;
++ case 'D': srv->srvconf.dont_daemonize = 1; break;
++ case 'v': show_version(); return 0;
+ case 'V': show_features(); return 0;
- case 'h': show_help(); return 0;
-- default:
++ case 'h': show_help(); return 0;
+ default:
- show_help();
- server_free(srv);
- return -1;
- }
- }
--
++ show_help();
++ server_free(srv);
++ return -1;
++ }
++ }
+
- if (!srv->config_storage) {
- log_error_write(srv, __FILE__, __LINE__, "s",
- "No configuration available. Try using -f option.");
--
++ if (!srv->config_storage) {
++ log_error_write(srv, __FILE__, __LINE__, "s",
++ "No configuration available. Try using -f option.");
+
- server_free(srv);
- return -1;
- }
--
++ server_free(srv);
++ return -1;
++ }
+
- if (print_config) {
- data_unset *dc = srv->config_context->data[0];
- if (dc) {
-@@ -533,7 +550,7 @@
- server_free(srv);
- return 0;
- }
--
++ if (print_config) {
++ data_unset *dc = srv->config_context->data[0];
++ if (dc) {
++ dc->print(dc, 0);
++ fprintf(stderr, "\n");
++ } else {
++ /* shouldn't happend */
++ fprintf(stderr, "global config not found\n");
++ }
++ }
+
- /* close stdin and stdout, as they are not needed */
- /* move stdin to /dev/null */
- if (-1 != (fd = open("/dev/null", O_RDONLY))) {
-@@ -541,54 +558,55 @@
- dup2(fd, STDIN_FILENO);
- close(fd);
- }
--
++ if (test_config) {
++ printf("Syntax OK\n");
++ }
+
- /* move stdout to /dev/null */
- if (-1 != (fd = open("/dev/null", O_WRONLY))) {
- close(STDOUT_FILENO);
- dup2(fd, STDOUT_FILENO);
- close(fd);
- }
--
++ if (test_config || print_config) {
++ server_free(srv);
++ return 0;
++ }
+
- if (0 != config_set_defaults(srv)) {
-- log_error_write(srv, __FILE__, __LINE__, "s",
++ /* close stdin and stdout, as they are not needed */
++ /* move stdin to /dev/null */
++ if (-1 != (fd = open("/dev/null", O_RDONLY))) {
++ close(STDIN_FILENO);
++ dup2(fd, STDIN_FILENO);
++ close(fd);
++ }
++
++ /* move stdout to /dev/null */
++ if (-1 != (fd = open("/dev/null", O_WRONLY))) {
++ close(STDOUT_FILENO);
++ dup2(fd, STDOUT_FILENO);
++ close(fd);
++ }
++
++ if (0 != config_set_defaults(srv)) {
+ log_error_write(srv, __FILE__, __LINE__, "s",
- "setting default values failed");
- server_free(srv);
- return -1;
- }
--
++ "setting default values failed");
++ server_free(srv);
++ return -1;
++ }
+
- /* UID handling */
- #ifdef HAVE_GETUID
- if (!i_am_root && (geteuid() == 0 || getegid() == 0)) {
- /* we are setuid-root */
--
-- log_error_write(srv, __FILE__, __LINE__, "s",
++ /* UID handling */
++#ifdef HAVE_GETUID
++ if (!i_am_root && (geteuid() == 0 || getegid() == 0)) {
++ /* we are setuid-root */
+
+ log_error_write(srv, __FILE__, __LINE__, "s",
- "Are you nuts ? Don't apply a SUID bit to this binary");
--
++ "Are you nuts ? Don't apply a SUID bit to this binary");
+
- server_free(srv);
- return -1;
- }
- #endif
--
++ server_free(srv);
++ return -1;
++ }
++#endif
+
- /* check document-root */
- if (srv->config_storage[0]->document_root->used <= 1) {
-- log_error_write(srv, __FILE__, __LINE__, "s",
++ /* check document-root */
++ if (srv->config_storage[0]->document_root->used <= 1) {
+ log_error_write(srv, __FILE__, __LINE__, "s",
- "document-root is not set\n");
--
++ "document-root is not set\n");
+
- server_free(srv);
--
++ server_free(srv);
+
- return -1;
- }
--
++ return -1;
++ }
+
- if (plugins_load(srv)) {
- log_error_write(srv, __FILE__, __LINE__, "s",
- "loading plugins finally failed");
--
++ if (plugins_load(srv)) {
++ log_error_write(srv, __FILE__, __LINE__, "s",
++ "loading plugins finally failed");
+
- plugins_free(srv);
- server_free(srv);
--
++ plugins_free(srv);
++ server_free(srv);
+
- return -1;
- }
--
++ return -1;
++ }
+
+#ifndef _WIN32
- /* open pid file BEFORE chroot */
- if (srv->srvconf.pid_file->used) {
- if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
-@@ -598,18 +616,18 @@
- "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
- return -1;
- }
--
++ /* open pid file BEFORE chroot */
++ if (srv->srvconf.pid_file->used) {
++ if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
++ struct stat st;
++ if (errno != EEXIST) {
++ log_error_write(srv, __FILE__, __LINE__, "sbs",
++ "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
++ return -1;
++ }
+
- if (0 != stat(srv->srvconf.pid_file->ptr, &st)) {
- log_error_write(srv, __FILE__, __LINE__, "sbs",
- "stating existing pid-file failed:", srv->srvconf.pid_file, strerror(errno));
- }
--
++ if (0 != stat(srv->srvconf.pid_file->ptr, &st)) {
++ log_error_write(srv, __FILE__, __LINE__, "sbs",
++ "stating existing pid-file failed:", srv->srvconf.pid_file, strerror(errno));
++ }
+
- if (!S_ISREG(st.st_mode)) {
- log_error_write(srv, __FILE__, __LINE__, "sb",
- "pid-file exists and isn't regular file:", srv->srvconf.pid_file);
- return -1;
- }
--
++ if (!S_ISREG(st.st_mode)) {
++ log_error_write(srv, __FILE__, __LINE__, "sb",
++ "pid-file exists and isn't regular file:", srv->srvconf.pid_file);
++ return -1;
++ }
+
- if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
- log_error_write(srv, __FILE__, __LINE__, "sbs",
- "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
-@@ -617,13 +635,14 @@
- }
- }
- }
--
++ if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
++ log_error_write(srv, __FILE__, __LINE__, "sbs",
++ "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
++ return -1;
++ }
++ }
++ }
+#endif
- if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
- /* select limits itself
- *
- * as it is a hard limit and will lead to a segfault we add some safety
- * */
-- srv->max_fds = FD_SETSIZE - 200;
++ if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
++ /* select limits itself
++ *
++ * as it is a hard limit and will lead to a segfault we add some safety
++ * */
+ fprintf(stderr, "%s.%d: max parallel connections: %d\r\n", __FILE__, __LINE__, FD_SETSIZE);
+ srv->max_fds = FD_SETSIZE - 4;
- } else {
- srv->max_fds = 4096;
- }
-@@ -636,7 +655,7 @@
- #ifdef HAVE_VALGRIND_VALGRIND_H
- if (RUNNING_ON_VALGRIND) use_rlimit = 0;
- #endif
--
++ } else {
++ srv->max_fds = 4096;
++ }
+
- #ifdef HAVE_GETRLIMIT
- if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
- log_error_write(srv, __FILE__, __LINE__,
-@@ -644,13 +663,13 @@
- strerror(errno));
- return -1;
- }
--
++ if (i_am_root) {
++ struct group *grp = NULL;
++ struct passwd *pwd = NULL;
++ int use_rlimit = 1;
+
- if (use_rlimit && srv->srvconf.max_fds) {
- /* set rlimits */
--
++#ifdef HAVE_VALGRIND_VALGRIND_H
++ if (RUNNING_ON_VALGRIND) use_rlimit = 0;
++#endif
+
- rlim.rlim_cur = srv->srvconf.max_fds;
- rlim.rlim_max = srv->srvconf.max_fds;
--
++#ifdef HAVE_GETRLIMIT
++ if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
++ log_error_write(srv, __FILE__, __LINE__,
++ "ss", "couldn't get 'max filedescriptors'",
++ strerror(errno));
++ return -1;
++ }
++
++ if (use_rlimit && srv->srvconf.max_fds) {
++ /* set rlimits */
++
++ rlim.rlim_cur = srv->srvconf.max_fds;
++ rlim.rlim_max = srv->srvconf.max_fds;
++
++ if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
++ log_error_write(srv, __FILE__, __LINE__,
++ "ss", "couldn't set 'max filedescriptors'",
++ strerror(errno));
++ return -1;
++ }
++ }
+
- if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
- log_error_write(srv, __FILE__, __LINE__,
- "ss", "couldn't set 'max filedescriptors'",
-@@ -659,7 +678,7 @@
- }
- }
-
-- /* #372: solaris need some fds extra for devpoll */
+ /* #372: solaris need some fds extra for devpoll */
- if (rlim.rlim_cur > 10) rlim.rlim_cur -= 10;
-
- if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
-@@ -677,33 +696,33 @@
++ if (rlim.rlim_cur > 10) rlim.rlim_cur -= 10;
++
++ if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
++ srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
++ } else {
++ srv->max_fds = rlim.rlim_cur;
++ }
++
++ /* set core file rlimit, if enable_cores is set */
++ if (use_rlimit && srv->srvconf.enable_cores && getrlimit(RLIMIT_CORE, &rlim) == 0) {
++ rlim.rlim_cur = rlim.rlim_max;
+ setrlimit(RLIMIT_CORE, &rlim);
+ }
+ #endif
if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
/* don't raise the limit above FD_SET_SIZE */
if (srv->max_fds > FD_SETSIZE - 200) {
"can't find groupname", srv->srvconf.groupname);
return -1;
}
-@@ -713,15 +732,15 @@
+@@ -713,15 +1083,15 @@
return -1;
}
}
if (srv->srvconf.changeroot->used) {
tzset();
-@@ -761,7 +780,7 @@
+@@ -761,7 +1131,7 @@
}
if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
} else {
srv->max_fds = rlim.rlim_cur;
}
-@@ -775,18 +794,18 @@
+@@ -775,18 +1145,18 @@
#endif
if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
/* don't raise the limit above FD_SET_SIZE */
return -1;
}
}
-@@ -802,25 +821,27 @@
+@@ -802,25 +1172,27 @@
/* or use the default */
srv->max_conns = srv->max_fds;
}
/* write pid file */
if (pid_fd != -1) {
buffer_copy_long(srv->tmp_buf, getpid());
-@@ -829,17 +850,17 @@
+@@ -829,17 +1201,17 @@
close(pid_fd);
pid_fd = -1;
}
/* dump unused config-keys */
for (i = 0; i < srv->config_context->used; i++) {
array *config = ((data_config *)srv->config_context->data[i])->value;
-@@ -847,43 +868,42 @@
+@@ -847,43 +1219,42 @@
for (j = 0; config && j < config->used; j++) {
data_unset *du = config->data[j];
return -1;
}
-
-+
- if (-1 == log_error_open(srv)) {
+- if (-1 == log_error_open(srv)) {
- log_error_write(srv, __FILE__, __LINE__, "s",
++
++ if (-1 == log_error_open(srv->srvconf.errorlog_file, srv->srvconf.errorlog_use_syslog)) {
+ log_error_write(srv, __FILE__, __LINE__, "s",
"opening errorlog failed, dying");
-
#ifdef HAVE_SIGACTION
memset(&act, 0, sizeof(act));
act.sa_handler = SIG_IGN;
-@@ -903,7 +923,7 @@
+@@ -903,7 +1274,7 @@
sigaction(SIGHUP, &act, NULL);
sigaction(SIGALRM, &act, NULL);
sigaction(SIGCHLD, &act, NULL);
#elif defined(HAVE_SIGNAL)
/* ignore the SIGPIPE from sendfile() */
signal(SIGPIPE, SIG_IGN);
-@@ -914,20 +934,20 @@
+@@ -914,20 +1285,20 @@
signal(SIGCHLD, signal_handler);
signal(SIGINT, signal_handler);
#endif
/* start watcher and workers */
num_childs = srv->srvconf.max_worker;
if (num_childs > 0) {
-@@ -957,13 +977,13 @@
+@@ -957,13 +1328,13 @@
}
#endif
* all server sockets get their handlers
*
* */
-@@ -971,7 +991,7 @@
+@@ -971,7 +1342,7 @@
plugins_free(srv);
network_close(srv);
server_free(srv);
return -1;
}
-@@ -986,7 +1006,7 @@
+@@ -986,17 +1357,17 @@
/* setup FAM */
if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM) {
if (0 != FAMOpen2(srv->stat_cache->fam, "lighttpd")) {
"could not open a fam connection, dieing.");
return -1;
}
-@@ -1018,16 +1038,40 @@
- int n;
- size_t ndx;
- time_t min_ts;
+ #ifdef HAVE_FAMNOEXISTS
+ FAMNoExists(srv->stat_cache->fam);
+ #endif
++ srv->stat_cache->sock->fd = FAMCONNECTION_GETFD(srv->stat_cache->fam);
+
+- srv->stat_cache->fam_fcce_ndx = -1;
+- fdevent_register(srv->ev, FAMCONNECTION_GETFD(srv->stat_cache->fam), stat_cache_handle_fdevent, NULL);
+- fdevent_event_add(srv->ev, &(srv->stat_cache->fam_fcce_ndx), FAMCONNECTION_GETFD(srv->stat_cache->fam), FDEVENT_IN);
++ fdevent_register(srv->ev, srv->stat_cache->sock, stat_cache_handle_fdevent, NULL);
++ fdevent_event_add(srv->ev, srv->stat_cache->sock, FDEVENT_IN);
+ }
+ #endif
+
+@@ -1007,330 +1378,34 @@
+
+ for (i = 0; i < srv->srv_sockets.used; i++) {
+ server_socket *srv_socket = srv->srv_sockets.ptr[i];
+- if (-1 == fdevent_fcntl_set(srv->ev, srv_socket->fd)) {
++ if (-1 == fdevent_fcntl_set(srv->ev, srv_socket->sock)) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed:", strerror(errno));
+ return -1;
+ }
+ }
+
+- /* main-loop */
+- while (!srv_shutdown) {
+- int n;
+- size_t ndx;
+- time_t min_ts;
-
-+
- if (handle_sig_hup) {
- handler_t r;
+- if (handle_sig_hup) {
+- handler_t r;
-
-+
- /* reset notification */
- handle_sig_hup = 0;
+- /* reset notification */
+- handle_sig_hup = 0;
-
-
-+
-+#if 0
-+ pid_t pid;
-+
-+ /* send the old process into a graceful-shutdown and start a
-+ * new process right away
-+ *
-+ * BUGS:
-+ * - if webserver is running on port < 1024 (e.g. 80, 433)
-+ * we don't have the permissions to bind to that port anymore
-+ *
-+ *
-+ * */
-+ if (0 == (pid = fork())) {
-+ execve(argv[0], argv, envp);
-+
-+ exit(-1);
-+ } else if (pid == -1) {
-+
-+ } else {
-+ /* parent */
-+
-+ graceful_shutdown = 1; /* shutdown without killing running connections */
-+ graceful_restart = 1; /* don't delete pid file */
-+ }
-+#else
- /* cycle logfiles */
+- /* cycle logfiles */
-
-+
- switch(r = plugins_call_handle_sighup(srv)) {
- case HANDLER_GO_ON:
- break;
-@@ -1035,30 +1079,31 @@
- log_error_write(srv, __FILE__, __LINE__, "sd", "sighup-handler return with an error", r);
- break;
- }
+- switch(r = plugins_call_handle_sighup(srv)) {
+- case HANDLER_GO_ON:
+- break;
+- default:
+- log_error_write(srv, __FILE__, __LINE__, "sd", "sighup-handler return with an error", r);
+- break;
+- }
-
-+
- if (-1 == log_error_cycle(srv)) {
- log_error_write(srv, __FILE__, __LINE__, "s", "cycling errorlog failed, dying");
+- if (-1 == log_error_cycle(srv)) {
+- log_error_write(srv, __FILE__, __LINE__, "s", "cycling errorlog failed, dying");
-
-+
- return -1;
- }
-+#endif
- }
+- return -1;
+- }
+- }
-
-+
- if (handle_sig_alarm) {
- /* a new second */
+- if (handle_sig_alarm) {
+- /* a new second */
-
-+
- #ifdef USE_ALARM
- /* reset notification */
- handle_sig_alarm = 0;
- #endif
+-#ifdef USE_ALARM
+- /* reset notification */
+- handle_sig_alarm = 0;
+-#endif
-
-+
- /* get current time */
- min_ts = time(NULL);
+- /* get current time */
+- min_ts = time(NULL);
-
-+
- if (min_ts != srv->cur_ts) {
- int cs = 0;
- connections *conns = srv->conns;
- handler_t r;
+- if (min_ts != srv->cur_ts) {
+- int cs = 0;
+- connections *conns = srv->conns;
+- handler_t r;
-
-+
- switch(r = plugins_call_handle_trigger(srv)) {
- case HANDLER_GO_ON:
- break;
-@@ -1069,21 +1114,21 @@
- log_error_write(srv, __FILE__, __LINE__, "d", r);
- break;
- }
+- switch(r = plugins_call_handle_trigger(srv)) {
+- case HANDLER_GO_ON:
+- break;
+- case HANDLER_ERROR:
+- log_error_write(srv, __FILE__, __LINE__, "s", "one of the triggers failed");
+- break;
+- default:
+- log_error_write(srv, __FILE__, __LINE__, "d", r);
+- break;
+- }
-
-+
- /* trigger waitpid */
- srv->cur_ts = min_ts;
+- /* trigger waitpid */
+- srv->cur_ts = min_ts;
-
- /* cleanup stat-cache */
-+
-+ /* cleanup stat-cache */
- stat_cache_trigger_cleanup(srv);
- /**
+- stat_cache_trigger_cleanup(srv);
+- /**
- * check all connections for timeouts
- *
-+ * check all connections for timeouts
-+ *
- */
- for (ndx = 0; ndx < conns->used; ndx++) {
- int changed = 0;
- connection *con;
- int t_diff;
+- */
+- for (ndx = 0; ndx < conns->used; ndx++) {
+- int changed = 0;
+- connection *con;
+- int t_diff;
-
-+
- con = conns->ptr[ndx];
-
- if (con->state == CON_STATE_READ ||
-@@ -1092,7 +1137,7 @@
- if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
- /* time - out */
- #if 0
+- con = conns->ptr[ndx];
+-
+- if (con->state == CON_STATE_READ ||
+- con->state == CON_STATE_READ_POST) {
+- if (con->request_count == 1) {
+- if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
+- /* time - out */
+-#if 0
- log_error_write(srv, __FILE__, __LINE__, "sd",
-+ log_error_write(srv, __FILE__, __LINE__, "sd",
- "connection closed - read-timeout:", con->fd);
- #endif
- connection_set_state(srv, con, CON_STATE_ERROR);
-@@ -1102,7 +1147,7 @@
- if (srv->cur_ts - con->read_idle_ts > con->conf.max_keep_alive_idle) {
- /* time - out */
- #if 0
+- "connection closed - read-timeout:", con->fd);
+-#endif
+- connection_set_state(srv, con, CON_STATE_ERROR);
+- changed = 1;
+- }
+- } else {
+- if (srv->cur_ts - con->read_idle_ts > con->conf.max_keep_alive_idle) {
+- /* time - out */
+-#if 0
- log_error_write(srv, __FILE__, __LINE__, "sd",
-+ log_error_write(srv, __FILE__, __LINE__, "sd",
- "connection closed - read-timeout:", con->fd);
- #endif
- connection_set_state(srv, con, CON_STATE_ERROR);
-@@ -1110,20 +1155,20 @@
- }
- }
- }
+- "connection closed - read-timeout:", con->fd);
+-#endif
+- connection_set_state(srv, con, CON_STATE_ERROR);
+- changed = 1;
+- }
+- }
+- }
-
-+
- if ((con->state == CON_STATE_WRITE) &&
+- if ((con->state == CON_STATE_WRITE) &&
- (con->write_request_ts != 0)) {
-+ (con->write_request_ts != 0)) {
- #if 0
- if (srv->cur_ts - con->write_request_ts > 60) {
+-#if 0
+- if (srv->cur_ts - con->write_request_ts > 60) {
- log_error_write(srv, __FILE__, __LINE__, "sdd",
-+ log_error_write(srv, __FILE__, __LINE__, "sdd",
- "connection closed - pre-write-request-timeout:", con->fd, srv->cur_ts - con->write_request_ts);
- }
- #endif
+- "connection closed - pre-write-request-timeout:", con->fd, srv->cur_ts - con->write_request_ts);
+- }
+-#endif
-
-+
- if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) {
- /* time - out */
- #if 1
+- if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) {
+- /* time - out */
+-#if 1
- log_error_write(srv, __FILE__, __LINE__, "sbsosds",
-+ log_error_write(srv, __FILE__, __LINE__, "sbsosds",
- "NOTE: a request for",
- con->request.uri,
- "timed out after writing",
-@@ -1138,35 +1183,35 @@
- }
- /* we don't like div by zero */
- if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1;
+- "NOTE: a request for",
+- con->request.uri,
+- "timed out after writing",
+- con->bytes_written,
+- "bytes. We waited",
+- (int)con->conf.max_write_idle,
+- "seconds. If this a problem increase server.max-write-idle");
+-#endif
+- connection_set_state(srv, con, CON_STATE_ERROR);
+- changed = 1;
+- }
+- }
+- /* we don't like div by zero */
+- if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1;
-
- if (con->traffic_limit_reached &&
- (con->conf.kbytes_per_second == 0 ||
-+
-+ if (con->traffic_limit_reached &&
-+ (con->conf.kbytes_per_second == 0 ||
- ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) {
- /* enable connection again */
- con->traffic_limit_reached = 0;
+- ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) {
+- /* enable connection again */
+- con->traffic_limit_reached = 0;
-
-+
- changed = 1;
- }
+- changed = 1;
+- }
-
-+
- if (changed) {
- connection_state_machine(srv, con);
- }
- con->bytes_written_cur_second = 0;
- *(con->conf.global_bytes_per_second_cnt_ptr) = 0;
+- if (changed) {
+- connection_state_machine(srv, con);
+- }
+- con->bytes_written_cur_second = 0;
+- *(con->conf.global_bytes_per_second_cnt_ptr) = 0;
-
-+
- #if 0
- if (cs == 0) {
- fprintf(stderr, "connection-state: ");
- cs = 1;
- }
+-#if 0
+- if (cs == 0) {
+- fprintf(stderr, "connection-state: ");
+- cs = 1;
+- }
-
-+
- fprintf(stderr, "c[%d,%d]: %s ",
- con->fd,
- con->fcgi.fd,
- connection_get_state(con->state));
- #endif
- }
+- fprintf(stderr, "c[%d,%d]: %s ",
+- con->fd,
+- con->fcgi.fd,
+- connection_get_state(con->state));
+-#endif
+- }
-
-+
- if (cs == 1) fprintf(stderr, "\n");
- }
- }
-@@ -1181,18 +1226,18 @@
- server_socket *srv_socket = srv->srv_sockets.ptr[i];
- fdevent_event_add(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
- }
+- if (cs == 1) fprintf(stderr, "\n");
+- }
+- }
+-
+- if (srv->sockets_disabled) {
+- /* our server sockets are disabled, why ? */
+-
+- if ((srv->cur_fds + srv->want_fds < srv->max_fds * 0.8) && /* we have enough unused fds */
+- (srv->conns->used < srv->max_conns * 0.9) &&
+- (0 == graceful_shutdown)) {
+- for (i = 0; i < srv->srv_sockets.used; i++) {
+- server_socket *srv_socket = srv->srv_sockets.ptr[i];
+- fdevent_event_add(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
+- }
-
-+
- log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again");
+- log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again");
-
-+
- srv->sockets_disabled = 0;
- }
- } else {
- if ((srv->cur_fds + srv->want_fds > srv->max_fds * 0.9) || /* out of fds */
- (srv->conns->used > srv->max_conns) || /* out of connections */
+- srv->sockets_disabled = 0;
+- }
+- } else {
+- if ((srv->cur_fds + srv->want_fds > srv->max_fds * 0.9) || /* out of fds */
+- (srv->conns->used > srv->max_conns) || /* out of connections */
- (graceful_shutdown)) { /* graceful_shutdown */
-+ (graceful_shutdown)) { /* graceful_shutdown */
-
- /* disable server-fds */
+-
+- /* disable server-fds */
-
-+
- for (i = 0; i < srv->srv_sockets.used; i++) {
- server_socket *srv_socket = srv->srv_sockets.ptr[i];
- fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
-@@ -1211,7 +1256,7 @@
- /* network_close() will cleanup after us */
- }
- }
+- for (i = 0; i < srv->srv_sockets.used; i++) {
+- server_socket *srv_socket = srv->srv_sockets.ptr[i];
+- fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
+-
+- if (graceful_shutdown) {
+- /* we don't want this socket anymore,
+- *
+- * closing it right away will make it possible for
+- * the next lighttpd to take over (graceful restart)
+- * */
+-
+- fdevent_unregister(srv->ev, srv_socket->fd);
+- close(srv_socket->fd);
+- srv_socket->fd = -1;
+-
+- /* network_close() will cleanup after us */
+- }
+- }
-
-+
- if (graceful_shutdown) {
- log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
- } else if (srv->conns->used > srv->max_conns) {
-@@ -1219,7 +1264,7 @@
- } else {
- log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
- }
+- if (graceful_shutdown) {
+- log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
+- } else if (srv->conns->used > srv->max_conns) {
+- log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached");
+- } else {
+- log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
+- }
-
-+
- srv->sockets_disabled = 1;
- }
- }
-@@ -1229,16 +1274,16 @@
- * we are ready to terminate without harming anyone */
- srv_shutdown = 1;
- }
+- srv->sockets_disabled = 1;
+- }
+- }
+-
+- if (graceful_shutdown && srv->conns->used == 0) {
+- /* we are in graceful shutdown phase and all connections are closed
+- * we are ready to terminate without harming anyone */
+- srv_shutdown = 1;
+- }
-
-+
- /* we still have some fds to share */
+- /* we still have some fds to share */
- if (srv->want_fds) {
-+ if (srv->want_fds) {
- /* check the fdwaitqueue for waiting fds */
- int free_fds = srv->max_fds - srv->cur_fds - 16;
- connection *con;
+- /* check the fdwaitqueue for waiting fds */
+- int free_fds = srv->max_fds - srv->cur_fds - 16;
+- connection *con;
-
-+
- for (; free_fds > 0 && NULL != (con = fdwaitqueue_unshift(srv, srv->fdwaitqueue)); free_fds--) {
- connection_state_machine(srv, con);
+- for (; free_fds > 0 && NULL != (con = fdwaitqueue_unshift(srv, srv->fdwaitqueue)); free_fds--) {
+- connection_state_machine(srv, con);
-
-+
- srv->want_fds--;
- }
- }
-@@ -1249,27 +1294,27 @@
- int fd_ndx;
- #if 0
- if (n > 0) {
+- srv->want_fds--;
+- }
+- }
++ lighty_mainloop(srv);
+
+- if ((n = fdevent_poll(srv->ev, 1000)) > 0) {
+- /* n is the number of events */
+- int revents;
+- int fd_ndx;
+-#if 0
+- if (n > 0) {
- log_error_write(srv, __FILE__, __LINE__, "sd",
-+ log_error_write(srv, __FILE__, __LINE__, "sd",
- "polls:", n);
- }
+- "polls:", n);
+- }
-#endif
-+#endif
- fd_ndx = -1;
- do {
- fdevent_handler handler;
- void *context;
- handler_t r;
--
-+
- fd_ndx = fdevent_event_next_fdndx (srv->ev, fd_ndx);
- revents = fdevent_event_get_revent (srv->ev, fd_ndx);
- fd = fdevent_event_get_fd (srv->ev, fd_ndx);
- handler = fdevent_get_handler(srv->ev, fd);
- context = fdevent_get_context(srv->ev, fd);
--
-+
- /* connection_handle_fdevent needs a joblist_append */
- #if 0
+- fd_ndx = -1;
+- do {
+- fdevent_handler handler;
+- void *context;
+- handler_t r;
+-
+- fd_ndx = fdevent_event_next_fdndx (srv->ev, fd_ndx);
+- revents = fdevent_event_get_revent (srv->ev, fd_ndx);
+- fd = fdevent_event_get_fd (srv->ev, fd_ndx);
+- handler = fdevent_get_handler(srv->ev, fd);
+- context = fdevent_get_context(srv->ev, fd);
+-
+- /* connection_handle_fdevent needs a joblist_append */
+-#if 0
- log_error_write(srv, __FILE__, __LINE__, "sdd",
-+ log_error_write(srv, __FILE__, __LINE__, "sdd",
- "event for", fd, revents);
+- "event for", fd, revents);
-#endif
-+#endif
- switch (r = (*handler)(srv, context, revents)) {
- case HANDLER_FINISHED:
- case HANDLER_GO_ON:
-@@ -1286,17 +1331,17 @@
- }
- } while (--n > 0);
- } else if (n < 0 && errno != EINTR) {
+- switch (r = (*handler)(srv, context, revents)) {
+- case HANDLER_FINISHED:
+- case HANDLER_GO_ON:
+- case HANDLER_WAIT_FOR_EVENT:
+- case HANDLER_WAIT_FOR_FD:
+- break;
+- case HANDLER_ERROR:
+- /* should never happen */
+- SEGFAULT();
+- break;
+- default:
+- log_error_write(srv, __FILE__, __LINE__, "d", r);
+- break;
+- }
+- } while (--n > 0);
+- } else if (n < 0 && errno != EINTR) {
- log_error_write(srv, __FILE__, __LINE__, "ss",
- "fdevent_poll failed:",
-+ log_error_write(srv, __FILE__, __LINE__, "ss",
-+ "fdevent_poll failed:",
- strerror(errno));
- }
+- strerror(errno));
+- }
-
-+
- for (ndx = 0; ndx < srv->joblist->used; ndx++) {
- connection *con = srv->joblist->ptr[ndx];
- handler_t r;
+- for (ndx = 0; ndx < srv->joblist->used; ndx++) {
+- connection *con = srv->joblist->ptr[ndx];
+- handler_t r;
-
-+
- connection_state_machine(srv, con);
+- connection_state_machine(srv, con);
-
-+
- switch(r = plugins_call_handle_joblist(srv, con)) {
- case HANDLER_FINISHED:
- case HANDLER_GO_ON:
-@@ -1305,32 +1350,33 @@
- log_error_write(srv, __FILE__, __LINE__, "d", r);
- break;
- }
+- switch(r = plugins_call_handle_joblist(srv, con)) {
+- case HANDLER_FINISHED:
+- case HANDLER_GO_ON:
+- break;
+- default:
+- log_error_write(srv, __FILE__, __LINE__, "d", r);
+- break;
+- }
-
-+
- con->in_joblist = 0;
- }
+- con->in_joblist = 0;
+- }
-
-+
- srv->joblist->used = 0;
- }
+- srv->joblist->used = 0;
+- }
-
- if (srv->srvconf.pid_file->used &&
-+
+ if (0 == graceful_restart &&
+ srv->srvconf.pid_file->used &&
srv->srvconf.changeroot->used == 0) {
-
+
/* clean-up */
- log_error_close(srv);
+- log_error_close(srv);
network_close(srv);
connections_free(srv);
plugins_free(srv);
server_free(srv);
-
++ log_free();
+
return 0;
}
--- ../lighttpd-1.4.11/src/settings.h 2005-08-11 01:26:41.000000000 +0300
-+++ lighttpd-1.4.12/src/settings.h 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/settings.h 2006-07-16 00:26:04.000000000 +0300
@@ -9,24 +9,24 @@
/**
* max size of a buffer which will just be reset
HANDLER_WAIT_FOR_FD
} handler_t;
--- ../lighttpd-1.4.11/src/spawn-fcgi.c 2006-03-07 14:18:10.000000000 +0200
-+++ lighttpd-1.4.12/src/spawn-fcgi.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/spawn-fcgi.c 2006-07-16 00:26:04.000000000 +0300
@@ -1,19 +1,16 @@
#include <sys/types.h>
-#include <sys/time.h>
}
#else
--- ../lighttpd-1.4.11/src/splaytree.c 2005-09-12 21:51:28.000000000 +0300
-+++ lighttpd-1.4.12/src/splaytree.c 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/splaytree.c 2006-07-16 00:26:03.000000000 +0300
@@ -56,19 +56,19 @@
#define node_size splaytree_size
r->left = t->right;
t->left = N.right;
--- ../lighttpd-1.4.11/src/splaytree.h 2005-09-12 21:51:13.000000000 +0300
-+++ lighttpd-1.4.12/src/splaytree.h 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/splaytree.h 2006-07-16 00:26:03.000000000 +0300
@@ -19,6 +19,6 @@
/* This macro returns the size of a node. Unlike "x->size", */
/* it works even if x=NULL. The test could be avoided by using */
#endif
--- ../lighttpd-1.4.11/src/stat_cache.c 2005-11-22 15:23:51.000000000 +0200
-+++ lighttpd-1.4.12/src/stat_cache.c 2006-07-15 22:43:21.000000000 +0300
++++ lighttpd-1.4.12/src/stat_cache.c 2006-07-18 13:03:40.000000000 +0300
@@ -6,7 +6,6 @@
#include <stdlib.h>
#include <string.h>
typedef struct {
int *ptr;
-@@ -105,15 +93,15 @@
+@@ -105,15 +93,16 @@
stat_cache *stat_cache_init(void) {
stat_cache *fc = NULL;
fc->dir_name = buffer_init();
#ifdef HAVE_FAM_H
fc->fam = calloc(1, sizeof(*fc->fam));
++ fc->sock = iosocket_init();
#endif
-#ifdef DEBUG_STAT_CACHE
ctrl.size = 0;
#endif
-@@ -122,24 +110,24 @@
+@@ -122,24 +111,24 @@
static stat_cache_entry * stat_cache_entry_init(void) {
stat_cache_entry *sce = NULL;
free(sce);
}
-@@ -148,22 +136,22 @@
+@@ -148,22 +137,22 @@
fam_dir_entry *fam_dir = NULL;
fam_dir = calloc(1, sizeof(*fam_dir));
free(fam_dir);
}
#endif
-@@ -174,7 +162,7 @@
+@@ -174,7 +163,7 @@
splay_tree *node = sc->files;
osize = sc->files->size;
stat_cache_entry_free(node->data);
sc->files = splaytree_delete(sc->files, node->key);
-@@ -187,12 +175,12 @@
+@@ -187,12 +176,12 @@
while (sc->dirs) {
int osize;
splay_tree *node = sc->dirs;
if (osize == 1) {
assert(NULL == sc->dirs);
} else {
-@@ -212,7 +200,7 @@
+@@ -202,6 +191,7 @@
+
+ if (sc->fam) {
+ FAMClose(sc->fam);
++ iosocket_free(sc->sock);
+ free(sc->fam);
+ }
+ #endif
+@@ -212,7 +202,7 @@
static int stat_cache_attr_get(buffer *buf, char *name) {
int attrlen;
int ret;
attrlen = 1024;
buffer_prepare_copy(buf, attrlen);
attrlen--;
-@@ -251,15 +239,15 @@
+@@ -251,15 +241,15 @@
sc->fam) {
events = FAMPending(sc->fam);
/* handle event */
switch(fe.code) {
-@@ -280,7 +268,7 @@
+@@ -280,7 +270,7 @@
sc->dirs = splaytree_splay(sc->dirs, ndx);
node = sc->dirs;
if (node && (node->key == ndx)) {
int osize = splaytree_size(sc->dirs);
-@@ -308,7 +296,7 @@
+@@ -298,17 +288,15 @@
+
+ if (revent & FDEVENT_HUP) {
+ /* fam closed the connection */
+- srv->stat_cache->fam_fcce_ndx = -1;
+-
+- fdevent_event_del(srv->ev, &(sc->fam_fcce_ndx), FAMCONNECTION_GETFD(sc->fam));
+- fdevent_unregister(srv->ev, FAMCONNECTION_GETFD(sc->fam));
++ fdevent_event_del(srv->ev, sc->sock);
++ fdevent_unregister(srv->ev, sc->sock);
+
+ FAMClose(sc->fam);
+ free(sc->fam);
sc->fam = NULL;
}
if (ctrl.ptr[j] == ndx) {
ctrl.ptr[j] = ctrl.ptr[--ctrl.used];
--- ../lighttpd-1.4.11/src/stream.c 2005-09-23 21:50:15.000000000 +0300
-+++ lighttpd-1.4.12/src/stream.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/stream.c 2006-07-16 00:26:04.000000000 +0300
@@ -1,7 +1,6 @@
#include <sys/types.h>
#include <sys/stat.h>
}
--- ../lighttpd-1.4.11/src/sys-files.h 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.4.12/src/sys-files.h 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/src/sys-files.h 2006-07-16 00:26:04.000000000 +0300
@@ -0,0 +1,67 @@
+#ifndef _SYS_FILES_H_
+#define _SYS_FILES_H_
+#endif
+
--- ../lighttpd-1.4.11/src/sys-mmap.h 2005-08-11 01:26:34.000000000 +0300
-+++ lighttpd-1.4.12/src/sys-mmap.h 2006-07-11 22:07:52.000000000 +0300
++++ lighttpd-1.4.12/src/sys-mmap.h 2006-07-16 00:26:04.000000000 +0300
@@ -1,7 +1,7 @@
#ifndef WIN32_MMAP_H
#define WIN32_MMAP_H
#define MAP_FAILED -1
#define PROT_SHARED 0
--- ../lighttpd-1.4.11/src/sys-process.h 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.4.12/src/sys-process.h 2006-07-15 22:43:21.000000000 +0300
++++ lighttpd-1.4.12/src/sys-process.h 2006-07-16 00:26:04.000000000 +0300
@@ -0,0 +1,17 @@
+#ifndef _SYS_PROCESS_H_
+#define _SYS_PROCESS_H_
+#endif
+
--- ../lighttpd-1.4.11/src/sys-socket.h 2005-08-11 01:26:39.000000000 +0300
-+++ lighttpd-1.4.12/src/sys-socket.h 2006-07-15 22:43:21.000000000 +0300
++++ lighttpd-1.4.12/src/sys-socket.h 2006-07-18 13:03:40.000000000 +0300
@@ -1,15 +1,26 @@
#ifndef WIN32_SOCKET_H
#define WIN32_SOCKET_H
#else
#include <sys/socket.h>
#include <sys/ioctl.h>
-@@ -18,7 +29,23 @@
+@@ -18,7 +29,25 @@
#include <sys/un.h>
#include <arpa/inet.h>
+#define SUN_LEN(su) \
+ (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
+#endif
++
++#define closesocket(x) close(x)
+
#include <netdb.h>
- #endif
-
++#endif /* !_WIN32 */
++
+typedef union {
+#ifdef HAVE_IPV6
+ struct sockaddr_in6 ipv6;
+ struct sockaddr_in ipv4;
+#ifdef HAVE_SYS_UN_H
+ struct sockaddr_un un;
-+#endif
+ #endif
+ struct sockaddr plain;
+} sock_addr;
-+
+
#endif
--- ../lighttpd-1.4.11/src/sys-strings.h 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.4.12/src/sys-strings.h 2006-07-11 22:07:51.000000000 +0300
++++ lighttpd-1.4.12/src/sys-strings.h 2006-07-16 00:26:03.000000000 +0300
@@ -0,0 +1,11 @@
+#ifndef _SYS_STRINGS_H_
+#define _SYS_STRINGS_H_
+#endif
+
--- ../lighttpd-1.4.11/tests/LightyTest.pm 2006-01-14 20:32:31.000000000 +0200
-+++ lighttpd-1.4.12/tests/LightyTest.pm 2006-07-11 22:07:53.000000000 +0300
-@@ -87,14 +87,14 @@
++++ lighttpd-1.4.12/tests/LightyTest.pm 2006-07-18 13:03:40.000000000 +0300
+@@ -87,14 +87,16 @@
# pre-process configfile if necessary
#
+ $ENV{'PORT'} = $self->{PORT};
unlink($self->{LIGHTTPD_PIDFILE});
- if (1) {
+- if (1) {
- system($self->{LIGHTTPD_PATH}." -f ".$self->{TESTDIR}."/tmp/cfg.file -m ".$self->{MODULES_PATH});
-+ system($self->{LIGHTTPD_PATH}." -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH});
++ if (defined $ENV{"TRACEME"} && $ENV{"TRACEME"} eq 'strace') {
++ system("strace -tt -s 512 -o strace ".$self->{LIGHTTPD_PATH}." -D -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH}." &");
++ } elsif (defined $ENV{"TRACEME"} && $ENV{"TRACEME"} eq 'valgrind') {
++ system("valgrind --tool=memcheck --show-reachable=yes --leak-check=yes --logfile=valgrind ".$self->{LIGHTTPD_PATH}." -D -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH}." &");
} else {
- system("valgrind --tool=memcheck --show-reachable=yes --leak-check=yes --logfile=foo ".$self->{LIGHTTPD_PATH}." -D -f ".$self->{TESTDIR}."/tmp/cfg.file -m ".$self->{MODULES_PATH}." &");
-+ system("valgrind --tool=memcheck --show-reachable=yes --leak-check=yes --logfile=foo ".$self->{LIGHTTPD_PATH}." -D -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH}." &");
++ system($self->{LIGHTTPD_PATH}." -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH});
}
select(undef, undef, undef, 0.1);
-@@ -184,7 +184,7 @@
+@@ -184,7 +186,7 @@
(my $h = $1) =~ tr/[A-Z]/[a-z]/;
if (defined $resp_hdr{$h}) {
$h, $resp_hdr{$h}, $2));
} else {
$resp_hdr{$h} = $2;
-@@ -196,6 +196,9 @@
+@@ -196,6 +198,9 @@
}
}
if (defined $resp_hdr{"content-length"}) {
$resp_body = substr($lines, 0, $resp_hdr{"content-length"});
--- ../lighttpd-1.4.11/tests/Makefile.am 2005-09-16 15:48:40.000000000 +0300
-+++ lighttpd-1.4.12/tests/Makefile.am 2006-07-15 22:43:22.000000000 +0300
++++ lighttpd-1.4.12/tests/Makefile.am 2006-07-16 00:26:05.000000000 +0300
@@ -39,10 +39,18 @@
mod-redirect.t \
mod-userdir.t \
TESTS_ENVIRONMENT=$(srcdir)/wrapper.sh $(srcdir) $(top_builddir)
--- ../lighttpd-1.4.11/tests/bug-06.conf 2005-08-27 17:44:19.000000000 +0300
-+++ lighttpd-1.4.12/tests/bug-06.conf 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/tests/bug-06.conf 2006-07-16 00:26:04.000000000 +0300
@@ -1,5 +1,5 @@
-server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
}
--- ../lighttpd-1.4.11/tests/bug-12.conf 2005-08-27 17:44:19.000000000 +0300
-+++ lighttpd-1.4.12/tests/bug-12.conf 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/tests/bug-12.conf 2006-07-16 00:26:04.000000000 +0300
@@ -1,5 +1,5 @@
-server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
}
--- ../lighttpd-1.4.11/tests/cachable.t 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.4.12/tests/cachable.t 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/tests/cachable.t 2006-07-18 13:03:40.000000000 +0300
@@ -0,0 +1,112 @@
+#!/usr/bin/env perl
+BEGIN {
+If-Modified-Since: Sun, 01 Jan 1970 00:00:01 GMT; foo
+EOF
+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
++$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Last-Modified' => ''} ];
+ok($tf->handle_http($t) == 0, 'Conditional GET - old If-Modified-Since, comment');
+
+my $now = $t->{date};
+If-None-Match: foo
+EOF
+ );
-+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
++$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+ETag' => ''} ];
+ok($tf->handle_http($t) == 0, 'Conditional GET - old If-None-Match');
+
+my $etag = $t->{etag};
+ok($tf->stop_proc == 0, "Stopping lighttpd");
+
--- ../lighttpd-1.4.11/tests/condition.conf 2005-08-27 17:44:19.000000000 +0300
-+++ lighttpd-1.4.12/tests/condition.conf 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/tests/condition.conf 2006-07-16 00:26:05.000000000 +0300
@@ -2,15 +2,15 @@
debug.log-request-handling = "enable"
debug.log-condition-handling = "enable"
url.redirect = ("^" => "/match_4")
--- ../lighttpd-1.4.11/tests/core-keepalive.t 2005-11-17 15:54:19.000000000 +0200
-+++ lighttpd-1.4.12/tests/core-keepalive.t 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/tests/core-keepalive.t 2006-07-16 00:26:05.000000000 +0300
@@ -40,7 +40,7 @@
GET /12345.txt HTTP/1.0
EOF
);
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
+--- ../lighttpd-1.4.11/tests/default.conf 1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/tests/default.conf 2006-07-16 00:26:05.000000000 +0300
+@@ -0,0 +1,111 @@
++server.name = "www.example.org"
++
++## bind to port (default: 80)
++server.port = env.PORT
++
++
++server.dir-listing = "enable"
++
++#server.event-handler = "linux-sysepoll"
++#server.event-handler = "linux-rtsig"
++
++server.modules = (
++ "mod_rewrite",
++ "mod_setenv",
++ "mod_access",
++ "mod_auth",
++ "mod_status",
++ "mod_expire",
++ "mod_simple_vhost",
++ "mod_redirect",
++ "mod_secdownload",
++ "mod_ssi",
++ "mod_fastcgi",
++ "mod_proxy",
++ "mod_cgi",
++ "mod_compress",
++ "mod_userdir",
++ "mod_accesslog" )
++
++server.indexfiles = ( "index.php", "index.html",
++ "index.htm", "default.htm" )
++
++ssi.extension = ( ".shtml" )
++
++######################## MODULE CONFIG ############################
++
++
++accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
++server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
++
++mimetype.assign = ( ".png" => "image/png",
++ ".jpg" => "image/jpeg",
++ ".jpeg" => "image/jpeg",
++ ".gif" => "image/gif",
++ ".html" => "text/html",
++ ".htm" => "text/html",
++ ".pdf" => "application/pdf",
++ ".swf" => "application/x-shockwave-flash",
++ ".spl" => "application/futuresplash",
++ ".txt" => "text/plain",
++ ".tar.gz" => "application/x-tgz",
++ ".tgz" => "application/x-tgz",
++ ".gz" => "application/x-gzip",
++ ".c" => "text/plain",
++ ".conf" => "text/plain" )
++
++compress.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
++compress.filetype = ("text/plain", "text/html")
++
++setenv.add-environment = ( "TRAC_ENV" => "tracenv", "SETENV" => "setenv")
++
++cgi.assign = ( ".pl" => "/usr/bin/perl",
++ ".cgi" => "/usr/bin/perl",
++ ".py" => "/usr/bin/python" )
++
++userdir.include-user = ( "jan" )
++userdir.path = "/"
++
++ssl.engine = "disable"
++ssl.pemfile = "server.pem"
++
++auth.backend = "plain"
++auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
++auth.backend.htpasswd.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.htpasswd"
++auth.backend.plain.groupfile = "lighttpd.group"
++
++auth.backend.ldap.hostname = "localhost"
++auth.backend.ldap.base-dn = "dc=my-domain,dc=com"
++auth.backend.ldap.filter = "(uid=$)"
++
++auth.require = ( "/server-status" =>
++ (
++ "method" => "digest",
++ "realm" => "download archiv",
++ "require" => "valid-user"
++ ),
++ "/auth.php" =>
++ (
++ "method" => "basic",
++ "realm" => "download archiv",
++ "require" => "user=jan"
++ ),
++ "/server-config" =>
++ (
++ "method" => "basic",
++ "realm" => "download archiv",
++ "require" => "valid-user"
++ )
++ )
++
++url.access-deny = ( "~", ".inc")
++
++url.redirect = ( "^/redirect/$" => "http://localhost:2048/" )
++
++url.rewrite = ( "^/rewrite/foo($|\?.+)" => "/indexfile/rewrite.php$1",
++ "^/rewrite/bar(?:$|\?(.+))" => "/indexfile/rewrite.php?bar&$1" )
++
++#### status module
++status.status-url = "/server-status"
++status.config-url = "/server-config"
++
--- ../lighttpd-1.4.11/tests/docroot/www/dummydir/.svn/entries 2006-03-09 19:21:49.000000000 +0200
-+++ lighttpd-1.4.12/tests/docroot/www/dummydir/.svn/entries 2006-07-15 22:43:22.000000000 +0300
++++ lighttpd-1.4.12/tests/docroot/www/dummydir/.svn/entries 2006-07-18 13:03:40.000000000 +0300
@@ -9,5 +9,6 @@
last-author="jan"
kind="dir"
uuid="152afb58-edef-0310-8abb-c4023f1b3aa9"
- revision="1040"/>
+ repos="svn://svn.lighttpd.net/lighttpd"
-+ revision="1173"/>
++ revision="1199"/>
</wc-entries>
--- ../lighttpd-1.4.11/tests/fastcgi-10.conf 2005-08-31 23:36:34.000000000 +0300
-+++ lighttpd-1.4.12/tests/fastcgi-10.conf 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/tests/fastcgi-10.conf 2006-07-16 00:26:04.000000000 +0300
@@ -1,12 +1,12 @@
-server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
}
--- ../lighttpd-1.4.11/tests/fastcgi-13.conf 2006-01-03 12:38:17.000000000 +0200
-+++ lighttpd-1.4.12/tests/fastcgi-13.conf 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/tests/fastcgi-13.conf 2006-07-18 13:03:40.000000000 +0300
@@ -1,5 +1,5 @@
-server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
compress.filetype = ("text/plain", "text/html")
fastcgi.debug = 0
+@@ -85,7 +85,7 @@
+ "grisu" => (
+ "host" => "127.0.0.1",
+ "port" => 1048,
+- "bin-path" => "/home/jan/Documents/php-5.1.0/sapi/cgi/php -c /usr/local/lib/php.ini",
++ "bin-path" => "/home/jan/Documents/php-5.1.4/sapi/cgi/php -c /usr/local/lib/php.ini",
+ "bin-copy-environment" => ( "PATH", "SHELL", "USER" ),
+ )
+ )
@@ -102,7 +102,7 @@
ssl.pemfile = "server.pem"
}
--- ../lighttpd-1.4.11/tests/fastcgi-auth.conf 2005-08-27 17:44:19.000000000 +0300
-+++ lighttpd-1.4.12/tests/fastcgi-auth.conf 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/tests/fastcgi-auth.conf 2006-07-16 00:26:05.000000000 +0300
@@ -1,5 +1,5 @@
-server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
}
--- ../lighttpd-1.4.11/tests/fastcgi-responder.conf 2005-08-27 17:44:19.000000000 +0300
-+++ lighttpd-1.4.12/tests/fastcgi-responder.conf 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/tests/fastcgi-responder.conf 2006-07-16 00:26:05.000000000 +0300
@@ -1,5 +1,5 @@
-server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
-server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
}
--- ../lighttpd-1.4.11/tests/fcgi-responder.c 2005-08-11 01:26:55.000000000 +0300
-+++ lighttpd-1.4.12/tests/fcgi-responder.c 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/tests/fcgi-responder.c 2006-07-16 00:26:05.000000000 +0300
@@ -6,11 +6,17 @@
int main () {
int num_requests = 2;
printf("Status: 200 OK\r\n\r\n");
num_requests--;
--- ../lighttpd-1.4.11/tests/lighttpd.conf 2006-03-09 15:26:58.000000000 +0200
-+++ lighttpd-1.4.12/tests/lighttpd.conf 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/tests/lighttpd.conf 2006-07-16 00:26:05.000000000 +0300
@@ -1,80 +1,18 @@
-debug.log-request-handling = "enable"
-debug.log-condition-handling = "enable"
}
--- ../lighttpd-1.4.11/tests/lowercase.conf 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.4.12/tests/lowercase.conf 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/tests/lowercase.conf 2006-07-16 00:26:05.000000000 +0300
@@ -0,0 +1,80 @@
+server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
+server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
+ static-file.exclude-extensions = ( ".jpg" )
+}
--- ../lighttpd-1.4.11/tests/lowercase.t 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.4.12/tests/lowercase.t 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/tests/lowercase.t 2006-07-16 00:26:05.000000000 +0300
@@ -0,0 +1,94 @@
+#!/usr/bin/env perl
+BEGIN {
+
+ok($tf->stop_proc == 0, "Stopping lighttpd");
+
+--- ../lighttpd-1.4.11/tests/mod-cgi.t 2005-09-01 14:43:05.000000000 +0300
++++ lighttpd-1.4.12/tests/mod-cgi.t 2006-07-18 13:03:40.000000000 +0300
+@@ -43,7 +43,7 @@
+ GET /nph-status.pl HTTP/1.0
+ EOF
+ );
+-$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
++$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 502 } ];
+ ok($tf->handle_http($t) == 0, 'NPH + perl, Bug #14');
+
+ $t->{REQUEST} = ( <<EOF
--- ../lighttpd-1.4.11/tests/mod-fastcgi.t 2006-03-09 15:30:45.000000000 +0200
-+++ lighttpd-1.4.12/tests/mod-fastcgi.t 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/tests/mod-fastcgi.t 2006-07-18 13:03:40.000000000 +0300
@@ -7,7 +7,7 @@
}
SKIP: {
- skip "no php found", 4 unless -x "/home/jan/Documents/php-5.1.0/sapi/cgi/php";
-+ skip "no php found", 4 unless -x "/home/jan/Documents/php-5.1.0/sapi/cgi/php";
++ skip "no php found", 4 unless -x "/home/jan/Documents/php-5.1.4/sapi/cgi/php";
$tf->{CONFIGFILE} = 'fastcgi-13.conf';
ok($tf->start_proc == 0, "Starting lighttpd with $tf->{CONFIGFILE}") or die();
$t->{REQUEST} = ( <<EOF
GET /index.fcgi?die-at-end HTTP/1.0
Host: www.example.org
--- ../lighttpd-1.4.11/tests/mod-proxy.t 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.4.12/tests/mod-proxy.t 2006-07-11 22:07:53.000000000 +0300
-@@ -0,0 +1,173 @@
++++ lighttpd-1.4.12/tests/mod-proxy.t 2006-07-18 13:03:40.000000000 +0300
+@@ -0,0 +1,175 @@
+#!/usr/bin/env perl
+BEGIN {
+ # add current source dir to the include-path
+## 1. the real webserver
+## 2. the proxy server
+
++SKIP: {
++ skip "disabled for now", 21;
+$tf_proxy->{PORT} = 2048;
+$tf_proxy->{CONFIGFILE} = 'proxy.conf';
+$tf_proxy->{LIGHTTPD_PIDFILE} = $tf_proxy->{SRCDIR}.'/tmp/lighttpd/lighttpd-proxy.pid';
+ok($tf_backend2->stop_proc == 0, "Stopping lighttpd");
+
+ok($tf_proxy->stop_proc == 0, "Stopping lighttpd proxy");
++}
+--- ../lighttpd-1.4.11/tests/proxy-backend-1.conf 1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/tests/proxy-backend-1.conf 2006-07-16 00:26:05.000000000 +0300
+@@ -0,0 +1,7 @@
++server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
++server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd-backend-1.pid"
++
++include "default.conf"
++
++
++server.tag = "proxy-backend-1"
+--- ../lighttpd-1.4.11/tests/proxy-backend-2.conf 1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/tests/proxy-backend-2.conf 2006-07-16 00:26:04.000000000 +0300
+@@ -0,0 +1,7 @@
++server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
++server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd-backend-2.pid"
++
++include "default.conf"
++
+
++server.tag = "proxy-backend-2"
--- ../lighttpd-1.4.11/tests/proxy.conf 1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.4.12/tests/proxy.conf 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/tests/proxy.conf 2006-07-16 00:26:05.000000000 +0300
@@ -0,0 +1,26 @@
+server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
+server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd-proxy.pid"
+}
+
--- ../lighttpd-1.4.11/tests/var-include.conf 2005-08-27 17:44:19.000000000 +0300
-+++ lighttpd-1.4.12/tests/var-include.conf 2006-07-11 22:07:53.000000000 +0300
++++ lighttpd-1.4.12/tests/var-include.conf 2006-07-16 00:26:05.000000000 +0300
@@ -2,15 +2,15 @@
debug.log-request-handling = "enable"
debug.log-condition-handling = "enable"