Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
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.