Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial set of changes. This patch breaks the infrastructure of the

server core.
  • Loading branch information...
commit 648a4c1151dc2884a93e241cbd98c5fadb3821bb 1 parent 216073a
@alobbs alobbs authored
View
5 cherokee/Makefile.am
@@ -1578,6 +1578,11 @@ $(common_rrd_tools) \
request-protected.h \
request.h \
request.c \
+protocol.h \
+protocol_http.h \
+protocol_http.c \
+protocol_spdy.h \
+protocol_spdy.c \
connection.h \
connection.c \
connection-poll.h \
View
85 cherokee/connection.c
@@ -29,12 +29,27 @@
ret_t
cherokee_connection_init (cherokee_connection_t *conn)
{
- conn->keepalive = 0;
+ INIT_LIST_HEAD (&conn->list_entry);
+ INIT_LIST_HEAD (&conn->requests);
cherokee_socket_init (&conn->socket);
+ cherokee_protocol_init (&conn->protocol, conn);
cherokee_connection_poll_init (&conn->polling_aim);
- INIT_LIST_HEAD (&conn->requests);
+ conn->timeout = -1;
+ conn->timeout_lapse = -1;
+ conn->timeout_header = NULL;
+ conn->keepalive = 0;
+
+ conn->rx = 0;
+ conn->tx = 0;
+ conn->rx_partial = 0;
+ conn->tx_partial = 0;
+ conn->traffic_next = 0;
+
+ cherokee_buffer_init (&conn->buffer_in);
+ cherokee_buffer_init (&conn->buffer_out);
+
return ret_ok;
}
@@ -42,7 +57,7 @@ cherokee_connection_init (cherokee_connection_t *conn)
static void
reuse_requests (cherokee_connection_t *conn)
{
- cherokee_thread_t *thd = CONN_THREAD(conn);
+ cherokee_thread_t *thd = CONN_THREAD(conn);
cherokee_list_t *i, *tmp;
list_for_each_safe (i, tmp, &conn->requests) {
@@ -65,12 +80,17 @@ cherokee_connection_mrproper (cherokee_connection_t *conn)
cherokee_connection_poll_mrproper (&conn->polling_aim);
- /* Connection socket */
+ /* Properties */
cherokee_socket_mrproper (&conn->socket);
+ cherokee_protocol_mrproper (&conn->protocol);
/* Free requests */
reuse_requests (conn);
+ /* Buffers */
+ cherokee_buffer_mrproper (&conn->buffer_in);
+ cherokee_buffer_mrproper (&conn->buffer_out);
+
return ret_ok;
}
@@ -80,6 +100,9 @@ cherokee_connection_clean (cherokee_connection_t *conn)
{
cherokee_list_t *i, *tmp;
+ /* Item of a list */
+ INIT_LIST_ENTRY (&conn->list_entry);
+
/* Polling aim */
if (conn->polling_aim.fd != -1) {
cherokee_fd_close (conn->polling_aim.fd);
@@ -87,8 +110,62 @@ cherokee_connection_clean (cherokee_connection_t *conn)
cherokee_connection_poll_clean (&conn->polling_aim);
+ /* Socket */
+ cherokee_socket_close (&conn->socket);
+ cherokee_socket_clean (&conn->socket);
+
/* Free requests */
reuse_requests (conn);
+ /* Timeout */
+ conn->timeout = -1;
+ conn->timeout_lapse = -1;
+ conn->timeout_header = NULL;
+
+ /* Traffic */
+ conn->rx = 0;
+ conn->tx = 0;
+ conn->rx_partial = 0;
+ conn->tx_partial = 0;
+ conn->traffic_next = 0;
+
+ /* Buffers */
+ cherokee_buffer_clean (&conn->buffer_in);
+ cherokee_buffer_clean (&conn->buffer_out);
+
+ /* Protocol */
+ cherokee_protocol_clean (&conn->protocol);
+
return ret_ok;
}
+
+
+void
+cherokee_connection_rx_add (cherokee_connection_t *conn, ssize_t rx)
+{
+ if (likely (rx > 0)) {
+ conn->rx += rx;
+ conn->rx_partial += rx;
+ }
+}
+
+
+void
+cherokee_connection_tx_add (cherokee_connection_t *conn, ssize_t tx)
+{
+ cuint_t to_sleep;
+
+ /* Count it
+ */
+ conn->tx += tx;
+ conn->tx_partial += tx;
+
+ /* Traffic shaping
+ */
+ if (conn->limit_rate) {
+ to_sleep = (tx * 1000) / conn->limit_bps;
+
+ /* It's meant to sleep for a while */
+ conn->limit_blocked_until = cherokee_bogonow_msec + to_sleep;
+ }
+}
View
42 cherokee/connection.h
@@ -29,25 +29,55 @@
#include "buffer.h"
#include "socket.h"
#include "list.h"
+#include "protocol.h"
#include "connection-poll.h"
CHEROKEE_BEGIN_DECLS
typedef struct {
- cherokee_socket_t socket;
- uint32_t keepalive;
- cherokee_connection_pool_t polling_aim;
- cherokee_list_t requests;
-} cherokee_connection_t;
+ /* Inherits from list */
+ cherokee_list_t list_entry;
+
+ /* Pointers */
+ void *thread;
+
+ /* Properties */
+ cherokee_socket_t socket;
+ cherokee_protocol_t protocol;
+ cherokee_connection_pool_t polling_aim;
+ cherokee_list_t requests;
+
+ /* Timeout & Keep-alive */
+ time_t timeout;
+ time_t timeout_lapse;
+ cherokee_buffer_t *timeout_header;
+ uint32_t keepalive;
-#define CONN(c) ((cherokee_connection_t *)(c))
+ /* Buffers */
+ cherokee_buffer_t buffer_in;
+ cherokee_buffer_t buffer_out;
+ /* Traffic */
+ off_t rx; /* Bytes received */
+ size_t rx_partial; /* RX partial counter */
+ off_t tx; /* Bytes sent */
+ size_t tx_partial; /* TX partial counter */
+ time_t traffic_next; /* Time to update traffic */
+
+} cherokee_connection_t;
+
+#define CONN(c) ((cherokee_connection_t *)(c))
+#define CONN_THREAD(c) (CONN(c)->thread)
/* Public methods
*/
ret_t cherokee_connection_init (cherokee_connection_t *conn);
ret_t cherokee_connection_mrproper (cherokee_connection_t *conn);
+/* Transfers
+ */
+void cherokee_connection_rx_add (cherokee_connection_t *conn, ssize_t rx);
+void cherokee_connection_tx_add (cherokee_connection_t *conn, ssize_t tx);
CHEROKEE_END_DECLS
View
90 cherokee/protocol.c
@@ -0,0 +1,90 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/* Cherokee
+ *
+ * Authors:
+ * Alvaro Lopez Ortega <alvaro@alobbs.com>
+ *
+ * Copyright (C) 2001-2011 Alvaro Lopez Ortega
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include "common-internal.h"
+#include "protocol.h"
+#include "connection.h"
+
+ret_t
+cherokee_protocol_init (cherokee_protocol_t *proto, void *cnt)
+{
+ cherokee_connection_t *conn = CONN(cnt);
+
+ PROTOCOL_BASE(proto)->conn = cnt;
+ PROTOCOL_BASE(proto)->type = proto_unset;
+ PROTOCOL_BASE(proto)->buffer_in = conn->buffer_in;
+ PROTOCOL_BASE(proto)->buffer_out = conn->buffer_out;
+
+ return ret_ok;
+}
+
+
+ret_t
+cherokee_protocol_clean (cherokee_protocol_t *proto)
+{
+ PROTOCOL_BASE(proto)->type = proto_unset;
+ PROTOCOL_BASE(proto)->conn = NULL;
+ PROTOCOL_BASE(proto)->buffer_in = NULL;
+ PROTOCOL_BASE(proto)->buffer_out = NULL;
+
+ return ret_ok;
+}
+
+
+ret_t
+cherokee_protocol_mrproper (cherokee_protocol_t *proto)
+{
+ cherokee_protocol_clean (proto);
+ return ret_ok;
+}
+
+
+ret_t
+cherokee_protocol_set (cherokee_protocol_t *proto,
+ cherokee_protocol_type_t type)
+{
+ TRACE (ENTRIES, "Setting protocol: %s\n",
+ type == proto_http ? "HTTP" :
+ type == proto_spdy ? "SPDY" : "????");
+
+ PROTOCOL_BASE(proto)->type = type;
+ return ret_ok;
+}
+
+
+ret_t
+cherokee_protocol_dispatch (cherokee_protocol_t *proto)
+{
+ switch (PROTOCOL_BASE(proto)->type) {
+ case proto_http:
+ return cherokee_protocol_http_dispatch (proto);
+ case http_spdy:
+ return cherokee_protocol_spdy_dispatch (proto);
+ default:
+ break;
+ }
+
+ SHOULDNT_HAPPEN;
+ return ret_error;
+}
View
84 cherokee/protocol.h
@@ -0,0 +1,84 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/* Cherokee
+ *
+ * Authors:
+ * Alvaro Lopez Ortega <alvaro@alobbs.com>
+ *
+ * Copyright (C) 2001-2011 Alvaro Lopez Ortega
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef CHEROKEE_PROTOCOL_H
+#define CHEROKEE_PROTOCOL_H
+
+#include "buffer.h"
+#include "list.h"
+
+CHEROKEE_BEGIN_DECLS
+
+/* Protocol types */
+typedef enum {
+ proto_unset,
+ proto_http,
+ proto_spdy,
+} cherokee_protocol_type_t;
+
+/* Base class */
+typedef struct {
+ cherokee_protocol_type_t type;
+ void *conn;
+ cherokee_buffer_t *buffer_in;
+ cherokee_buffer_t *buffer_out;
+} cherokee_protocol_base_t;
+
+/* HTTP class
+ */
+typedef struct {
+ cherokee_protocol_base_t base;
+ int http;
+} cherokee_protocol_http_t;
+
+/* SPDY class
+ */
+typedef struct {
+ cherokee_protocol_base_t base;
+ int http;
+} cherokee_protocol_spdy_t;
+
+/* Union
+ */
+typedef union {
+ cherokee_protocol_http_t http;
+ cherokee_protocol_spdy_t spdy;
+} cherokee_protocol_t;
+
+#define PROTOCOL(p) ((cherokee_protocol_t *)(p))
+#define PROTOCOL_BASE(p) ((cherokee_protocol_base_t *)(p))
+#define PROTOCOL_HTTP(p) ((cherokee_protocol_http_t *)(p))
+#define PROTOCOL_SPDY(p) ((cherokee_protocol_spdy_t *)(p))
+
+/* Methods */
+ret_t cherokee_protocol_init (cherokee_protocol_t *proto, void *conn);
+ret_t cherokee_protocol_clean (cherokee_protocol_t *proto);
+ret_t cherokee_protocol_mrproper (cherokee_protocol_t *proto);
+
+ret_t cherokee_protocol_set (cherokee_protocol_t *proto, cherokee_protocol_type_t type);
+ret_t cherokee_protocol_dispatch (cherokee_protocol_t *proto);
+
+CHEROKEE_END_DECLS
+
+#endif /* CHEROKEE_PROTOCOL_H */
View
113 cherokee/protocol_http.c
@@ -0,0 +1,113 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/* Cherokee
+ *
+ * Authors:
+ * Alvaro Lopez Ortega <alvaro@alobbs.com>
+ *
+ * Copyright (C) 2001-2011 Alvaro Lopez Ortega
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include "common-internal.h"
+#include "protocol_http.h"
+
+ret_t
+cherokee_protocol_http_dispatch (cherokee_protocol_t *proto)
+{
+ size_t bytes = 0;
+ cherokee_connection_t *conn = CONN (PROTOCOL_BASE(proto)->conn);
+ cherokee_fdpoll_t *fdpoll = CONN_THREAD(conn)->fdpoll;
+ cherokee_connection_t *sock = SOCKET (&conn->socket);
+ cherokee_poll_mode_t mode = poll_mode_nothing;
+ cherokee_poll_mode_t mode_s = poll_mode_nothing;
+
+ /* Figure out the mode
+ */
+ if (! cherokee_buffer_is_empty (conn->buffer_out)) {
+ mode |= poll_mode_write;
+ }
+
+ mode_s = cherokee_fdpoll_check (fdpoll, conn->socket.socket);
+ if (mode_s & poll_mode_read) {
+ mode |= poll_mode_read;
+ }
+
+ /* Send
+ */
+ if (mode & poll_mode_write) {
+ /* Punch buffer in the socket */
+ ret = cherokee_socket_bufwrite (sock, conn->buffer_out, &bytes);
+
+ switch (ret) {
+ case ret_ok:
+ break;
+
+ case ret_eagain:
+ conn->polling_aim.fd = conn->socket.socket;
+ conn->polling_aim.mode = poll_mode_write;
+ goto receive;
+
+ default:
+ return ret;
+ }
+
+ /* Skip the chunk already sent */
+ cherokee_buffer_move_to_begin (conn->buffer_out, bytes);
+ }
+
+ /* Receive */
+receive:
+ if (mode & poll_mode_read) {
+ bytes = 0;
+
+ ret = cherokee_socket_bufread (sock, conn->buffer_in, to_read, &bytes);
+ switch (ret) {
+ case ret_ok:
+ cherokee_connection_rx_add (conn, cnt_read);
+ *len = cnt_read;
+ return ret_ok;
+
+ case ret_eof:
+ case ret_error:
+ return ret;
+
+ case ret_eagain:
+ if (cnt_read > 0) {
+ cherokee_connection_rx_add (conn, cnt_read);
+ *len = cnt_read;
+ return ret_ok;
+ }
+
+ conn->polling_aim.fd = conn->socket.socket;
+ conn->polling_aim.mode = poll_mode_read;
+
+ return ret_eagain;
+
+ default:
+ RET_UNKNOWN(ret);
+ return ret_error;
+ }
+
+
+ }
+
+
+ if (cherokee_connection_poll_is_set (&conn->polling_aim))
+ return ret_egain;
+
+ return ret_ok;
+}
View
36 cherokee/protocol_http.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/* Cherokee
+ *
+ * Authors:
+ * Alvaro Lopez Ortega <alvaro@alobbs.com>
+ *
+ * Copyright (C) 2001-2011 Alvaro Lopez Ortega
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef CHEROKEE_PROTOCOL_HTTP_H
+#define CHEROKEE_PROTOCOL_HTTP_H
+
+#include "protocol.h"
+
+CHEROKEE_BEGIN_DECLS
+
+ret_t cherokee_protocol_http_dispatch (cherokee_protocol_t *proto);
+
+CHEROKEE_END_DECLS
+
+#endif /* CHEROKEE_PROTOCOL_HTTP_H */
View
33 cherokee/protocol_spdy.c
@@ -0,0 +1,33 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/* Cherokee
+ *
+ * Authors:
+ * Alvaro Lopez Ortega <alvaro@alobbs.com>
+ *
+ * Copyright (C) 2001-2011 Alvaro Lopez Ortega
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include "common-internal.h"
+#include "protocol_spdy.h"
+
+
+ret_t
+cherokee_protocol_spdy_dispatch (cherokee_protocol_t *proto)
+{
+ return ret_ok;
+}
View
37 cherokee/protocol_spdy.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/* Cherokee
+ *
+ * Authors:
+ * Alvaro Lopez Ortega <alvaro@alobbs.com>
+ *
+ * Copyright (C) 2001-2011 Alvaro Lopez Ortega
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef CHEROKEE_PROTOCOL_SPDY_H
+#define CHEROKEE_PROTOCOL_SPDY_H
+
+#include "buffer.h"
+#include "list.h"
+
+CHEROKEE_BEGIN_DECLS
+
+ret_t cherokee_protocol_spdy_dispatch (cherokee_protocol_t *proto);
+
+CHEROKEE_END_DECLS
+
+#endif /* CHEROKEE_PROTOCOL_SPDY_H */
View
26 cherokee/request-protected.h
@@ -125,9 +125,8 @@ struct cherokee_request {
/* Buffers
*/
- cherokee_buffer_t incoming_header; /* -> header */
- cherokee_buffer_t header_buffer; /* <- header, -> post data */
- cherokee_buffer_t buffer; /* <- data */
+ /* cherokee_buffer_t header_buffer; /\* <- header, -> post data *\/ */
+ /* cherokee_buffer_t buffer; /\* <- data *\/ */
/* State
*/
@@ -140,6 +139,8 @@ struct cherokee_request {
/* Headers
*/
cherokee_header_t header;
+ cherokee_buffer_t header_buffer_in;
+ cherokee_buffer_t header_buffer_out;
/* Encoders
*/
@@ -171,24 +172,10 @@ struct cherokee_request {
cherokee_http_auth_t auth_type; /* Auth type of the resource */
cherokee_http_auth_t req_auth_type; /* Auth type of the request */
- /* Traffic
- */
- off_t rx; /* Bytes received */
- size_t rx_partial; /* RX partial counter */
- off_t tx; /* Bytes sent */
- size_t tx_partial; /* TX partial counter */
- time_t traffic_next; /* Time to update traffic */
-
/* Post info
*/
cherokee_post_t post;
- /* Net connection
- */
- time_t timeout;
- time_t timeout_lapse;
- cherokee_buffer_t *timeout_header;
-
/* Polling
*/
@@ -317,9 +304,4 @@ ret_t cherokee_request_log (cherokee_request_t *conn);
ret_t cherokee_request_update_vhost_traffic (cherokee_request_t *conn);
char *cherokee_request_print (cherokee_request_t *conn);
-/* Transfers
- */
-void cherokee_request_rx_add (cherokee_request_t *conn, ssize_t rx);
-void cherokee_request_tx_add (cherokee_request_t *conn, ssize_t tx);
-
#endif /* CHEROKEE_REQUEST_PROTECTED_H */
View
78 cherokee/request.c
@@ -117,9 +117,6 @@ cherokee_request_new (cherokee_request_t **req)
n->tx_partial = 0;
n->traffic_next = 0;
n->validator = NULL;
- n->timeout = -1;
- n->timeout_lapse = -1;
- n->timeout_header = NULL;
n->expiration = cherokee_expiration_none;
n->expiration_time = 0;
n->expiration_prop = cherokee_expiration_prop_none;
@@ -129,8 +126,7 @@ cherokee_request_new (cherokee_request_t **req)
n->limit_blocked_until = 0;
cherokee_buffer_init (&n->buffer);
- cherokee_buffer_init (&n->header_buffer);
- cherokee_buffer_init (&n->incoming_header);
+ cherokee_buffer_init (&n->header_buffer_out);
cherokee_buffer_init (&n->encoder_buffer);
cherokee_buffer_init (&n->logger_real_ip);
@@ -198,8 +194,8 @@ cherokee_request_free (cherokee_request_t *req)
cherokee_buffer_mrproper (&req->pathinfo);
cherokee_buffer_mrproper (&req->buffer);
- cherokee_buffer_mrproper (&req->header_buffer);
- cherokee_buffer_mrproper (&req->incoming_header);
+ cherokee_buffer_mrproper (&req->header_buffer_in);
+ cherokee_buffer_mrproper (&req->header_buffer_out);
cherokee_buffer_mrproper (&req->query_string);
cherokee_buffer_mrproper (&req->encoder_buffer);
@@ -337,6 +333,7 @@ cherokee_request_clean (cherokee_request_t *req,
cherokee_buffer_clean (&req->query_string);
cherokee_buffer_clean (&req->self_trace);
cherokee_buffer_clean (&req->chunked_len);
+ cherokee_buffer_clean (&req->header_buffer_out);
req->error_internal_code = http_unset;
cherokee_buffer_clean (&req->error_internal_url);
@@ -356,7 +353,6 @@ cherokee_request_clean (cherokee_request_t *req,
cherokee_header_clean (&req->header);
cherokee_buffer_clean (&req->buffer);
- cherokee_buffer_clean (&req->header_buffer);
if (reuse) {
/* Skip trailing CRLF (which may be sent by some HTTP clients)
@@ -365,15 +361,15 @@ cherokee_request_clean (cherokee_request_t *req,
* handled in next request. This may avoid a subsequent real
* move_to_begin of the contents left in the buffer.
*/
- crlf_len = cherokee_buffer_cnt_spn (&req->incoming_header, header_len, CRLF);
+ crlf_len = cherokee_buffer_cnt_spn (&req->header_buffer_in, header_len, CRLF);
header_len += (crlf_len <= MAX_HEADER_CRLF) ? crlf_len : 0;
- cherokee_buffer_move_to_begin (&req->incoming_header, header_len);
+ cherokee_buffer_move_to_begin (&req->header_buffer_in, header_len);
TRACE (ENTRIES, "conn %p, %s headers\n", req,
- !cherokee_buffer_is_empty (&req->incoming_header) ? "has" : "doesn't have");
+ !cherokee_buffer_is_empty (&req->header_buffer_in) ? "has" : "doesn't have");
} else {
- cherokee_buffer_clean (&req->incoming_header);
+ cherokee_buffer_clean (&req->header_buffer_in);
}
return ret_ok;
@@ -383,20 +379,26 @@ cherokee_request_clean (cherokee_request_t *req,
ret_t
cherokee_request_clean_close (cherokee_request_t *req)
{
- /* Close and clean the socket
- */
- cherokee_socket_close (&req->socket);
- cherokee_socket_clean (&req->socket);
+ // TODO: Implement properties clean
+ //
+ //
+ return ret_ok;
- /* Make sure the connection Keep-Alive is disabled
- */
- req->keepalive = 0;
- cherokee_buffer_clean (&req->incoming_header);
- /* Clean the connection object
- */
- cherokee_request_clean (req, false);
- return ret_ok;
+ /* /\* Close and clean the socket */
+ /* *\/ */
+ /* cherokee_socket_close (&req->socket); */
+ /* cherokee_socket_clean (&req->socket); */
+
+ /* /\* Make sure the connection Keep-Alive is disabled */
+ /* *\/ */
+ /* req->keepalive = 0; */
+ /* cherokee_buffer_clean (&req->incoming_header); */
+
+ /* /\* Clean the connection object */
+ /* *\/ */
+ /* cherokee_request_clean (req, false); */
+ /* return ret_ok; */
}
@@ -944,7 +946,7 @@ cherokee_request_build_header (cherokee_request_t *req)
/* Try to get the headers from the handler
*/
- ret = cherokee_handler_add_headers (req->handler, &req->header_buffer);
+ ret = cherokee_handler_add_headers (req->handler, &req->header_buffer_out);
if (unlikely (ret != ret_ok)) {
switch (ret) {
case ret_eof:
@@ -960,13 +962,13 @@ cherokee_request_build_header (cherokee_request_t *req)
/* Front-line Cache (in): Handler headers
*/
if (req->flcache.mode == flcache_mode_in) {
- cherokee_buffer_add_buffer (&req->flcache.header, &req->header_buffer);
+ cherokee_buffer_add_buffer (&req->flcache.header, &req->header_buffer_out);
/* Add X-Cache miss
*/
- cherokee_buffer_add_str (&req->header_buffer, "X-Cache: MISS from ");
- cherokee_request_build_host_port_string (req, &req->header_buffer);
- cherokee_buffer_add_str (&req->header_buffer, CRLF);
+ cherokee_buffer_add_str (&req->header_buffer_out, "X-Cache: MISS from ");
+ cherokee_request_build_host_port_string (req, &req->header_buffer_out);
+ cherokee_buffer_add_str (&req->header_buffer_out, CRLF);
}
/* Replies with no body cannot use chunked encoding
@@ -1008,7 +1010,7 @@ cherokee_request_build_header (cherokee_request_t *req)
/* Add handler headers
*/
- cherokee_buffer_add_buffer (&req->buffer, &req->header_buffer);
+ cherokee_buffer_add_buffer (&req->buffer, &req->header_buffer_out);
/* Add the server headers (phase 2)
*/
@@ -1202,7 +1204,7 @@ cherokee_request_reading_check (cherokee_request_t *req)
{
/* Check for too long headers
*/
- if (req->incoming_header.len > MAX_HEADER_LEN) {
+ if (req->header_buffer_in.len > MAX_HEADER_LEN) {
req->error_code = http_request_entity_too_large;
return ret_error;
}
@@ -2175,7 +2177,7 @@ cherokee_request_get_request (cherokee_request_t *req)
/* Header parsing
*/
- ret = cherokee_header_parse (&req->header, &req->incoming_header, &error_code);
+ ret = cherokee_header_parse (&req->header, &req->header_buffer_in, &error_code);
if (unlikely (ret < ret_ok)) {
goto error;
}
@@ -2696,7 +2698,7 @@ cherokee_request_open_request (cherokee_request_t *req)
/* Ensure the space for headers and I/O buffer
*/
- cherokee_buffer_ensure_size (&req->header_buffer, 384);
+ cherokee_buffer_ensure_size (&req->header_buffer_out, 384);
cherokee_buffer_ensure_size (&req->buffer, DEFAULT_READ_SIZE+1);
/* Init the connection handler object
@@ -2775,11 +2777,11 @@ cherokee_request_clean_error_headers (cherokee_request_t *req)
char *begin;
char *end;
- if (cherokee_buffer_is_empty (&req->header_buffer))
+ if (cherokee_buffer_is_empty (&req->header_buffer_out))
return ret_ok;
- begin = strncasestrn_s (req->header_buffer.buf,
- req->header_buffer.len,
+ begin = strncasestrn_s (req->header_buffer_out.buf,
+ req->header_buffer_out.len,
"Content-Length: ");
if (begin != NULL) {
end = strchr (begin+16, CHR_CR);
@@ -2789,8 +2791,8 @@ cherokee_request_clean_error_headers (cherokee_request_t *req)
if (end[1] == CHR_LF)
end++;
- cherokee_buffer_remove_chunk (&req->header_buffer,
- begin - req->header_buffer.buf,
+ cherokee_buffer_remove_chunk (&req->header_buffer_out,
+ begin - req->header_buffer_out.buf,
(end-begin)+1);
}
View
1,254 cherokee/thread.c
@@ -471,7 +471,7 @@ finalize_request (cherokee_thread_t *thread,
/* Update the timeout value
*/
- req->timeout = cherokee_bogonow_now + req->timeout_lapse;
+ conn->timeout = cherokee_bogonow_now + conn->timeout_lapse;
}
@@ -540,10 +540,10 @@ process_polling_connections (cherokee_thread_t *thd)
/* Has the connection expired?
*/
- if (req->timeout < cherokee_bogonow_now) {
+ if (conn->timeout < cherokee_bogonow_now) {
TRACE (ENTRIES",polling,timeout",
"processing polling conn (%p, %s): Time out\n",
- req, cherokee_request_get_phase_str (req));
+ conn, cherokee_request_get_phase_str (req));
/* Information collection
*/
@@ -629,12 +629,15 @@ process_polling_connections (cherokee_thread_t *thd)
static void
process_active_connections (cherokee_thread_t *thd)
{
- ret_t ret;
- off_t len;
- cherokee_list_t *i, *tmp;
- cherokee_request_t *req = NULL;
- cherokee_server_t *srv = SRV(thd->server);
- cherokee_socket_status_t blocking;
+ ret_t ret;
+ off_t len;
+ cherokee_list_t *i, *tmp1;
+ cherokee_list_t *j, *tmp2;
+ cherokee_request_t *req = NULL;
+ cherokee_connection_t *conn = NULL;
+ cherokee_virtual_server_t *vsrv = NULL;
+ cherokee_server_t *srv = SRV(thd->server);
+ cherokee_socket_status_t blocking;
#ifdef TRACE_ENABLED
if (cherokee_trace_is_tracing()) {
@@ -653,33 +656,21 @@ process_active_connections (cherokee_thread_t *thd)
/* Process active connections
*/
- list_for_each_safe (i, tmp, LIST(&thd->active_list)) {
- req = REQ(i);
-
- TRACE (ENTRIES, "processing conn (%p), phase %d '%s', socket=%d\n",
- req, req->phase, cherokee_request_get_phase_str (req), req->socket.socket);
+ list_for_each_safe (i, tmp1, LIST(&thd->active_list)) {
+ conn = CONN(i);
- /* Thread's properties
+ /* Thread property: Current connection
*/
- if (REQ_VSRV(req)) {
- /* Current connection
- */
- CHEROKEE_THREAD_PROP_SET (thread_connection_ptr, req);
+ CHEROKEE_THREAD_PROP_SET (thread_connection_ptr, conn);
+
- /* Error writer
- */
- if (REQ_VSRV(req)->error_writer) {
- CHEROKEE_THREAD_PROP_SET (thread_error_writer_ptr,
- REQ_VSRV(req)->error_writer);
- }
- }
/* Has the connection been too much time w/o any work
*/
- if (req->timeout < cherokee_bogonow_now) {
+ if (conn->timeout < cherokee_bogonow_now) {
TRACE (ENTRIES",polling,timeout",
"processing active conn (%p, %s): Time out\n",
- req, cherokee_request_get_phase_str (req));
+ conn, cherokee_request_get_phase_str (conn));
/* The lingering close timeout expired.
* Proceed to close the connection.
@@ -691,742 +682,785 @@ process_active_connections (cherokee_thread_t *thd)
continue;
}
- /* Information collection
- */
- if (THREAD_SRV(thd)->collector != NULL) {
- cherokee_collector_log_timeout (THREAD_SRV(thd)->collector);
- }
+ /* Information collection
+ */
+ if (THREAD_SRV(thd)->collector != NULL) {
+ cherokee_collector_log_timeout (THREAD_SRV(thd)->collector);
+ }
- goto shutdown;
- }
+ goto shutdown;
- /* Update the connection timeout
- */
- if ((req->phase != phase_tls_handshake) &&
- (req->phase != phase_reading_header) &&
- (req->phase != phase_reading_post) &&
- (req->phase != phase_shutdown) &&
- (req->phase != phase_lingering))
- {
- cherokee_request_update_timeout (req);
- }
- /* Maybe update traffic counters
- */
- if ((REQ_VSRV(req)->collector) &&
- (req->traffic_next < cherokee_bogonow_now) &&
- ((req->rx_partial != 0) || (req->tx_partial != 0)))
- {
- cherokee_request_update_vhost_traffic (req);
- }
- /* Traffic shaping limiter
- */
- if (req->limit_blocked_until > 0) {
- cherokee_thread_retire_active_connection (thd, req);
- cherokee_limiter_add_conn (&thd->limiter, req);
- continue;
- }
- TRACE (ENTRIES, "conn on phase n=%d: %s\n",
- req->phase, cherokee_request_get_phase_str (req));
- /* Phases
- */
- switch (req->phase) {
- case phase_tls_handshake:
- blocking = socket_closed;
-
- ret = cherokee_socket_init_tls (&req->socket, REQ_VSRV(req), req, &blocking);
- switch (ret) {
- case ret_eagain:
- switch (blocking) {
- case socket_reading:
- break;
- case socket_writing:
- break;
+ list_for_each_safe (j, tmp2, LIST(conn->requests)) {
+ req = REQ(i);
+ vsrv = REQ_VSRV(i);
- default:
- break;
- }
+ TRACE (ENTRIES, "processing req (c=%p,r=%p), phase %d '%s', socket=%d\n",
+ conn, req, req->phase, cherokee_request_get_phase_str (req), req->socket.socket);
- continue;
+ /* Thread properties: Current request
+ */
+ CHEROKEE_THREAD_PROP_SET (thread_request_ptr, req);
- case ret_ok:
- TRACE(ENTRIES, "Handshake %s\n", "finished");
+ /* Error writer */
+ if ((vsrv != NULL) && (vsrv->error_writer != NULL)) {
+ CHEROKEE_THREAD_PROP_SET (thread_error_writer_ptr, vsrv->error_writer);
+ }
- /* Set mode and update timeout
- */
- cherokee_request_update_timeout (req);
+ /* Has the connection been too much time w/o any work
+ */
+ if (conn->timeout < cherokee_bogonow_now) {
+ TRACE (ENTRIES",polling,timeout",
+ "processing active conn (%p, %s): Time out\n",
+ req, cherokee_request_get_phase_str (req));
- req->phase = phase_reading_header;
- break;
+ /* The lingering close timeout expired.
+ * Proceed to close the connection.
+ */
+ if ((req->phase == phase_shutdown) ||
+ (req->phase == phase_lingering))
+ {
+ close_active_connection (thd, req, false);
+ continue;
+ }
- case ret_eof:
- case ret_error:
- goto shutdown;
+ /* Information collection
+ */
+ if (THREAD_SRV(thd)->collector != NULL) {
+ cherokee_collector_log_timeout (THREAD_SRV(thd)->collector);
+ }
- default:
- RET_UNKNOWN(ret);
goto shutdown;
}
- break;
- case phase_reading_header:
- /* Maybe the buffer has a request (previous pipelined)
+ /* Update the connection timeout
*/
- if (! cherokee_buffer_is_empty (&req->incoming_header))
+ if ((req->phase != phase_tls_handshake) &&
+ (req->phase != phase_reading_header) &&
+ (req->phase != phase_reading_post) &&
+ (req->phase != phase_shutdown) &&
+ (req->phase != phase_lingering))
{
- ret = cherokee_header_has_header (&req->header,
- &req->incoming_header,
- req->incoming_header.len);
- switch (ret) {
- case ret_ok:
- goto phase_reading_header_EXIT;
- case ret_not_found:
- break;
- case ret_error:
- goto shutdown;
- default:
- RET_UNKNOWN(ret);
- goto shutdown;
- }
- }
-
- /* Read from the client
- */
- ret = cherokee_request_recv (req,
- &req->incoming_header,
- DEFAULT_RECV_SIZE, &len);
- switch (ret) {
- case ret_ok:
- break;
- case ret_eagain:
- cherokee_thread_deactive_to_polling (thd, req);
- continue;
- case ret_eof:
- case ret_error:
- goto shutdown;
- default:
- RET_UNKNOWN(ret);
- goto shutdown;
+ cherokee_request_update_timeout (req);
}
- /* Check security after read
+ /* Maybe update traffic counters
*/
- ret = cherokee_request_reading_check (req);
- if (ret != ret_ok) {
- req->keepalive = 0;
- req->phase = phase_setup_connection;
- req->header.version = http_version_11;
- continue;
+ if ((vsrv->collector) &&
+ (req->traffic_next < cherokee_bogonow_now) &&
+ ((req->rx_partial != 0) || (req->tx_partial != 0)))
+ {
+ cherokee_request_update_vhost_traffic (req);
}
- /* May it already has the full header
+ /* Traffic shaping limiter
*/
- ret = cherokee_header_has_header (&req->header, &req->incoming_header, len+4);
- switch (ret) {
- case ret_ok:
- break;
- case ret_not_found:
- req->phase = phase_reading_header;
+ if (req->limit_blocked_until > 0) {
+ cherokee_thread_retire_active_connection (thd, req);
+ cherokee_limiter_add_conn (&thd->limiter, req);
continue;
- case ret_error:
- goto shutdown;
- default:
- RET_UNKNOWN(ret);
- goto shutdown;
}
- /* fall down */
-
- phase_reading_header_EXIT:
- req->phase = phase_processing_header;
+ TRACE (ENTRIES, "conn on phase n=%d: %s\n",
+ req->phase, cherokee_request_get_phase_str (req));
- /* fall down */
-
- case phase_processing_header:
- /* Get the request
+ /* Phases
*/
- ret = cherokee_request_get_request (req);
- switch (ret) {
- case ret_ok:
- break;
+ switch (req->phase) {
+ case phase_tls_handshake:
+ blocking = socket_closed;
- case ret_eagain:
- continue;
+ ret = cherokee_socket_init_tls (&req->socket, vsrv, req, &blocking);
+ switch (ret) {
+ case ret_eagain:
+ switch (blocking) {
+ case socket_reading:
+ break;
- default:
- cherokee_request_setup_error_handler (req);
- continue;
- }
+ case socket_writing:
+ break;
- /* Thread's error logger
- */
- if (REQ_VSRV(req) &&
- REQ_VSRV(req)->error_writer)
- {
- CHEROKEE_THREAD_PROP_SET (thread_error_writer_ptr,
- REQ_VSRV(req)->error_writer);
- }
+ default:
+ break;
+ }
- /* Update timeout of the Keep-alive connections carried over..
- * The previous timeout was set to allow them to linger open
- * for a while. The new one is set to allow the server to serve
- * the new request.
- */
- if ((req->keepalive > 0) &&
- (req->keepalive < REQ_SRV(req)->keepalive_max))
- {
- cherokee_request_update_timeout (req);
- }
+ continue;
- /* Information collection
- */
- if (THREAD_SRV(thd)->collector != NULL) {
- cherokee_collector_log_request (THREAD_SRV(thd)->collector);
- }
+ case ret_ok:
+ TRACE(ENTRIES, "Handshake %s\n", "finished");
- req->phase = phase_setup_connection;
+ /* Set mode and update timeout
+ */
+ cherokee_request_update_timeout (req);
- /* fall down */
+ req->phase = phase_reading_header;
+ break;
- case phase_setup_connection: {
- cherokee_rule_list_t *rules;
- cherokee_boolean_t is_userdir;
+ case ret_eof:
+ case ret_error:
+ goto shutdown;
- /* HSTS support
- */
- if ((req->socket.is_tls != TLS) &&
- (REQ_VSRV(req)->hsts.enabled))
- {
- cherokee_request_setup_hsts_handler (req);
- continue;
- }
+ default:
+ RET_UNKNOWN(ret);
+ goto shutdown;
+ }
+ break;
- /* Is it already an error response?
- */
- if (http_type_300 (req->error_code) ||
- http_type_400 (req->error_code) ||
- http_type_500 (req->error_code))
- {
- cherokee_request_setup_error_handler (req);
- continue;
- }
+ case phase_reading_header:
+ /* Maybe the buffer has a request (previous pipelined)
+ */
+ if (! cherokee_buffer_is_empty (&req->incoming_header))
+ {
+ ret = cherokee_header_has_header (&req->header,
+ &req->incoming_header,
+ req->incoming_header.len);
+ switch (ret) {
+ case ret_ok:
+ goto phase_reading_header_EXIT;
+ case ret_not_found:
+ break;
+ case ret_error:
+ goto shutdown;
+ default:
+ RET_UNKNOWN(ret);
+ goto shutdown;
+ }
+ }
- /* Front-line cache
- */
- if ((REQ_VSRV(req)->flcache) &&
- (req->header.method == http_get))
- {
- TRACE (ENTRIES, "Front-line cache available: '%s'\n", REQ_VSRV(req)->name.buf);
+ /* Read from the client
+ */
+ ret = cherokee_request_recv (req,
+ &req->incoming_header,
+ DEFAULT_RECV_SIZE, &len);
+ switch (ret) {
+ case ret_ok:
+ break;
+ case ret_eagain:
+ cherokee_thread_deactive_to_polling (thd, req);
+ continue;
+ case ret_eof:
+ case ret_error:
+ goto shutdown;
+ default:
+ RET_UNKNOWN(ret);
+ goto shutdown;
+ }
- ret = cherokee_flcache_req_get_cached (REQ_VSRV(req)->flcache, req);
- if (ret == ret_ok) {
- /* Set Keepalive, Rate, and skip to add_headers
- */
- cherokee_request_set_keepalive (req);
- cherokee_request_set_rate (req, &req->config_entry);
+ /* Check security after read
+ */
+ ret = cherokee_request_reading_check (req);
+ if (ret != ret_ok) {
+ req->keepalive = 0;
+ req->phase = phase_setup_connection;
+ req->header.version = http_version_11;
+ continue;
+ }
- req->phase = phase_add_headers;
- goto add_headers;
+ /* May it already has the full header
+ */
+ ret = cherokee_header_has_header (&req->header, &req->incoming_header, len+4);
+ switch (ret) {
+ case ret_ok:
+ break;
+ case ret_not_found:
+ req->phase = phase_reading_header;
+ continue;
+ case ret_error:
+ goto shutdown;
+ default:
+ RET_UNKNOWN(ret);
+ goto shutdown;
}
- }
- TRACE (ENTRIES, "Setup connection begins: request=\"%s\"\n", req->request.buf);
- TRACE_REQ(req);
+ /* fall down */
- cherokee_config_entry_ref_clean (&req->config_entry);
+ phase_reading_header_EXIT:
+ req->phase = phase_processing_header;
- /* Choose the virtual entries table
- */
- is_userdir = ((REQ_VSRV(req)->userdir.len > 0) && (req->userdir.len > 0));
+ /* fall down */
- if (is_userdir) {
- rules = &REQ_VSRV(req)->userdir_rules;
- } else {
- rules = &REQ_VSRV(req)->rules;
- }
+ case phase_processing_header:
+ /* Get the request
+ */
+ ret = cherokee_request_get_request (req);
+ switch (ret) {
+ case ret_ok:
+ break;
- /* Local directory
- */
- if (cherokee_buffer_is_empty (&req->local_directory)) {
- if (is_userdir)
- ret = cherokee_request_build_local_directory_userdir (req, REQ_VSRV(req));
- else
- ret = cherokee_request_build_local_directory (req, REQ_VSRV(req));
- }
+ case ret_eagain:
+ continue;
- /* Check against the rule list. It fills out ->config_entry, and
- * req->auth_type
- * req->expiration*
- * req->timeout_*
- */
- ret = cherokee_rule_list_match (rules, req, &req->config_entry);
- if (unlikely (ret != ret_ok)) {
- cherokee_request_setup_error_handler (req);
- continue;
- }
+ default:
+ cherokee_request_setup_error_handler (req);
+ continue;
+ }
- /* Local directory
- */
- cherokee_request_set_custom_droot (req, &req->config_entry);
+ /* Thread's error logger
+ */
+ if (vsrv && vsrv->error_writer) {
+ CHEROKEE_THREAD_PROP_SET (thread_error_writer_ptr, vsrv->error_writer);
+ }
- /* Set the logger of the connection
- */
- if (req->config_entry.no_log != true) {
- req->logger_ref = REQ_VSRV(req)->logger;
- }
+ /* Update timeout of the Keep-alive connections carried over..
+ * The previous timeout was set to allow them to linger open
+ * for a while. The new one is set to allow the server to serve
+ * the new request.
+ */
+ if ((req->keepalive > 0) &&
+ (req->keepalive < REQ_SRV(req)->keepalive_max))
+ {
+ cherokee_request_update_timeout (req);
+ }
- /* Check of the HTTP method is supported by the handler
- */
- ret = cherokee_request_check_http_method (req, &req->config_entry);
- if (unlikely (ret != ret_ok)) {
- cherokee_request_setup_error_handler (req);
- continue;
- }
+ /* Information collection
+ */
+ if (THREAD_SRV(thd)->collector != NULL) {
+ cherokee_collector_log_request (THREAD_SRV(thd)->collector);
+ }
- /* Check Only-Secure connections
- */
- ret = cherokee_request_check_only_secure (req, &req->config_entry);
- if (unlikely (ret != ret_ok)) {
- cherokee_request_setup_error_handler (req);
- continue;
- }
+ req->phase = phase_setup_connection;
- /* Check for IP validation
- */
- ret = cherokee_request_check_ip_validation (req, &req->config_entry);
- if (unlikely (ret != ret_ok)) {
- cherokee_request_setup_error_handler (req);
- continue;
- }
+ /* fall down */
- /* Check for authentication
- */
- ret = cherokee_request_check_authentication (req, &req->config_entry);
- if (unlikely (ret != ret_ok)) {
- cherokee_request_setup_error_handler (req);
- continue;
- }
+ case phase_setup_connection: {
+ cherokee_rule_list_t *rules;
+ cherokee_boolean_t is_userdir;
- /* Update the keep-alive property
- */
- cherokee_request_set_keepalive (req);
+ /* HSTS support
+ */
+ if ((req->socket.is_tls != TLS) &&
+ (vsrv->hsts.enabled))
+ {
+ cherokee_request_setup_hsts_handler (req);
+ continue;
+ }
- /* Traffic Shaping
- */
- cherokee_request_set_rate (req, &req->config_entry);
+ /* Is it already an error response?
+ */
+ if (http_type_300 (req->error_code) ||
+ http_type_400 (req->error_code) ||
+ http_type_500 (req->error_code))
+ {
+ cherokee_request_setup_error_handler (req);
+ continue;
+ }
- /* Create the handler
- */
- ret = cherokee_request_create_handler (req, &req->config_entry);
- switch (ret) {
- case ret_ok:
- break;
- case ret_eagain:
- cherokee_request_clean_for_respin (req);
- continue;
- case ret_eof:
- /* Connection drop */
- close_active_connection (thd, req, true);
- continue;
- default:
- cherokee_request_setup_error_handler (req);
- continue;
- }
+ /* Front-line cache
+ */
+ if ((vsrv->flcache) &&
+ (req->header.method == http_get))
+ {
+ TRACE (ENTRIES, "Front-line cache available: '%s'\n", vsrv->name.buf);
+
+ ret = cherokee_flcache_req_get_cached (vsrv->flcache, req);
+ if (ret == ret_ok) {
+ /* Set Keepalive, Rate, and skip to add_headers
+ */
+ cherokee_request_set_keepalive (req);
+ cherokee_request_set_rate (req, &req->config_entry);
- /* Turn chunked encoding on, if possible
- */
- cherokee_request_set_chunked_encoding (req);
+ req->phase = phase_add_headers;
+ goto add_headers;
+ }
+ }
- /* Instance an encoder if needed
- */
- ret = cherokee_request_create_encoder (req, req->config_entry.encoders);
- if (unlikely (ret != ret_ok)) {
- cherokee_request_setup_error_handler (req);
- continue;
- }
+ TRACE (ENTRIES, "Setup connection begins: request=\"%s\"\n", req->request.buf);
+ TRACE_REQ(req);
- /* Parse the rest of headers
- */
- ret = cherokee_request_parse_range (req);
- if (unlikely (ret != ret_ok)) {
- cherokee_request_setup_error_handler (req);
- continue;
- }
+ cherokee_config_entry_ref_clean (&req->config_entry);
- /* Front-line cache
- */
- if ((REQ_VSRV(req)->flcache != NULL) &&
- (req->config_entry.flcache == true) &&
- (cherokee_flcache_req_is_storable (REQ_VSRV(req)->flcache, req) == ret_ok))
- {
- cherokee_flcache_req_set_store (REQ_VSRV(req)->flcache, req);
+ /* Choose the virtual entries table
+ */
+ is_userdir = ((vsrv->userdir.len > 0) && (req->userdir.len > 0));
+
+ if (is_userdir) {
+ rules = &vsrv->userdir_rules;
+ } else {
+ rules = &vsrv->rules;
+ }
- /* Update expiration
+ /* Local directory
*/
- if (req->flcache.mode == flcache_mode_in) {
- if (req->config_entry.expiration == cherokee_expiration_epoch) {
- req->flcache.avl_node_ref->valid_until = 0;
- } else if (req->config_entry.expiration == cherokee_expiration_time) {
- req->flcache.avl_node_ref->valid_until = cherokee_bogonow_now + req->config_entry.expiration_time;
- }
+ if (cherokee_buffer_is_empty (&req->local_directory)) {
+ if (is_userdir)
+ ret = cherokee_request_build_local_directory_userdir (req, vsrv);
+ else
+ ret = cherokee_request_build_local_directory (req, vsrv);
}
- }
- req->phase = phase_init;
- }
+ /* Check against the rule list. It fills out ->config_entry, and
+ * req->auth_type
+ * req->expiration*
+ * conn->timeout_*
+ */
+ ret = cherokee_rule_list_match (rules, req, &req->config_entry);
+ if (unlikely (ret != ret_ok)) {
+ cherokee_request_setup_error_handler (req);
+ continue;
+ }
- case phase_init:
- /* Look for the request
- */
- ret = cherokee_request_open_request (req);
- switch (ret) {
- case ret_ok:
- case ret_error:
- break;
+ /* Local directory
+ */
+ cherokee_request_set_custom_droot (req, &req->config_entry);
- case ret_eagain:
- continue;
+ /* Set the logger of the connection
+ */
+ if (req->config_entry.no_log != true) {
+ req->logger_ref = vsrv->logger;
+ }
- default:
- if ((MODULE(req->handler)->info) &&
- (MODULE(req->handler)->info->name))
- LOG_ERROR (CHEROKEE_ERROR_THREAD_HANDLER_RET,
- ret, MODULE(req->handler)->info->name);
- else
- RET_UNKNOWN(ret);
- break;
- }
-
- /* If it is an error, and the connection has not a handler to manage
- * this error, the handler has to be changed by an error_handler.
- */
- if (req->handler == NULL) {
- goto shutdown;
- }
+ /* Check of the HTTP method is supported by the handler
+ */
+ ret = cherokee_request_check_http_method (req, &req->config_entry);
+ if (unlikely (ret != ret_ok)) {
+ cherokee_request_setup_error_handler (req);
+ continue;
+ }
- if (http_type_300(req->error_code) ||
- http_type_400(req->error_code) ||
- http_type_500(req->error_code))
- {
- if (HANDLER_SUPPORTS (req->handler, hsupport_error)) {
- ret = cherokee_request_clean_error_headers (req);
- if (unlikely (ret != ret_ok)) {
- goto shutdown;
- }
- } else {
- /* Try to setup an error handler
- */
- ret = cherokee_request_setup_error_handler (req);
- if ((ret != ret_ok) &&
- (ret != ret_eagain))
- {
- /* Critical error: It couldn't instance the handler
- */
- goto shutdown;
- }
+ /* Check Only-Secure connections
+ */
+ ret = cherokee_request_check_only_secure (req, &req->config_entry);
+ if (unlikely (ret != ret_ok)) {
+ cherokee_request_setup_error_handler (req);
continue;
}
- }
- /* Figure next state
- */
- if (! (http_method_with_input (req->header.method) ||
- http_method_with_optional_input (req->header.method)))
- {
- req->phase = phase_add_headers;
- goto add_headers;
- }
+ /* Check for IP validation
+ */
+ ret = cherokee_request_check_ip_validation (req, &req->config_entry);
+ if (unlikely (ret != ret_ok)) {
+ cherokee_request_setup_error_handler (req);
+ continue;
+ }
- /* Register with the POST tracker
- */
- if ((srv->post_track) && (req->post.has_info)) {
- srv->post_track->func_register (srv->post_track, req);
- }
+ /* Check for authentication
+ */
+ ret = cherokee_request_check_authentication (req, &req->config_entry);
+ if (unlikely (ret != ret_ok)) {
+ cherokee_request_setup_error_handler (req);
+ continue;
+ }
- req->phase = phase_reading_post;
+ /* Update the keep-alive property
+ */
+ cherokee_request_set_keepalive (req);
- case phase_reading_post:
+ /* Traffic Shaping
+ */
+ cherokee_request_set_rate (req, &req->config_entry);
- /* Read/Send the POST info
- */
- ret = cherokee_request_read_post (req);
- switch (ret) {
- case ret_ok:
- break;
- case ret_eagain:
- if (cherokee_request_poll_is_set (&req->polling_aim)) {
- cherokee_thread_deactive_to_polling (thd, req);
+ /* Create the handler
+ */
+ ret = cherokee_request_create_handler (req, &req->config_entry);
+ switch (ret) {
+ case ret_ok:
+ break;
+ case ret_eagain:
+ cherokee_request_clean_for_respin (req);
+ continue;
+ case ret_eof:
+ /* Connection drop */
+ close_active_connection (thd, req, true);
+ continue;
+ default:
+ cherokee_request_setup_error_handler (req);
+ continue;
}
- continue;
- case ret_eof:
- case ret_error:
- req->error_code = http_internal_error;
- cherokee_request_setup_error_handler (req);
- continue;
- default:
- RET_UNKNOWN(ret);
- }
-
- /* Turn the connection in write mode
- */
- req->phase = phase_add_headers;
- case phase_add_headers:
- add_headers:
+ /* Turn chunked encoding on, if possible
+ */
+ cherokee_request_set_chunked_encoding (req);
- /* Build the header
- */
- ret = cherokee_request_build_header (req);
- switch (ret) {
- case ret_ok:
- break;
- case ret_eagain:
- if (cherokee_request_poll_is_set (&req->polling_aim)) {
- cherokee_thread_deactive_to_polling (thd, req);
+ /* Instance an encoder if needed
+ */
+ ret = cherokee_request_create_encoder (req, req->config_entry.encoders);
+ if (unlikely (ret != ret_ok)) {
+ cherokee_request_setup_error_handler (req);
+ continue;
}
- continue;
- case ret_eof:
- case ret_error:
- req->error_code = http_internal_error;
- cherokee_request_setup_error_handler (req);
- continue;
- default:
- RET_UNKNOWN(ret);
- }
- /* If it is an error, we have to respin the connection
- * to install a proper error handler.
- */
- if ((http_type_300 (req->error_code) ||
- http_type_400 (req->error_code) ||
- http_type_500 (req->error_code)) &&
- (!HANDLER_SUPPORTS (req->handler, hsupport_error))) {
- req->phase = phase_setup_connection;
- continue;
- }
+ /* Parse the rest of headers
+ */
+ ret = cherokee_request_parse_range (req);
+ if (unlikely (ret != ret_ok)) {
+ cherokee_request_setup_error_handler (req);
+ continue;
+ }
- /* If it has mmaped content, skip next stage
- */
- if (req->mmaped != NULL)
- goto phase_send_headers_EXIT;
+ /* Front-line cache
+ */
+ if ((vsrv->flcache != NULL) &&
+ (req->config_entry.flcache == true) &&
+ (cherokee_flcache_req_is_storable (vsrv->flcache, req) == ret_ok))
+ {
+ cherokee_flcache_req_set_store (vsrv->flcache, req);
- /* Front-line cache: store
- */
- if (req->flcache.mode == flcache_mode_in) {
- ret = cherokee_flcache_conn_commit_header (&req->flcache, req);
- if (ret != ret_ok) {
- /* Disabled Front-Line Cache */
- req->flcache.mode = flcache_mode_error;
+ /* Update expiration
+ */
+ if (req->flcache.mode == flcache_mode_in) {
+ if (req->config_entry.expiration == cherokee_expiration_epoch) {
+ req->flcache.avl_node_ref->valid_until = 0;
+ } else if (req->config_entry.expiration == cherokee_expiration_time) {
+ req->flcache.avl_node_ref->valid_until = cherokee_bogonow_now + req->config_entry.expiration_time;
+ }
+ }
}
+
+ req->phase = phase_init;
}
- req->phase = phase_send_headers;
+ case phase_init:
+ /* Look for the request
+ */
+ ret = cherokee_request_open_request (req);
+ switch (ret) {
+ case ret_ok:
+ case ret_error:
+ break;
- case phase_send_headers:
+ case ret_eagain:
+ continue;
- /* Send headers to the client
- */
- ret = cherokee_request_send_header (req);
- switch (ret) {
- case ret_eagain:
- cherokee_thread_deactive_to_polling (thd, req);
- continue;
+ default:
+ if ((MODULE(req->handler)->info) &&
+ (MODULE(req->handler)->info->name))
+ LOG_ERROR (CHEROKEE_ERROR_THREAD_HANDLER_RET,
+ ret, MODULE(req->handler)->info->name);
+ else
+ RET_UNKNOWN(ret);
+ break;
+ }
- case ret_ok:
- if (!http_method_with_body (req->header.method)) {
- finalize_request (thd, req);
- continue;
+ /* If it is an error, and the connection has not a handler to manage
+ * this error, the handler has to be changed by an error_handler.
+ */
+ if (req->handler == NULL) {
+ goto shutdown;
}
- if (!http_code_with_body (req->error_code)) {
- finalize_request (thd, req);
- continue;
+
+ if (http_type_300(req->error_code) ||
+ http_type_400(req->error_code) ||
+ http_type_500(req->error_code))
+ {
+ if (HANDLER_SUPPORTS (req->handler, hsupport_error)) {
+ ret = cherokee_request_clean_error_headers (req);
+ if (unlikely (ret != ret_ok)) {
+ goto shutdown;
+ }
+ } else {
+ /* Try to setup an error handler
+ */
+ ret = cherokee_request_setup_error_handler (req);
+ if ((ret != ret_ok) &&
+ (ret != ret_eagain))
+ {
+ /* Critical error: It couldn't instance the handler
+ */
+ goto shutdown;
+ }
+ continue;
+ }
}
- break;
- case ret_eof:
- case ret_error:
- goto shutdown;
+ /* Figure next state
+ */
+ if (! (http_method_with_input (req->header.method) ||
+ http_method_with_optional_input (req->header.method)))
+ {
+ req->phase = phase_add_headers;
+ goto add_headers;
+ }
- default:
- RET_UNKNOWN(ret);
- }
+ /* Register with the POST tracker
+ */
+ if ((srv->post_track) && (req->post.has_info)) {
+ srv->post_track->func_register (srv->post_track, req);
+ }
- phase_send_headers_EXIT:
- req->phase = phase_stepping;
+ req->phase = phase_reading_post;
- case phase_stepping:
+ case phase_reading_post:
- /* Special case:
- * If the content is mmap()ed, it has to send the header +
- * the file content and stop processing the connection.
- */
- if (req->mmaped != NULL) {
- ret = cherokee_request_send_header_and_mmaped (req);
+ /* Read/Send the POST info
+ */
+ ret = cherokee_request_read_post (req);
switch (ret) {
+ case ret_ok:
+ break;
case ret_eagain:
- cherokee_thread_deactive_to_polling (thd, req);
+ if (cherokee_request_poll_is_set (&req->polling_aim)) {
+ cherokee_thread_deactive_to_polling (thd, req);
+ }
continue;
-
case ret_eof:
- finalize_request (thd, req);
- continue;
-
case ret_error:
- close_active_connection (thd, req, true);
+ req->error_code = http_internal_error;
+ cherokee_request_setup_error_handler (req);
continue;
-
default:
- finalize_request (thd, req);
- continue;
+ RET_UNKNOWN(ret);
}
- }
- /* Handler step: read or make new data to send
- * Front-line cache handled internally.
- */
- ret = cherokee_request_step (req);
- switch (ret) {
- case ret_eagain:
- if (cherokee_request_poll_is_set (&req->polling_aim)) {
- cherokee_thread_deactive_to_polling (thd, req);
- }
- continue;
+ /* Turn the connection in write mode
+ */
+ req->phase = phase_add_headers;
- case ret_eof_have_data:
- ret = cherokee_request_send (req);
+ case phase_add_headers:
+ add_headers:
+ /* Build the header
+ */
+ ret = cherokee_request_build_header (req);
switch (ret) {
case ret_ok:
- finalize_request (thd, req);
- continue;
+ break;
case ret_eagain:
if (cherokee_request_poll_is_set (&req->polling_aim)) {
cherokee_thread_deactive_to_polling (thd, req);
}
- break;
+ continue;
case ret_eof:
case ret_error:
+ req->error_code = http_internal_error;
+ cherokee_request_setup_error_handler (req);
+ continue;
default:
- close_active_connection (thd, req, false);
+ RET_UNKNOWN(ret);
+ }
+
+ /* If it is an error, we have to respin the connection
+ * to install a proper error handler.
+ */
+ if ((http_type_300 (req->error_code) ||
+ http_type_400 (req->error_code) ||
+ http_type_500 (req->error_code)) &&
+ (!HANDLER_SUPPORTS (req->handler, hsupport_error))) {
+ req->phase = phase_setup_connection;
continue;
}
- break;
- case ret_ok:
- ret = cherokee_request_send (req);
+ /* If it has mmaped content, skip next stage
+ */
+ if (req->mmaped != NULL)
+ goto phase_send_headers_EXIT;
+ /* Front-line cache: store
+ */
+ if (req->flcache.mode == flcache_mode_in) {
+ ret = cherokee_flcache_conn_commit_header (&req->flcache, req);
+ if (ret != ret_ok) {
+ /* Disabled Front-Line Cache */
+ req->flcache.mode = flcache_mode_error;
+ }
+ }
+
+ req->phase = phase_send_headers;
+
+ case phase_send_headers:
+
+ /* Send headers to the client
+ */
+ ret = cherokee_request_send_header (req);
switch (ret) {
- case ret_ok:
- continue;
case ret_eagain:
- if (cherokee_request_poll_is_set (&req->polling_aim)) {
- cherokee_thread_deactive_to_polling (thd, req);
+ cherokee_thread_deactive_to_polling (thd, req);
+ continue;
+
+ case ret_ok:
+ if (!http_method_with_body (req->header.method)) {
+ finalize_request (thd, req);
+ continue;
+ }
+ if (!http_code_with_body (req->error_code)) {
+ finalize_request (thd, req);
+ continue;
}
break;
+
case ret_eof:
case ret_error:
+ goto shutdown;
+
default:
- close_active_connection (thd, req, false);
- continue;
+ RET_UNKNOWN(ret);
}
- break;
- case ret_ok_and_sent:
- break;
+ phase_send_headers_EXIT:
+ req->phase = phase_stepping;
- case ret_eof:
- finalize_request (thd, req);
- continue;
+ case phase_stepping:
- case ret_error:
- close_active_connection (thd, req, false);
- continue;
+ /* Special case:
+ * If the content is mmap()ed, it has to send the header +
+ * the file content and stop processing the connection.
+ */
+ if (req->mmaped != NULL) {
+ ret = cherokee_request_send_header_and_mmaped (req);
+ switch (ret) {
+ case ret_eagain:
+ cherokee_thread_deactive_to_polling (thd, req);
+ continue;
- default:
- RET_UNKNOWN(ret);
- goto shutdown;
- }
- break;
+ case ret_eof:
+ finalize_request (thd, req);
+ continue;
- shutdown:
- req->phase = phase_shutdown;
+ case ret_error:
+ close_active_connection (thd, req, true);
+ continue;
- case phase_shutdown:
- /* Perform a proper SSL/TLS shutdown
- */
- if (req->socket.is_tls == TLS) {
- ret = req->socket.cryptor->shutdown (req->socket.cryptor);
+ default:
+ finalize_request (thd, req);
+ continue;
+ }
+ }
+
+ /* Handler step: read or make new data to send
+ * Front-line cache handled internally.
+ */
+ ret = cherokee_request_step (req);
switch (ret) {
+ case ret_eagain:
+ if (cherokee_request_poll_is_set (&req->polling_aim)) {
+ cherokee_thread_deactive_to_polling (thd, req);
+ }
+ continue;
+
+ case ret_eof_have_data:
+ ret = cherokee_request_send (req);
+
+ switch (ret) {
+ case ret_ok:
+ finalize_request (thd, req);
+ continue;
+ case ret_eagain:
+ if (cherokee_request_poll_is_set (&req->polling_aim)) {
+ cherokee_thread_deactive_to_polling (thd, req);
+ }
+ break;
+ case ret_eof:
+ case ret_error:
+ default:
+ close_active_connection (thd, req, false);
+ continue;
+ }
+ break;
+
case ret_ok:
- case ret_eof:
- case ret_error:
+ ret = cherokee_request_send (req);
+
+ switch (ret) {
+ case ret_ok:
+ continue;
+ case ret_eagain:
+ if (cherokee_request_poll_is_set (&req->polling_aim)) {
+ cherokee_thread_deactive_to_polling (thd, req);
+ }
+ break;
+ case ret_eof:
+ case ret_error:
+ default:
+ close_active_connection (thd, req, false);
+ continue;
+ }
break;
- case ret_eagain:
- cherokee_thread_deactive_to_polling (thd, req);
+ case ret_ok_and_sent:
+ break;
+
+ case ret_eof:
+ finalize_request (thd, req);
continue;
- default:
- RET_UNKNOWN (ret);
+ case ret_error:
close_active_connection (thd, req, false);
continue;
+
+ default:
+ RET_UNKNOWN(ret);
+ goto shutdown;
}
- }
+ break;
- /* Shutdown socket for writing
- */
- ret = cherokee_request_shutdown_wr (req);
- switch (ret) {
- case ret_ok:
- /* Extend the timeout
- */
- req->timeout = cherokee_bogonow_now + SECONDS_TO_LINGER;
- TRACE (ENTRIES, "Lingering-close timeout = now + %d secs\n", SECONDS_TO_LINGER);
+ shutdown:
+ req->phase = phase_shutdown;
- /* Wait for the socket to be readable:
- * FIN + ACK will have arrived by then
+ case phase_shutdown:
+ /* Perform a proper SSL/TLS shutdown
*/
- req->phase = phase_lingering;
+ if (req->socket.is_tls == TLS) {
+ ret = req->socket.cryptor->shutdown (req->socket.cryptor);
+ switch (ret) {
+ case ret_ok:
+ case ret_eof:
+ case ret_error:
+ break;
+
+ case ret_eagain:
+ cherokee_thread_deactive_to_polling (thd, req);
+ continue;
- break;
- default:
- /* Error, no linger and no last read,
- * just close the connection.
+ default:
+ RET_UNKNOWN (ret);
+ close_active_connection (thd, req, false);
+ continue;
+ }
+ }
+
+ /* Shutdown socket for writing
*/
- close_active_connection (thd, req, true);
- continue;
- }
+ ret = cherokee_request_shutdown_wr (req);
+ switch (ret) {
+ case ret_ok:
+ /* Extend the timeout
+ */
+ conn->timeout = cherokee_bogonow_now + SECONDS_TO_LINGER;
+ TRACE (ENTRIES, "Lingering-close timeout = now + %d secs\n", SECONDS_TO_LINGER);
- /* fall down */
+ /* Wait for the socket to be readable:
+ * FIN + ACK will have arrived by then
+ */
+ req->phase = phase_lingering;
- case phase_lingering:
- ret = cherokee_request_linger_read (req);
- switch (ret) {
- case ret_ok:
- continue;
- case ret_eagain:
- cherokee_thread_deactive_to_polling (thd, req);
- continue;
- case ret_eof:
- case ret_error:
- close_active_connection (thd, req, false);
- continue;
- default:
- RET_UNKNOWN(ret);
- close_active_connection (thd, req, false);
- continue;
- }
- break;
+ break;
+ default:
+ /* Error, no linger and no last read,
+ * just close the connection.
+ */
+ close_active_connection (thd, req, true);
+ continue;
+ }
- default:
- SHOULDNT_HAPPEN;
- }
+ /* fall down */
+
+ case phase_lingering:
+ ret = cherokee_request_linger_read (req);
+ switch (ret) {
+ case ret_ok:
+ continue;
+ case ret_eagain:
+ cherokee_thread_deactive_to_polling (thd, req);
+ continue;
+ case ret_eof:
+ case ret_error:
+ close_active_connection (thd, req, false);
+ continue;
+ default:
+ RET_UNKNOWN(ret);
+ close_active_connection (thd, req, false);
+ continue;
+ }
+ break;
- } /* list */
+ default:
+ SHOULDNT_HAPPEN;
+ }
+ } /* list (req) */
+ } /* list (conn)*/
}
View
2  cherokee/threading.c
@@ -64,6 +64,7 @@ cherokee_threading_init (void)
#ifdef HAVE_PTHREAD
pthread_key_create (&thread_error_writer_ptr, NULL);
pthread_key_create (&thread_connection_ptr, NULL);
+ pthread_key_create (&thread_request_ptr, NULL);
#endif
return ret_ok;
@@ -83,6 +84,7 @@ cherokee_threading_free (void)
#ifdef HAVE_PTHREAD
pthread_key_delete (thread_error_writer_ptr);
pthread_key_delete (thread_connection_ptr);
+ pthread_key_delete (thread_request_ptr);
#endif
return ret_ok;
View
1  cherokee/threading.h
@@ -47,6 +47,7 @@ extern pthread_mutexattr_t cherokee_mutexattr_errorcheck;
extern pthread_key_t thread_error_writer_ptr;
extern pthread_key_t thread_connection_ptr;
+extern pthread_key_t thread_request_ptr;
/* Global if */
#endif
Please sign in to comment.
Something went wrong with that request. Please try again.