¡Hola!
This is yet another patch:
* manager:
- Init now requires a hostname, so that each manager will connect to a
specific fcgi-server
* handler
- Added "ServerList" directive in config file, typical use:
Extension fcgi {
Handler fastcgi {
ServerList /tmp/sock
ServerList 127.0.0.1:8090
ServerList 127.0.0.1:8070
}
}
Each entry will be assigned to a manager. Each request will be
round-robined through this array of managers.
I didn't use Server and Socket since they are string-typed directive.
Still not sure if this will be accepted.
- I also haven't touch interpreter part since it is string type
directive, so only one Interpreter will be allowed, I guess. Should each
(local) server requires separate Interpreter directive?
- Headers spewed by fcgi-server now consumed and parsed by the handler
so it will give the correct Status: and/or Location: value to main
server.
- SCRIPT_FILENAME is now sent by handler to fcgi-server so fcgi-server
can find the correct script name for dynamic fcgi requests (it works
with PHP5 now)
* some findings and thoughts:
- PHP sometimes close the connection on idle time.
- manager should be capable to reconnect automatically on
disconnections.
- the patch couldn't be tested with the latest svn up. The compilation
somehow breaks on:
/bin/sh ../libtool --tag=CC --mode=link gcc -g -O2 -o
cherokee_logrotate cherokee_logrotate.o libcherokee-config.la
libcherokee-base.la libcherokee-client.la -ldl
gcc -g -O2 -o .libs/cherokee_logrotate
cherokee_logrotate.o ./.libs/libcherokee-config.so ./.libs/libcherokee-base.so
./.libs/libcherokee-client.so -ldl -Wl,--rpath -Wl,/opt/ch/lib
/opt/ch/lib/libcherokee-server.so.0: undefined reference to
`cherokee_buffer_is_empty'
I tried to freshly svn co and still the problem exists, also some minor
stuff like undefined off_t and the needs to give --enable-trace
to ./configure
Please check whether I'm on a correct track.
Sorry that I'm being slower and slower, getting less leisure (read:
hacking) hour per week now *-(
Index: cherokee/fcgi_manager.c
===================================================================
--- cherokee/fcgi_manager.c (revision 105)
+++ cherokee/fcgi_manager.c (working copy)
@@ -22,7 +22,10 @@
* USA
*/
+#include "connection.h"
+#include "connection-protected.h"
#include "common-internal.h"
+#include "handler_fastcgi.h"
#include "fcgi_manager.h"
#include "fastcgi.h"
@@ -32,12 +35,14 @@
#define DEFAULT_PORT 8002
#define CONN_POLL_INCREMENT 16
+static pthread_mutex_t __global_fastcgi_manager_lock;
ret_t
-cherokee_fcgi_manager_new (cherokee_fcgi_manager_t **fcgim)
+cherokee_fcgi_manager_new (cherokee_fcgi_manager_t **fcgim, char *host)
{
int i;
ret_t ret;
+ char *port;
CHEROKEE_NEW_STRUCT (n,fcgi_manager);
/* Init
@@ -48,6 +53,8 @@
n->port = DEFAULT_PORT;
cherokee_buffer_init (&n->hostname);
cherokee_buffer_init (&n->read_buffer);
+ n->request_id = 0;
+ n->connected = -1;
cherokee_buffer_ensure_size (&n->read_buffer, DEFAULT_READ_SIZE);
@@ -55,13 +62,32 @@
n->conn_poll = (cherokee_connection_t **) malloc (
CONN_POLL_INCREMENT * sizeof(cherokee_connection_t *));
+ n->remaining_size = 0;
for (i=0; i<CONN_POLL_INCREMENT; i++) {
n->conn_poll[i] = NULL;
}
+ if (*host == '/') {
+ cherokee_buffer_add (&n->hostname, host, strlen(host));
+ } else {
+ /* Parse host name
+ */
+ port = strchr(host, ':');
+ if (port == NULL) {
+ cherokee_buffer_add (&n->hostname, host, strlen(host));
+ } else {
+ *port = '\0';
+ n->port = atoi(port+1);
+ cherokee_buffer_add (&n->hostname, host, port - host);
+ *port = ':';
+ }
+ }
+
/* Return
*/
*fcgim = n;
+
+ CHEROKEE_MUTEX_INIT(&__global_fastcgi_manager_lock, NULL);
return ret_ok;
}
@@ -92,36 +118,32 @@
{
ret_t ret;
- ret = cherokee_socket_set_client (fcgim->socket, AF_INET);
- if (ret != ret_ok) return ret;
+ if (*fcgim->hostname.buf == '/') {
+ ret = cherokee_socket_set_client (fcgim->socket, AF_UNIX);
+ if (ret != ret_ok) return ret;
+ ret = cherokee_socket_gethostbyname (fcgim->socket, &fcgim->hostname);
+ if (ret != ret_ok) return ret;
+ } else {
+ ret = cherokee_socket_set_client (fcgim->socket, AF_INET);
+ if (ret != ret_ok) return ret;
- ret = cherokee_socket_gethostbyname (fcgim->socket, &fcgim->hostname);
- if (ret != ret_ok) return ret;
+ ret = cherokee_socket_gethostbyname (fcgim->socket, &fcgim->hostname);
+ if (ret != ret_ok) return ret;
+ SOCKET_SIN_PORT(fcgim->socket) = htons(fcgim->port);
+ }
- SOCKET_SIN_PORT(fcgim->socket) = htons(fcgim->port);
+
- return cherokee_socket_connect (fcgim->socket);
+ fcgim->connected = cherokee_socket_connect (fcgim->socket);
+ return fcgim->connected;
}
ret_t
-cherokee_fcgi_manager_connect_to_srv (cherokee_fcgi_manager_t *fcgim, char *host)
+cherokee_fcgi_manager_connect_to_srv (cherokee_fcgi_manager_t *fcgim)
{
- char *port;
- ret_t ret;
+ ret_t ret;
- /* Parse host name
- */
- port = strchr(host, ':');
- if (port == NULL) {
- cherokee_buffer_add (&fcgim->hostname, host, strlen(host));
- } else {
- *port = '\0';
- fcgim->port = atoi(port+1);
- cherokee_buffer_add (&fcgim->hostname, host, port - host);
- *port = ':';
- }
-
/* Connect to the server
*/
ret = connect_to_fastcgi_server (fcgim);
@@ -178,7 +200,7 @@
{
cuint_t i;
cint_t slot = -1;
-
+
/* Look for the first free slot
*/
for (i=0; i<fcgim->conn_poll_size; i++) {
@@ -208,7 +230,7 @@
fcgim->conn_poll[slot] = conn;
printf ("registered id=%d\n", slot);
- *id = slot;
+ *id = slot + 1;
return ret_ok;
}
@@ -236,81 +258,234 @@
{
ret_t ret;
+ CHEROKEE_MUTEX_LOCK (&__global_fastcgi_manager_lock);
+ /*printf ("-----------------------write start--------------------------\n");*/
ret = cherokee_socket_write (fcgim->socket, info, sent);
- if (ret != ret_ok) return ret;
+ /*
+ cherokee_buffer_print_debug (info, -1);
+ printf ("-----------------------write end %d-%d-%d--------------------------\n", info->len, *sent, ret);*/
+ CHEROKEE_MUTEX_UNLOCK (&__global_fastcgi_manager_lock);
+ if (ret != ret_ok) {
+ if (ret == ret_eof)
+ fcgim->connected = -1;
+ return ret;
+ }
cherokee_buffer_move_to_begin (info, *sent);
return ret_ok;
}
+static void
+set_status (cherokee_fcgi_manager_t *fcgim, cherokee_fcgi_status_t status)
+{
+ cherokee_handler_fastcgi_t *fcgi;
+ cherokee_connection_t *conn;
+
+ conn = fcgim->conn_poll [fcgim->request_id - 1];
+ if (conn != NULL) {
+ fcgi = (cherokee_handler_fastcgi_t *) conn->handler;
+ if (fcgi != NULL) {
+ fcgi->status = status;
+ }
+ }
+}
+static void
+process_buffer (cherokee_fcgi_manager_t *fcgim, void *data, cuint_t data_len)
+{
+ cherokee_connection_t *conn;
+ cherokee_handler_fastcgi_t *fcgi;
+ char *message;
+
+ conn = fcgim->conn_poll [fcgim->request_id - 1];
+ if (conn == NULL)
+ {
+ return;
+ }
+
+ fcgi = (cherokee_handler_fastcgi_t *) conn->handler;
+ switch (fcgim->request_type)
+ {
+ case FCGI_STDERR:
+ message = (char*) strndup (data, data_len + 1);
+ message [data_len] = 0;
+ cherokee_logger_write_string (CONN_VSRV(conn)->logger, "%s", message);
+ free (message);
+ break;
+ case FCGI_STDOUT:
+ cherokee_buffer_add (&fcgi->incoming_buffer, data, data_len);
+ if (fcgim->remaining_size == 0)
+ set_status (fcgim, fcgi_data_available);
+ break;
+ }
+}
+
static ret_t
process_read_buffer (cherokee_fcgi_manager_t *fcgim)
{
- cuint_t offset;
- FCGI_Header *header;
-
- offset = 0;
- while (fcgim->read_buffer.len - offset >= sizeof(FCGI_EndRequestRecord))
- {
- cuint_t id;
- cuint_t len;
+ ret_t ret = ret_eagain;
+ cuint_t len, bytes_to_move, offset = 0;
+ FCGI_Header *header;
+ FCGI_EndRequestBody *end_request;
+ void *start = fcgim->read_buffer.buf;
- header = (FCGI_Header *)((&fcgim->read_buffer.buf) + offset);
- id = (header->requestIdB0 | (header->requestIdB1 << 8));
- len = (header->contentLengthB0 | (header->contentLengthB1 << 8)) + header->paddingLength;
+ while (fcgim->read_buffer.len > 0)
+ {
+ if (fcgim->remaining_size == 0) {
+ if (fcgim->read_buffer.len < sizeof(FCGI_Header))
+ return ret_eagain;
- switch (header->type) {
- case FCGI_STDERR:
- printf ("strerr\n");
- break;
- case FCGI_STDOUT:
- printf ("stdout\n");
- break;
- case FCGI_END_REQUEST:
- printf ("end request\n");
- break;
- default:
- PRINT_ERROR ("ERROR: Unknown FCGI header type: %d\n", header->type);
- }
+ header = (FCGI_Header *) start;
- offset += sizeof(FCGI_EndRequestRecord);
- }
+ if (!(header->type == FCGI_STDERR ||
+ header->type == FCGI_STDOUT ||
+ header->type == FCGI_END_REQUEST))
+ {
+ printf ("rb:%d x:%d rs:%d\n", fcgim->read_buffer.len, fcgim->padding, fcgim->remaining_size);
+ cherokee_buffer_print_debug (&fcgim->read_buffer, -1);
+ return ret_error;
+ }
- return ret_ok;
+ fcgim->request_id = (header->requestIdB0 | (header->requestIdB1 << 8));
+ fcgim->request_type = header->type;
+ len = (header->contentLengthB0 | (header->contentLengthB1 << 8));
+ fcgim->padding = header->paddingLength;
+ fcgim->return_value = 0;
+ fcgim->status = 0;
+
+ offset = FCGI_HEADER_LEN;
+ if (len > (fcgim->read_buffer.len - FCGI_HEADER_LEN))
+ {
+ fcgim->remaining_size = len - fcgim->read_buffer.len - FCGI_HEADER_LEN + 16;
+ len = fcgim->read_buffer.len - FCGI_HEADER_LEN;
+ bytes_to_move = len;
+ } else {
+ fcgim->remaining_size = 0;
+ bytes_to_move = len;
+ if ((fcgim->padding + len) > (fcgim->read_buffer.len - FCGI_HEADER_LEN)) {
+ fcgim->padding = (fcgim->padding + len) - fcgim->read_buffer.len - FCGI_HEADER_LEN;
+ bytes_to_move += fcgim->padding;
+ } else {
+ bytes_to_move += fcgim->padding;
+ fcgim->padding = 0;
+ }
+ }
+ bytes_to_move += FCGI_HEADER_LEN;
+ } else {
+ if (fcgim->remaining_size > fcgim->read_buffer.len) {
+ fcgim->remaining_size = fcgim->remaining_size - fcgim->read_buffer.len;
+ len = fcgim->read_buffer.len;
+ bytes_to_move = len;
+ } else {
+ len = fcgim->remaining_size;
+ bytes_to_move = len;
+ if (fcgim->padding > 0) {
+ if ((fcgim->remaining_size + fcgim->padding) > fcgim->read_buffer.len) {
+ fcgim->padding = fcgim->remaining_size + fcgim->padding - fcgim->read_buffer.len;
+ } else {
+ bytes_to_move += fcgim->padding;
+ fcgim->padding = 0;
+ }
+ }
+ fcgim->remaining_size = 0;
+ }
+ }
+
+ switch (fcgim->request_type) {
+ case FCGI_STDERR:
+ case FCGI_STDOUT:
+ if (len > 0)
+ process_buffer (fcgim, (start + offset), len);
+ break;
+ case FCGI_END_REQUEST:
+ end_request = (FCGI_EndRequestBody *) (start + offset);
+ fcgim->status = end_request->protocolStatus;
+ fcgim->return_value = end_request->appStatusB0 |
+ (end_request->appStatusB0 << 8) |
+ (end_request->appStatusB0 << 16) |
+ (end_request->appStatusB0 << 24);
+ set_status (fcgim, fcgi_data_completed);
+ break;
+ default:
+ PRINT_ERROR ("ERROR: Unknown FCGI header type: %X\n", header->type);
+ cherokee_buffer_print_debug (&fcgim->read_buffer, -1);
+ ret = ret_error;
+ }
+
+ cherokee_buffer_move_to_begin (&fcgim->read_buffer, bytes_to_move);
+
+ if (ret == ret_error)
+ break;
+ }
+
+ if (fcgim->read_buffer.len == 0)
+ cherokee_buffer_mrproper (&fcgim->read_buffer);
+
+ return ret;
}
-
ret_t
-cherokee_fcgi_manager_step (cherokee_fcgi_manager_t *fcgim)
+fcgi_manager_step (cherokee_fcgi_manager_t *fcgim, cuint_t id)
{
ret_t ret;
size_t size;
+ cherokee_connection_t *conn;
+ cherokee_handler_fastcgi_t *fcgi;
+
+ conn = fcgim->conn_poll [id - 1];
+ fcgi = (cherokee_handler_fastcgi_t *) conn->handler;
- /* Read from the FastCGI application
- */
- if (fcgim->read_buffer.len < sizeof(FCGI_Header))
- {
- ret = cherokee_socket_read (fcgim->socket, &fcgim->read_buffer, DEFAULT_READ_SIZE, &size);
- printf ("cherokee_fcgi_manager_step: _read %d\n", ret);
- if (ret != ret_ok) return ret;
- }
+ if (fcgi->status > fcgi_data_available)
+ return ret_ok;
- /* Process the information
- */
- if (fcgim->read_buffer.len >= sizeof(FCGI_Header))
- {
- ret = process_read_buffer (fcgim);
- printf ("cherokee_fcgi_manager_step: process %d\n", ret);
- return ret_ok;
- }
+ printf (" [reading start %d %d]\n" , id, fcgi->status);
+ while (1)
+ {
+ /* Read from the FastCGI application
+ */
+ if (fcgim->read_buffer.len < sizeof(FCGI_Header))
+ {
+ /*
+ printf (" [readin %d %d" , id, fcgi->status);*/
+ ret = cherokee_socket_read (fcgim->socket, &fcgim->read_buffer, DEFAULT_READ_SIZE, &size);
+ /*printf (" readout %d %d %d] ", id, ret, fcgim->remaining_size);
+ printf ("-----------------------read start--------------------------\n");
+ cherokee_buffer_print_debug (&fcgim->read_buffer, -1);
+ printf ("-----------------------read end %d %d--------------------------\n", size, ret);*/
+ if (ret != ret_ok) {
+ if (ret == ret_eof)
+ fcgim->connected = -1;
+ break;
+ }
+ }
- /* Read
- */
- return ret_eagain;
+ /* Process the information
+ */
+ ret = process_read_buffer (fcgim);
+
+ if (ret == ret_error)
+ break;
+
+ if (fcgim->remaining_size <= 0)
+ break;
+ }
+ /*
+ printf (" [reading result %d %d %d]\n" , id, fcgi->status, ret);*/
+
+ return ret;
}
+ret_t
+cherokee_fcgi_manager_step (cherokee_fcgi_manager_t *fcgim, cuint_t id)
+{
+ ret_t ret;
+ CHEROKEE_MUTEX_LOCK (&__global_fastcgi_manager_lock);
+ ret = fcgi_manager_step (fcgim, id);
+ CHEROKEE_MUTEX_UNLOCK (&__global_fastcgi_manager_lock);
+ return ret;
+}
+
ret_t
cherokee_fcgi_manager_add_conn (cherokee_fcgi_manager_t *fcgim, cherokee_connection_t *conn)
{
Index: cherokee/fcgi_manager.h
===================================================================
--- cherokee/fcgi_manager.h (revision 105)
+++ cherokee/fcgi_manager.h (working copy)
@@ -36,9 +36,19 @@
cherokee_socket_t *socket;
int port;
cherokee_buffer_t hostname;
+ int connected;
cherokee_buffer_t read_buffer;
+ int request_type;
+ cuint_t request_id;
+ cherokee_buffer_t request_buffer;
+ int return_value;
+ int status;
+
+ cuint_t padding;
+ cuint_t remaining_size;
+
/* Connections
*/
cherokee_connection_t **conn_poll;
@@ -47,16 +57,16 @@
} cherokee_fcgi_manager_t;
-ret_t cherokee_fcgi_manager_new (cherokee_fcgi_manager_t **fcgim);
+ret_t cherokee_fcgi_manager_new (cherokee_fcgi_manager_t **fcgim, char *host);
ret_t cherokee_fcgi_manager_free (cherokee_fcgi_manager_t *fcgim);
-ret_t cherokee_fcgi_manager_connect_to_srv (cherokee_fcgi_manager_t *fcgim, char *host);
+ret_t cherokee_fcgi_manager_connect_to_srv (cherokee_fcgi_manager_t *fcgim);
ret_t cherokee_fcgi_manager_spawn_srv (cherokee_fcgi_manager_t *fcgim, char *command);
ret_t cherokee_fcgi_manager_register_conn (cherokee_fcgi_manager_t *fcgim, cherokee_connection_t *conn, cuint_t *id);
ret_t cherokee_fcgi_manager_unregister_conn (cherokee_fcgi_manager_t *fcgim, cherokee_connection_t *conn);
-ret_t cherokee_fcgi_manager_step (cherokee_fcgi_manager_t *fcgim);
+ret_t cherokee_fcgi_manager_step (cherokee_fcgi_manager_t *fcgim, cuint_t);
ret_t cherokee_fcgi_manager_send (cherokee_fcgi_manager_t *fcgim, cherokee_buffer_t *info, size_t *sent);
ret_t cherokee_fcgi_manager_add_conn (cherokee_fcgi_manager_t *fcgim, cherokee_connection_t *conn);
Index: cherokee/macros.h
===================================================================
--- cherokee/macros.h (revision 105)
+++ cherokee/macros.h (working copy)
@@ -187,6 +187,7 @@
/* Tracing facility
*/
+#define TRACE_ENABLED
#ifdef TRACE_ENABLED
# define TRACE_ENV "CHEROKEE_TRACE"
@@ -241,10 +242,10 @@
# define FMT_OFFSET "%lu"
# define CST_OFFSET unsigned long
#else
-# error Unknown size of off_t
+# define FMT_OFFSET "%lu"
+# define CST_OFFSET unsigned long
#endif
-
#ifdef O_NOATIME
# define CHE_O_READ O_RDONLY | O_BINARY | O_NOATIME
#else
Index: cherokee/read_config_grammar.y
===================================================================
--- cherokee/read_config_grammar.y (revision 105)
+++ cherokee/read_config_grammar.y (working copy)
@@ -320,7 +320,7 @@
%token T_ICONS T_AUTH T_NAME T_METHOD T_PASSWDFILE T_SSL_CA_LIST_FILE T_FROM T_SOCKET T_LOG_FLUSH_INTERVAL
%token T_HEADERFILE T_PANIC_ACTION T_JUST_ABOUT T_LISTEN_QUEUE_SIZE T_SENDFILE T_MINSIZE T_MAXSIZE T_MAX_FDS
%token T_SHOW T_CHROOT T_ONLY_SECURE T_MAX_CONNECTION_REUSE T_REWRITE T_POLL_METHOD T_EXTENSION T_IPV6 T_ENV
-%token T_REQUEST
+%token T_SERVER_LIST T_REQUEST
%token <number> T_NUMBER T_PORT T_PORT_TLS
%token <string> T_QSTRING T_FULLDIR T_ID T_HTTP_URL T_HTTPS_URL T_HOSTNAME T_IP T_DOMAIN_NAME T_ADDRESS_PORT
@@ -1028,6 +1028,27 @@
}
}
+handler_option : T_SERVER_LIST str_type
+{
+ cherokee_table_t *properties;
+ list_t *plist = NULL;
+ list_t nlist = LIST_HEAD_INIT(nlist);
+
+ properties = current_config_entry->handler_properties;
+
+ if (properties != NULL) {
+ cherokee_typed_table_get_list (properties, "serverlist", &plist);
+ }
+
+ if (plist == NULL) {
+ cherokee_list_add (&nlist, $2);
+ cherokee_dirs_table_entry_set_prop (current_config_entry, "serverlist", typed_list, &nlist,
+ (cherokee_typed_free_func_t) cherokee_list_free_item_simple);
+ } else {
+ cherokee_list_add_tail (plist, $2);
+ }
+}
+
handler_option : T_SOCKET T_FULLDIR
{ dirs_table_set_handler_prop (current_config_entry, "socket", $2); };
Index: cherokee/buffer.c
===================================================================
--- cherokee/buffer.c (revision 105)
+++ cherokee/buffer.c (working copy)
@@ -568,6 +568,7 @@
cherokee_buffer_print_debug (cherokee_buffer_t *buf, int len)
{
int i, length;
+ char text[17];
if ((len == -1) || (buf->len <= len)) {
length = buf->len;
@@ -575,20 +576,24 @@
length = len;
}
-
+ text [16] = 0;
for (i=0; i < length; i++) {
if (i%16 == 0) {
printf ("%08x ", i);
}
printf ("%02x", buf->buf[i] & 0xFF);
+ if (buf->buf[i] > ' ' && buf->buf[i] < 128)
+ text [i%16] = (char) buf->buf[i];
+ else
+ text [i%16] = '.';
if ((i+1)%2 == 0) {
printf (" ");
}
if ((i+1)%16 == 0) {
- printf ("\n");
+ printf ("%s\n", text);
}
fflush(stdout);
Index: cherokee/Makefile.am
===================================================================
--- cherokee/Makefile.am (revision 105)
+++ cherokee/Makefile.am (working copy)
@@ -179,7 +179,7 @@
handler_fastcgi = \
$(common_cgi) \
-fastcgi.h \
+cgi.c cgi.h fastcgi.h \
handler_fastcgi.c \
handler_fastcgi.h \
fcgi_manager.h \
@@ -578,7 +578,6 @@
$(poll_port_src) \
$(poll_select_src) \
$(win32_src) \
-\
cherokee.h \
http.h \
http.c \
@@ -640,7 +639,6 @@
resolv_cache.c \
typed_table.h \
typed_table.c \
-\
mime_grammar.y \
mime_scanner.l
Index: cherokee/handler_fastcgi.c
===================================================================
--- cherokee/handler_fastcgi.c (revision 105)
+++ cherokee/handler_fastcgi.c (working copy)
@@ -22,14 +22,15 @@
* USA
*/
+#include "buffer.h"
#include "common-internal.h"
#include "handler_fastcgi.h"
#include "fastcgi.h"
#include "connection.h"
#include "connection-protected.h"
#include "thread.h"
+#include "list_ext.h"
-
cherokee_module_info_t cherokee_fastcgi_info = {
cherokee_handler, /* type */
cherokee_handler_fastcgi_new /* new func */
@@ -38,24 +39,23 @@
/* Global managers
*/
+static int __global_fastcgi_managers_index;
static cherokee_table_t *__global_fastcgi_managers;
#ifdef HAVE_PTHREAD
static pthread_mutex_t __global_fastcgi_managers_lock;
#endif
-
-
static void
fcgi_build_header (FCGI_Header *hdr, cuchar_t type, cushort_t request_id, cuint_t content_length, cuchar_t padding)
{
hdr->version = FCGI_VERSION_1;
hdr->type = type;
- hdr->requestIdB0 = (cuchar_t) request_id;
- hdr->requestIdB1 = (cuchar_t) (request_id >> 8) & 0xff;
- hdr->contentLengthB0 = (cuchar_t) (content_length % 256);
- hdr->contentLengthB1 = (cuchar_t) (content_length / 256);
+ hdr->requestIdB0 = (cuchar_t) request_id;
+ hdr->requestIdB1 = (cuchar_t) (request_id >> 8) & 0xff;
+ hdr->contentLengthB0 = (cuchar_t) (content_length % 256);
+ hdr->contentLengthB1 = (cuchar_t) (content_length / 256);
hdr->paddingLength = padding;
- hdr->reserved = 0;
+ hdr->reserved = 0;
}
static void
@@ -96,17 +96,15 @@
n->manager_ref = NULL;
n->host_ref = NULL;
n->interpreter_ref = NULL;
+ n->server_list = NULL;
- cherokee_buffer_init (&n->write_buffer);
- cherokee_buffer_init (&n->incoming_buffer);
- cherokee_buffer_init (&n->environment);
-
if (properties) {
- cherokee_typed_table_get_str (properties, "server", &n->host_ref);
+ cherokee_typed_table_get_list (properties, "serverlist", &n->server_list);
cherokee_typed_table_get_str (properties, "interpreter", &n->interpreter_ref);
}
- /* Return
+ n->max_manager = MAX (__global_fastcgi_managers_index, list_len (n->server_list));
+ /* Return
*/
*hdl = HANDLER(n);
return ret_ok;
@@ -118,6 +116,7 @@
{
cherokee_fcgi_manager_unregister_conn (hdl->manager_ref, HANDLER_CONN(hdl));
+ cherokee_buffer_mrproper (&hdl->data);
cherokee_buffer_mrproper (&hdl->write_buffer);
cherokee_buffer_mrproper (&hdl->incoming_buffer);
cherokee_buffer_mrproper (&hdl->environment);
@@ -125,34 +124,83 @@
return ret_ok;
}
+static void
+fixup_params (cherokee_buffer_t *buf, cuint_t id)
+{
+ char *byte, *end, *last_pad;
+ char padding [8] = {0, 0, 0, 0, 0, 0, 0, 0};
+ int length;
+ int crafted_id [2];
+ int pad;
+ if (buf->len == 0)
+ return;
+ end = buf->buf + buf->len;
+ crafted_id [0] = (cuchar_t) id;
+ crafted_id [1] = (cuchar_t) (id >> 8) & 0xff;
+ byte = (char*) buf->buf;
+ while (byte < end)
+ {
+ byte += 2;
+ if (*byte == (char) 0xFF)
+ *byte = crafted_id [1];
+ byte ++;
+ if (*byte == (char) 0xFF)
+ *byte = crafted_id [0];
+ byte ++;
+ length = (*byte << 8);
+ byte ++;
+ length |= *byte;
+ byte ++;
+ length += *byte;
+
+ last_pad = byte;
+ byte ++;
+ byte += (length + 1);
+ }
+
+
+ if ((buf->len % 8) != 0)
+ {
+ pad = 8 - (buf->len % 8);
+ cherokee_buffer_ensure_size (buf, buf->len + pad);
+
+ *last_pad = pad;
+ cherokee_buffer_add (buf, padding, pad);
+ }
+}
+
static void
add_env_pair (cherokee_buffer_t *buf,
char *key, int key_len,
char *val, int val_len)
{
+ FCGI_BeginRequestRecord request;
int len;
-
+
len = key_len + val_len;
- len += key_len > 127 ? 4 : 1;
- len += val_len > 127 ? 4 : 1;
+ len += key_len > 127 ? 4 : 1;
+ len += val_len > 127 ? 4 : 1;
- cherokee_buffer_ensure_size (buf, buf->len + key_len + val_len);
+ cherokee_buffer_ensure_size (buf, buf->len + key_len + val_len + sizeof(FCGI_Header));
+ fcgi_build_header (&request.header, FCGI_PARAMS, 0xFFFF, len, 0);
+ cherokee_buffer_add (buf, (void *)&request.header, sizeof(FCGI_Header));
+
if (key_len <= 127) {
buf->buf[buf->len++] = key_len;
- } else {
+ } else {
buf->buf[buf->len++] = ((key_len >> 24) & 0xff) | 0x80;
buf->buf[buf->len++] = (key_len >> 16) & 0xff;
buf->buf[buf->len++] = (key_len >> 8) & 0xff;
buf->buf[buf->len++] = (key_len >> 0) & 0xff;
- }
+ }
if (val_len <= 127) {
buf->buf[buf->len++] = val_len;
- } else {
+ } else {
buf->buf[buf->len++] = ((val_len >> 24) & 0xff) | 0x80;
buf->buf[buf->len++] = (val_len >> 16) & 0xff;
buf->buf[buf->len++] = (val_len >> 8) & 0xff;
@@ -163,45 +211,62 @@
cherokee_buffer_add (buf, val, val_len);
}
+static void
+add_more_env (cherokee_handler_fastcgi_t *fcgi, cherokee_buffer_t *buf)
+{
+ cherokee_connection_t *conn;
+ cherokee_buffer_t buffer = CHEROKEE_BUF_INIT;
+ int len;
+ conn = HANDLER_CONN(fcgi);
+ cherokee_buffer_add_buffer (&buffer, &conn->local_directory);
+
+ if (conn->request.len > 0) {
+ if (conn->request.buf [0] == '/') {
+ cherokee_buffer_add (&buffer, conn->request.buf + 1, conn->request.len - 1);
+ } else {
+ cherokee_buffer_add (&buffer, conn->request.buf, conn->request.len);
+ }
+ }
+
+ add_env_pair (buf,
+ "SCRIPT_FILENAME", 15,
+ buffer.buf, buffer.len);
+ cherokee_buffer_mrproper (&buffer);
+}
+
static ret_t
build_initial_packages (cherokee_handler_fastcgi_t *fcgi)
{
ret_t ret;
- cherokee_buffer_t tmp = CHEROKEE_BUF_INIT;
+ cherokee_buffer_t tmp = CHEROKEE_BUF_INIT, write_tmp = CHEROKEE_BUF_INIT;
cherokee_connection_t *conn;
FCGI_BeginRequestRecord request;
conn = HANDLER_CONN(fcgi);
-
/* FCGI_BEGIN_REQUEST
*/
fcgi_build_header (&request.header, FCGI_BEGIN_REQUEST, fcgi->id, sizeof(request.body), 0);
- fcgi_build_request_body (&request.body);
+ fcgi_build_request_body (&request);
cherokee_buffer_add (&fcgi->write_buffer, (void *)&request, sizeof(FCGI_BeginRequestRecord));
-
+
/* Add enviroment variables
- */
- ret = cherokee_cgi_build_basic_env (conn, (cherokee_cgi_set_env_pair_t) add_env_pair, &tmp, &fcgi->write_buffer);
- if (unlikely (ret != ret_ok)) return ret;
+ */
+ ret = cherokee_cgi_build_basic_env (conn, (cherokee_cgi_set_env_pair_t) add_env_pair, &tmp, &write_tmp);
+ if (unlikely (ret != ret_ok)) return ret;
+ add_more_env (fcgi, &write_tmp);
+ fixup_params (&write_tmp, fcgi->id);
+ cherokee_buffer_add_buffer (&fcgi->write_buffer, &write_tmp);
cherokee_buffer_mrproper (&tmp);
+ cherokee_buffer_mrproper (&write_tmp);
- fcgi_build_header (&request.header, FCGI_PARAMS, fcgi->id, tmp.size, 0);
- cherokee_buffer_add (&fcgi->write_buffer, (void *)&request.header, sizeof(FCGI_Header));
- cherokee_buffer_add_buffer (&fcgi->write_buffer, &tmp);
-
/* There aren't more parameters
*/
fcgi_build_header (&request.header, FCGI_PARAMS, fcgi->id, 0, 0);
cherokee_buffer_add (&fcgi->write_buffer, (void *)&request.header, sizeof(FCGI_Header));
- /* Stdin
- */
- fcgi_build_header (&request.header, FCGI_STDIN, fcgi->id, 0, 0);
- cherokee_buffer_add (&fcgi->write_buffer, (void *)&request.header, sizeof(FCGI_Header));
-
return ret_ok;
}
@@ -212,16 +277,41 @@
ret_t ret;
size_t sent = 0;
cherokee_connection_t *conn = HANDLER_CONN(fcgi);
+ list_t *list_tmp;
+ int i = 0;
- if (fcgi->host_ref == NULL) {
- PRINT_ERROR_S ("ERROR: FastCGI without Host\n");
- return ret_error;
- }
+ cherokee_buffer_init (&fcgi->write_buffer);
+ cherokee_buffer_init (&fcgi->incoming_buffer);
+ cherokee_buffer_init (&fcgi->data);
+ cherokee_buffer_init (&fcgi->environment);
+ fcgi->status = fcgi_data_unavailable;
+ fcgi->sending_phase = fcgi_sending_first_data;
/* Look for the FCGI managers table
*/
CHEROKEE_MUTEX_LOCK (&__global_fastcgi_managers_lock);
+
+ if (__global_fastcgi_managers_index > fcgi->max_manager)
+ __global_fastcgi_managers_index = fcgi->max_manager;
+ list_for_each (list_tmp, fcgi->server_list) {
+ char *host;
+
+ if (i < __global_fastcgi_managers_index) {
+ i ++;
+ continue;
+ } else {
+ fcgi->host_ref = LIST_ITEM_INFO (list_tmp);
+
+ __global_fastcgi_managers_index ++;
+
+ if (__global_fastcgi_managers_index >= fcgi->max_manager)
+ __global_fastcgi_managers_index = 0;
+
+ break;
+ }
+ }
+
ret = cherokee_table_get (__global_fastcgi_managers, fcgi->host_ref, (void **)&fcgi->manager_ref);
if (ret == ret_not_found) {
cherokee_fcgi_manager_t *n;
@@ -233,7 +323,7 @@
/* Create a new manager object
*/
- ret = cherokee_fcgi_manager_new (&n);
+ ret = cherokee_fcgi_manager_new (&n, fcgi->host_ref);
if (unlikely (ret != ret_ok)) return ret;
/* Assign the object to that path
@@ -244,19 +334,23 @@
/* Launch a new FastCGI server and connect to it
*/
- ret = cherokee_fcgi_manager_spawn_srv (n, fcgi->interpreter_ref);
- if (unlikely (ret != ret_ok)) return ret;
+
+ ret = cherokee_fcgi_manager_connect_to_srv (n);
+ if (unlikely (ret != ret_ok)) {
+ ret = cherokee_fcgi_manager_spawn_srv (n, fcgi->interpreter_ref);
+ if (unlikely (ret != ret_ok)) return ret;
- ret = cherokee_fcgi_manager_connect_to_srv (n, fcgi->host_ref);
- if (unlikely (ret != ret_ok)) return ret_error;
+ ret = cherokee_fcgi_manager_connect_to_srv (n);
+ if (unlikely (ret != ret_ok)) return ret_error;
+ }
}
CHEROKEE_MUTEX_UNLOCK (&__global_fastcgi_managers_lock);
-
/* Register this connection in the FastCGI manager
*/
ret = cherokee_fcgi_manager_register_conn (fcgi->manager_ref, conn, &fcgi->id);
+
if (unlikely (ret != ret_ok)) return ret;
/* Send the first packet
@@ -267,34 +361,84 @@
return ret_ok;
}
+static
+void
+complete_request (cherokee_handler_fastcgi_t *fcgi)
+{
+ FCGI_BeginRequestRecord request;
+
+ fcgi_build_header (&request.header, FCGI_STDIN, fcgi->id, 0, 0);
+ cherokee_buffer_add (&fcgi->write_buffer, (void *)&request.header, sizeof(FCGI_Header));
+ fcgi->sending_phase = fcgi_sending_data_finalized;
+}
+
+static
ret_t
-cherokee_handler_fastcgi_step (cherokee_handler_fastcgi_t *fcgi, cherokee_buffer_t *buffer)
+read_fcgi (cherokee_handler_fastcgi_t *fcgi)
{
- ret_t ret;
- size_t done;
+ ret_t ret = ret_eagain;
+ size_t size;
+ cherokee_fcgi_manager_t *fcgim;
+ cherokee_connection_t *conn;
+ cherokee_buffer_t post_buffer = CHEROKEE_BUF_INIT;
+ FCGI_BeginRequestRecord request;
- return_if_fail (fcgi->manager_ref != NULL, ret_error);
+ conn = HANDLER_CONN(fcgi);
+ fcgim = fcgi->manager_ref;
+
+ if (fcgi->sending_phase == fcgi_sending_first_data_completed)
+ {
+ if (! cherokee_post_is_empty (&conn->post)) {
+ cherokee_post_walk_reset (&conn->post);
+ fcgi->sending_phase = fcgi_sending_post_data;
+ }
+ }
- printf ("cherokee_handler_fastcgi_step: begin\n");
-
+ if (fcgi->sending_phase == fcgi_sending_post_data)
+ {
+ ret = cherokee_post_walk_read (&conn->post, &post_buffer, DEFAULT_READ_SIZE);
+ size = post_buffer.len;
+ if (size > 0)
+ {
+ fcgi_build_header (&request.header, FCGI_STDIN, fcgi->id, size, 0);
+ cherokee_buffer_add (&fcgi->write_buffer, (void *)&request.header, sizeof(FCGI_Header));
+ cherokee_buffer_add_buffer (&fcgi->write_buffer, &post_buffer);
+ cherokee_buffer_mrproper (&post_buffer);
+ }
+
+ if (ret == ret_ok)
+ {
+ fcgi->sending_phase = fcgi_sending_data_completed;
+ }
+ }
+
+ if (fcgi->sending_phase == fcgi_sending_first_data && cherokee_post_is_empty (&conn->post))
+ complete_request (fcgi);
+
+ if (fcgi->sending_phase == fcgi_sending_data_completed)
+ complete_request (fcgi);
+
/* It has something to send
*/
- if (! cherokee_buffer_is_empty (&fcgi->write_buffer)) {
- ret = cherokee_fcgi_manager_send (fcgi->manager_ref, &fcgi->write_buffer, &done);
- printf ("cherokee_handler_fastcgi_step: !empty, send: %d\n", ret);
+ if (! cherokee_buffer_is_empty (&fcgi->write_buffer)) {
+ ret = cherokee_fcgi_manager_send (fcgi->manager_ref, &fcgi->write_buffer, &size);
+
+ if (cherokee_buffer_is_empty (&fcgi->write_buffer)) {
+ cherokee_buffer_mrproper (&fcgi->write_buffer);
+ if (fcgi->sending_phase == fcgi_sending_first_data)
+ fcgi->sending_phase = fcgi_sending_first_data_completed;
+ }
switch (ret) {
case ret_ok:
- if (cherokee_buffer_is_empty (&fcgi->write_buffer))
- return ret_eagain;
+ break;
- return ret_ok;
-
case ret_eagain:
return ret_eagain;
case ret_eof:
+ break;
case ret_error:
return ret_error;
default:
@@ -302,22 +446,180 @@
}
}
+ if (fcgi->sending_phase < fcgi_sending_first_data_completed)
+ {
+ ret = ret_eagain;
+ } else {
+ ret = cherokee_fcgi_manager_step (fcgim, fcgi->id);
+ if (ret != ret_eof)
+ {
+ if (fcgi->status == fcgi_data_available || fcgi->status == fcgi_data_completed)
+ ret = ret_ok;
+ else
+ ret = ret_eagain;
+ } else {
+ if (fcgi->sending_phase <= fcgi_sending_first_data_completed) {
+
+ ret = ret_eagain;
+ }
+ }
+ }
+
+ return ret;
+}
+
+ret_t
+cherokee_handler_fastcgi_step (cherokee_handler_fastcgi_t *fcgi, cherokee_buffer_t *buffer)
+{
+ ret_t ret = ret_ok;
+
+ return_if_fail (buffer != NULL, ret_error);
+
+ if (!cherokee_buffer_is_empty (&fcgi->incoming_buffer))
+ {
+ cherokee_buffer_add_buffer (buffer, &fcgi->incoming_buffer);
+ cherokee_buffer_mrproper (&fcgi->incoming_buffer);
+ if (fcgi->status != fcgi_data_completed)
+ {
+ fcgi->status = fcgi_data_unavailable;
+ } else {
+ return ret_ok;
+ }
+ }
+
/* Lets read from the FastCGI server
- * As side effect it could update more connections in this call
*/
- ret = cherokee_fcgi_manager_step (fcgi->manager_ref);
- printf ("cherokee_handler_fastcgi_step: manager_step: %d\n", ret);
+ if (fcgi->status != fcgi_data_completed) {
+ ret = read_fcgi (fcgi);
+ if (ret == ret_ok) {
+ if (fcgi->status > fcgi_data_unavailable) {
+ cherokee_buffer_add_buffer (buffer, &fcgi->incoming_buffer);
+ cherokee_buffer_mrproper (&fcgi->incoming_buffer);
+ }
+ if (fcgi->status == fcgi_data_completed)
+ ret = ret_ok;
+ else {
+ fcgi->status = fcgi_data_unavailable;
+ ret = ret_eagain;
+ }
+ }
- // To continue..
+ } else {
+ ret = ret_ok;
+ }
- return ret_ok;
+ return ret;
}
+ret_t
+process_header (cherokee_handler_fastcgi_t *fcgi, cherokee_buffer_t *buf)
+{
+ cherokee_connection_t *conn = HANDLER_CONN(fcgi);
+ char *tmp, *end;
+ tmp = buf->buf;
+ while (1) {
+ if (tmp == NULL || *tmp == 0)
+ break;
+
+ end = strstr (tmp, CRLF);
+ if (end == NULL)
+ end = tmp + strlen (tmp);
+
+ if (strncmp (tmp, "Status: ", 8) == 0) {
+ int real_status;
+ char original_byte;
+
+ original_byte = *end;
+ *end = 0;
+ tmp += 8;
+ real_status = atoi (tmp);
+ *end = original_byte;
+
+ if (real_status <= 0) {
+ conn->error_code = http_internal_error;
+ return ret_error;
+ }
+ conn->error_code = real_status;
+ }
+ else if (strncmp (tmp, "Location: ", 10) == 0) {
+ tmp += 10;
+ cherokee_buffer_add (&conn->redirect, tmp, end - tmp);
+ }
+
+ tmp = end + (*end == 0 ? 0 : 2);
+ }
+
+ return ret_ok;
+}
+
+
ret_t
-cherokee_handler_fastcgi_add_headers (cherokee_handler_fastcgi_t *hdl, cherokee_buffer_t *buffer)
+cherokee_handler_fastcgi_add_headers (cherokee_handler_fastcgi_t *fcgi, cherokee_buffer_t *buffer)
{
- return ret_ok;
+ ret_t ret;
+
+ int len;
+ char *content;
+ int end_len;
+
+ /* Sanity check
+ */
+ return_if_fail (buffer != NULL, ret_error);
+
+ /* Read information from the FCGI
+ */
+ ret = read_fcgi (fcgi);
+
+ switch (ret) {
+ case ret_eof:
+ case ret_ok:
+ break;
+
+ case ret_error:
+ case ret_eagain:
+ return ret;
+
+ default:
+ RET_UNKNOWN(ret);
+ return ret_error;
+ }
+
+ if (fcgi->incoming_buffer.buf == NULL)
+ {
+ if (ret == ret_eof)
+ return ret_eof;
+ else
+ return ret_ok;
+ }
+
+ /* Look the end of headers
+ */
+ content = strstr (fcgi->incoming_buffer.buf, CRLF CRLF);
+ if (content != NULL) {
+ end_len = 4;
+ } else {
+ content = strstr (fcgi->incoming_buffer.buf, "\n\n");
+ end_len = 2;
+ }
+
+ if (content == NULL) {
+ return (ret == ret_eof) ? ret_eof : ret_eagain;
+ }
+
+ /* Copy the header
+ */
+ len = content - fcgi->incoming_buffer.buf;
+
+ cherokee_buffer_ensure_size (buffer, len+6);
+ cherokee_buffer_add (buffer, fcgi->incoming_buffer.buf, len);
+ cherokee_buffer_add (buffer, CRLF CRLF, 4);
+
+ /* Drop out the headers, we already have a copy
+ */
+ cherokee_buffer_move_to_begin (&fcgi->incoming_buffer, len + end_len);
+
+ return process_header (fcgi, buffer);
}
@@ -325,7 +627,7 @@
*/
void
-fastcgi_init (cherokee_module_loader_t *loader)
+cherokee_module_fastcgi_init (cherokee_module_loader_t *loader)
{
PRINT_ERROR_S ("WARNING: The FastCGI is under development, it isn't ready to be used!\n");
@@ -333,4 +635,5 @@
*/
cherokee_table_new (&__global_fastcgi_managers);
CHEROKEE_MUTEX_INIT(&__global_fastcgi_managers_lock, NULL);
+ __global_fastcgi_managers_index = 0;
}
Index: cherokee/handler_fastcgi.h
===================================================================
--- cherokee/handler_fastcgi.h (revision 105)
+++ cherokee/handler_fastcgi.h (working copy)
@@ -56,23 +56,42 @@
// struct sockaddr_un local;
} cherokee_fcgi_sockaddr_t;
+typedef enum {
+ fcgi_data_unavailable,
+ fcgi_data_available,
+ fcgi_data_completed,
+} cherokee_fcgi_status_t;
+typedef enum {
+ fcgi_sending_first_data,
+ fcgi_sending_first_data_completed,
+ fcgi_sending_post_data,
+ fcgi_sending_data_completed,
+ fcgi_sending_data_finalized
+} cherokee_fcgi_sending_phase_t;
+
+
typedef struct {
cherokee_handler_t handler;
/* FastCGI manager
*/
- cherokee_fcgi_manager_t *manager_ref;
- char *host_ref;
- char *interpreter_ref;
- cuint_t id;
+ cherokee_fcgi_manager_t *manager_ref;
+ char *host_ref;
+ char *interpreter_ref;
+ cuint_t id;
/* FastCGI protocol stuff
*/
- cherokee_buffer_t environment;
- cherokee_buffer_t write_buffer;
- cherokee_buffer_t incoming_buffer;
+ cherokee_buffer_t environment;
+ cherokee_buffer_t write_buffer;
+ cherokee_buffer_t incoming_buffer;
+ cherokee_buffer_t data;
+ cuint_t status;
+ cherokee_fcgi_sending_phase_t sending_phase;
+ list_t *server_list;
+ int max_manager;
} cherokee_handler_fastcgi_t;
#define FCGI(x) ((cherokee_handler_fastcgi_t *)(x))
Index: cherokee/post.c
===================================================================
--- cherokee/post.c (revision 105)
+++ cherokee/post.c (working copy)
@@ -260,19 +260,26 @@
case post_in_memory:
cherokee_buffer_add (buf, post->info.buf + post->walk_offset, len);
post->walk_offset += len;
- return ret_ok;
+ if (post->walk_offset > post->info.len)
+ return ret_ok;
+
+ return ret_eagain;
+
case post_in_tmp_file:
cherokee_buffer_ensure_size (buf, buf->len + len + 1);
ur = fread (buf->buf + buf->len, 1, len, post->tmp_file_p);
if (ur <= 0) {
- return (feof(post->tmp_file_p)) ? ret_eof : ret_error;
+ return (feof(post->tmp_file_p)) ? ret_ok : ret_error;
}
+
+ if (ur < len)
+ return ret_ok;
buf->len += ur;
buf->buf[buf->len] = '\0';
- return ret_ok;
+ return ret_eagain;
default:
SHOULDNT_HAPPEN;
Index: cherokee/read_config_scanner.l
===================================================================
--- cherokee/read_config_scanner.l (revision 105)
+++ cherokee/read_config_scanner.l (working copy)
@@ -113,6 +113,7 @@
"MaxConnectionReuse" { return T_MAX_CONNECTION_REUSE; }
"IOCache" { return T_IO_CACHE; }
"Env" { return T_ENV; }
+"ServerList" { return T_SERVER_LIST; }
"HeaderFile" { return T_HEADERFILE; }
"On" { yylval.number = 1; return T_NUMBER; }
"Off" { yylval.number = 0; return T_NUMBER; }
Index: cherokee/socket.c
===================================================================
--- cherokee/socket.c (revision 105)
+++ cherokee/socket.c (working copy)
@@ -1050,7 +1050,13 @@
ret_t
cherokee_socket_gethostbyname (cherokee_socket_t *socket, cherokee_buffer_t *hostname)
{
- return cherokee_gethostbyname (hostname->buf, &SOCKET_SIN_ADDR(socket));
+ if (SOCKET_AF(socket) == AF_UNIX) {
+ SOCKET_ADDR_UNIX(socket).sun_family = AF_UNIX;
+ memset ((char*) SOCKET_SUN_PATH (socket), 0, sizeof (SOCKET_ADDR_UNIX(socket)));
+ strncpy (SOCKET_SUN_PATH (socket), hostname->buf, hostname->len);
+ return ret_ok;
+ } else
+ return cherokee_gethostbyname (hostname->buf, &SOCKET_SIN_ADDR(socket));
}
@@ -1060,7 +1066,10 @@
{
int r;
- r = connect (SOCKET_FD(socket), (struct sockaddr *) &SOCKET_ADDR(socket), sizeof(cherokee_sockaddr_t));
+ if (SOCKET_AF(socket) == AF_UNIX)
+ r = connect (SOCKET_FD(socket), (struct sockaddr *) &SOCKET_ADDR_UNIX(socket), sizeof(SOCKET_ADDR_UNIX(socket)));
+ else
+ r = connect (SOCKET_FD(socket), (struct sockaddr *) &SOCKET_ADDR(socket), sizeof(cherokee_sockaddr_t));
if (r < 0) {
int err = SOCK_ERRNO();
Index: cherokee/socket.h
===================================================================
--- cherokee/socket.h (revision 105)
+++ cherokee/socket.h (working copy)
@@ -43,6 +43,7 @@
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
+# include <sys/un.h>
#endif
#ifdef HAVE_ARPA_INET_H
@@ -100,6 +101,7 @@
typedef union {
struct sockaddr sa;
struct sockaddr_in sa_in;
+ struct sockaddr_un sa_un;
#ifdef HAVE_SOCKADDR_IN6
struct sockaddr_in6 sa_in6;
#endif
@@ -140,12 +142,14 @@
#define SOCKET_FD(s) (SOCKET(s)->socket)
#define SOCKET_AF(s) (SOCKET(s)->client_addr.sa.sa_family)
#define SOCKET_ADDR(s) (SOCKET(s)->client_addr)
+#define SOCKET_ADDR_UNIX(s) (SOCKET(s)->client_addr.sa_un)
#define SOCKET_ADDR_IPv4(s) ((struct sockaddr_in *)&SOCKET(s)->client_addr)
#define SOCKET_ADDR_IPv6(s) ((struct sockaddr_in6 *)&SOCKET(s)->client_addr)
#define SOCKET_STATUS(s) (SOCKET(s)->status)
#define SOCKET_SIN_PORT(s) (SOCKET(s)->client_addr.sa_in.sin_port)
#define SOCKET_SIN_ADDR(s) (SOCKET(s)->client_addr.sa_in.sin_addr)
+#define SOCKET_SUN_PATH(s) (SOCKET(s)->client_addr.sa_un.sun_path)
#define SOCKET_ADDRESS_IPv4(s) (SOCKET_ADDR_IPv4(s)->sin_addr.s_addr)
#define SOCKET_ADDRESS_IPv6(s) (SOCKET_ADDR_IPv6(s)->sin6_addr.s6_addr)
Index: Makefile.am
===================================================================
--- Makefile.am (revision 105)
+++ Makefile.am (working copy)
@@ -1,6 +1,6 @@
## Cherokee: Makefile.am -*- makefile -*-
-SUBDIRS = m4 contrib www doc icons qa cherokee cget
+SUBDIRS = m4 contrib www icons qa cherokee cget
bin_SCRIPTS = cherokee-config
SUFFIXES = .sample.pre .sample
_______________________________________________
Cherokee mailing list
[email protected]
http://www.alobbs.com/cgi-bin/mailman/listinfo/cherokee