0
static VALUE sInternedKeys;
0
static VALUE sRackInput;
0
-#define
thin_connection_error(connection, msg) \
0
+#define
connection_error(connection, msg) \
0
rb_funcall(connection->backend->obj, rb_intern("log_error"), 1, \
0
rb_exc_new(rb_eRuntimeError, msg, strlen(msg))); \
0
-
thin_connection_close(connection)
0
+
connection_close(connection)
0
-#define thin_connection_errorno(connection) \
0
- thin_connection_error(connection, strerror(errno))
0
+#define connection_errorno(connection) \
0
+ connection_error(connection, strerror(errno))
0
-static void
thin_connection_closable_cb(EV_P_ struct ev_io *watcher, int revents)
0
+static void
connection_closable_cb(EV_P_ struct ev_io *watcher, int revents)
0
-
thin_connection_t *connection = get_ev_data(connection, watcher, write);
0
+
connection_t *connection = get_ev_data(connection, watcher, write);
0
-
thin_connection_close(connection);
0
+
connection_close(connection);
0
-static void
thin_connection_writable_cb(EV_P_ struct ev_io *watcher, int revents)
0
+static void
connection_writable_cb(EV_P_ struct ev_io *watcher, int revents)
0
-
thin_connection_t *connection = get_ev_data(connection, watcher, write);
0
+
connection_t *connection = get_ev_data(connection, watcher, write);
0
sent = send(connection->fd,
0
connection->write_buffer.current += sent;
0
-
thin_connection_errorno(connection);
0
+
connection_errorno(connection);
0
if (connection->write_buffer.current == connection->write_buffer.len) {
0
- watcher->cb =
thin_connection_closable_cb;
0
+ watcher->cb =
connection_closable_cb;
0
-static void
thin_connection_readable_cb(EV_P_ struct ev_io *watcher, int revents)
0
+static void
connection_readable_cb(EV_P_ struct ev_io *watcher, int revents)
0
-
thin_connection_t *connection = get_ev_data(connection, watcher, read);
0
+
connection_t *connection = get_ev_data(connection, watcher, read);
0
- char buf[
THIN_BUFFER_SIZE];
0
+ char buf[
BUFFER_SIZE];
0
- n = recv(connection->fd, buf,
THIN_BUFFER_SIZE, 0);
0
+ n = recv(connection->fd, buf,
BUFFER_SIZE, 0);
0
-
thin_connection_errorno(connection);
0
+
connection_errorno(connection);
0
-
thin_connection_parse(connection, buf, n);
0
+
connection_parse(connection, buf, n);
0
-void
thin_connection_start(thin_backend_t *backend, int fd, struct sockaddr_in remote_addr)
0
+void
connection_start(backend_t *backend, int fd, struct sockaddr_in remote_addr)
0
- thin_connection_t *connection = NULL;
0
- thin_connection_t *connections = backend->connections->items;
0
+ connection_t *connection = NULL;
0
+ connection_t *connections = backend->connections->items;
0
/* select the first closed connection */
0
/* no free connection found, add more */
0
if (connection == NULL) {
0
-
thin_connections_create(backend->connections, THIN_CONNECTIONS_SIZE);
0
+
connections_create(backend->connections, CONNECTIONS_SIZE);
0
connections = backend->connections->items;
0
/* FIXME: bug here on high concurrency, causes segfault on line 88 */
0
connection = &connections[++i];
0
connection->read_buffer.current = 0;
0
/* assign env[rack.input] */
0
- connection->input =
thin_input_new(&connection->read_buffer);
0
+ connection->input =
input_new(&connection->read_buffer);
0
rb_gc_register_address(&connection->input);
0
rb_hash_aset(connection->env, sRackInput, connection->input);
0
connection->parser.data = connection;
0
- watch(connection,
thin_connection_readable_cb, read, EV_READ);
0
+ watch(connection,
connection_readable_cb, read, EV_READ);
0
/* TODO add timeout watcher */
0
-void
thin_connection_parse(thin_connection_t *connection, char *buf, int len)
0
+void
connection_parse(connection_t *connection, char *buf, int len)
0
if (!http_parser_is_finished(&connection->parser)
0
- && connection->read_buffer.len + len > THIN_MAX_HEADER) {
0
- thin_connection_error(connection, "Header too big");
0
+ && connection->read_buffer.len + len > MAX_HEADER) {
0
+ connection_error(connection, "Header too big");
0
if (http_parser_has_error(&connection->parser)) {
0
-
thin_connection_error(connection, "Invalid request");
0
+
connection_error(connection, "Invalid request");
0
/* request fully received */
0
if (http_parser_is_finished(&connection->parser) && connection->read_buffer.len >= connection->content_length) {
0
unwatch(connection, read);
0
-
thin_connection_process(connection);
0
+
connection_process(connection);
0
-void
thin_connection_send_status(thin_connection_t *connection, const int status)
0
+void
connection_send_status(connection_t *connection, const int status)
0
- n = sprintf(connection->write_buffer.ptr, "HTTP/1.1 %s" CRLF,
thin_status(status));
0
+ n = sprintf(connection->write_buffer.ptr, "HTTP/1.1 %s" CRLF,
get_status_line(status));
0
connection->write_buffer.len = n;
0
-void
thin_connection_send_headers(thin_connection_t *connection, VALUE headers)
0
+void
connection_send_headers(connection_t *connection, VALUE headers)
0
VALUE hash, keys, key, value;
0
static VALUE iter_body(VALUE chunk, VALUE *val_conn)
0
-
thin_connection_t *conn = (thin_connection_t *) val_conn;
0
+
connection_t *conn = (connection_t *) val_conn;
0
size_t len = RSTRING_LEN(chunk);
0
memcpy(conn->write_buffer.ptr + conn->write_buffer.len, RSTRING_PTR(chunk), len);
0
-int
thin_connection_send_body(thin_connection_t *conn, VALUE body)
0
+int
connection_send_body(connection_t *conn, VALUE body)
0
if (TYPE(body) == T_STRING) {
0
/* Calling String#each creates several other strings which is slower and use more mem,
0
-void
thin_connection_process(thin_connection_t *connection)
0
+void
connection_process(connection_t *connection)
0
/* Call the app to process the request */
0
VALUE response = rb_funcall_rescue(connection->backend->app, sInternedCall, 1, connection->env);
0
if (response == Qundef) {
0
rb_funcall(connection->backend->obj, rb_intern("log_error"), 0);
0
-
thin_connection_close(connection);
0
+
connection_close(connection);
0
/* store response info and prepare for writing */
0
int status = FIX2INT(rb_ary_entry(response, 0));
0
VALUE body = rb_ary_entry(response, 2);
0
/* TODO grow buffer if too small */
0
- thin_connection_send_status(connection, status);
0
- thin_connection_send_headers(connection, headers);
0
- thin_connection_send_body(connection, body);
0
+ connection_send_status(connection, status);
0
+ connection_send_headers(connection, headers);
0
+ connection_send_body(connection, body);
0
- watch(connection,
thin_connection_writable_cb, write, EV_WRITE);
0
+ watch(connection,
connection_writable_cb, write, EV_WRITE);
0
-void
thin_connection_close(thin_connection_t *connection)
0
+void
connection_close(connection_t *connection)
0
unwatch(connection, read);
0
unwatch(connection, write);
0
-void
thin_connections_init()
0
+void
connections_init()
0
/* Intern some Ruby string */
0
sInternedCall = rb_intern("call");
0
sRackInput = rb_obj_freeze(rb_str_new2("rack.input"));
0
-void
thin_connections_create(array_t *connections, size_t num)
0
+void
connections_create(array_t *connections, size_t num)
0
-
thin_connection_t *connection;
0
+
connection_t *connection;
0
for (i = 0; i <= num; ++i) {
0
connection = array_push(connections);
0
-
thin_setup_parser_callbacks(connection);
0
+
parser_callbacks_setup(connection);