Add some TRACE messages
[MonkeyD.git] / src / connection.c
blob4bf825dcace1410a1ff54bd44c7dd33d8b129a6d
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /* Monkey HTTP Daemon
4 * ------------------
5 * Copyright (C) 2008, Eduardo Silva P.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Library General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include "monkey.h"
23 #include "http.h"
24 #include "connection.h"
25 #include "scheduler.h"
26 #include "epoll.h"
27 #include "request.h"
28 #include "socket.h"
29 #include "plugin.h"
30 #include "utils.h"
32 #include <string.h>
33 #include <stdio.h>
35 int mk_conn_read(int socket)
37 int ret;
38 struct client_request *cr;
39 struct sched_list_node *sched;
41 /* Plugin hook */
42 ret = mk_plugin_event_read(socket);
43 #ifdef TRACE
44 MK_TRACE("Check plugin hook | ret = %i", ret);
45 #endif
46 if (ret != MK_PLUGIN_RET_EVENT_NOT_ME) {
47 return ret;
50 sched = mk_sched_get_thread_conf();
52 cr = mk_request_client_get(socket);
53 if (!cr) {
54 /* Note: Linux don't set TCP_NODELAY socket flag by default,
55 * also we set the client socket on non-blocking mode
57 mk_socket_set_tcp_nodelay(socket);
58 mk_socket_set_nonblocking(socket);
60 cr = mk_request_client_create(socket);
62 /* Update requests counter */
63 mk_sched_update_thread_status(NULL,
64 MK_SCHEDULER_ACTIVE_UP,
65 MK_SCHEDULER_CLOSED_DOWN);
67 else {
68 /* If cr struct already exists, that could means that we
69 * are facing a keepalive connection, need to verify, if it
70 * applies we increase the thread status for active connections
72 if (cr->counter_connections > 1 && cr->body_length == 0) {
73 mk_sched_update_thread_status(NULL,
74 MK_SCHEDULER_ACTIVE_UP,
75 MK_SCHEDULER_CLOSED_NONE);
79 /* Read incomming data */
80 ret = mk_handler_read(socket, cr);
82 if (ret > 0) {
83 if (mk_http_pending_request(cr) == 0) {
84 mk_epoll_socket_change_mode(sched->epoll_fd,
85 socket, MK_EPOLL_WRITE);
87 else if (cr->body_length + 1 >= MAX_REQUEST_BODY) {
88 /* Request is incomplete and our buffer is full,
89 * close connection
91 mk_request_client_remove(socket);
92 return -1;
95 return ret;
98 int mk_conn_write(int socket)
100 int ret = -1, ka;
101 struct client_request *cr;
102 struct sched_list_node *sched;
104 /* Plugin hook */
105 ret = mk_plugin_event_write(socket);
106 #ifdef TRACE
107 MK_TRACE("Check plugin hook | ret = %i", ret);
108 #endif
109 if (ret != MK_PLUGIN_RET_EVENT_NOT_ME) {
110 return ret;
113 #ifdef TRACE
114 MK_TRACE("Normal connection write handling...");
115 #endif
117 sched = mk_sched_get_thread_conf();
118 mk_sched_update_conn_status(sched, socket, MK_SCHEDULER_CONN_PROCESS);
120 /* Get node from schedule list node which contains
121 * the information regarding to the current client/socket
123 cr = mk_request_client_get(socket);
125 if (!cr) {
126 return -1;
129 ret = mk_handler_write(socket, cr);
130 ka = mk_http_keepalive_check(socket, cr);
132 /* if ret < 0, means that some error
133 * happened in the writer call, in the
134 * other hand, 0 means a successful request
135 * processed, if ret > 0 means that some data
136 * still need to be send.
139 if (ret <= 0) {
140 mk_request_free_list(cr);
142 /* We need to ask to http_keepalive if this
143 * connection can continue working or we must
144 * close it.
147 mk_sched_update_thread_status(sched,
148 MK_SCHEDULER_ACTIVE_DOWN,
149 MK_SCHEDULER_CLOSED_UP);
151 if (ka < 0 || ret < 0) {
152 mk_request_client_remove(socket);
153 return -1;
155 else {
156 mk_request_ka_next(cr);
157 mk_epoll_socket_change_mode(sched->epoll_fd,
158 socket, MK_EPOLL_READ);
159 return 0;
162 else if (ret > 0) {
163 return 0;
166 /* avoid to make gcc cry :_( */
167 return -1;
170 int mk_conn_error(int socket)
172 struct client_request *cr;
173 struct sched_list_node *sched;
175 #ifdef TRACE
176 MK_TRACE("Connection Handler, error on FD %i", socket);
177 #endif
179 sched = mk_sched_get_thread_conf();
180 mk_sched_remove_client(NULL, socket);
181 cr = mk_request_client_get(socket);
182 if (cr) {
183 mk_request_client_remove(socket);
186 return 0;
189 int mk_conn_close(int socket)
191 struct sched_list_node *sched;
193 #ifdef TRACE
194 MK_TRACE("Connection Handler, closed on FD %i", socket);
195 #endif
197 sched = mk_sched_get_thread_conf();
198 mk_sched_remove_client(sched, socket);
200 return 0;
203 int mk_conn_timeout(int socket)
205 struct sched_list_node *sched;
207 #ifdef TRACE
208 MK_TRACE("Connection Handler, timeout on FD %i", socket);
209 #endif
211 sched = mk_sched_get_thread_conf();
212 mk_sched_check_timeouts(sched);
214 return 0;