Request buffer size now is dynamic :)
[MonkeyD.git] / src / connection.c
blob9bbc03a40e259906710affc1d6bd2fd8fe03fa29
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /* Monkey HTTP Daemon
4 * ------------------
5 * Copyright (C) 2001-2010, Eduardo Silva P. <edsiper@gmail.com>
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 #ifdef TRACE
42 MK_TRACE("Connection Handler, read on FD %i", socket);
43 #endif
45 /* Plugin hook */
46 ret = mk_plugin_event_read(socket);
47 if (ret != MK_PLUGIN_RET_EVENT_NOT_ME) {
48 if (ret == MK_PLUGIN_RET_END || ret == MK_PLUGIN_RET_CLOSE_CONX){
49 return -1;
51 return ret;
54 sched = mk_sched_get_thread_conf();
56 cr = mk_request_client_get(socket);
57 if (!cr) {
58 /* Note: Linux don't set TCP_NODELAY socket flag by default,
60 mk_socket_set_tcp_nodelay(socket);
62 /* Create client */
63 cr = mk_request_client_create(socket);
66 /* Read incomming data */
67 ret = mk_handler_read(socket, cr);
69 if (ret > 0) {
70 if (mk_http_pending_request(cr) == 0) {
71 mk_epoll_change_mode(sched->epoll_fd,
72 socket, MK_EPOLL_WRITE);
74 else if (cr->body_length + 1 >= config->max_request_size) {
75 /* Request is incomplete and our buffer is full,
76 * close connection
78 mk_request_client_remove(socket);
79 return -1;
82 return ret;
85 int mk_conn_write(int socket)
87 int ret = -1;
88 struct client_request *cr;
89 struct sched_list_node *sched;
91 #ifdef TRACE
92 MK_TRACE("[FD %i] Connection Handler, write", socket);
93 #endif
95 /* Plugin hook */
96 ret = mk_plugin_event_write(socket);
97 #ifdef TRACE
98 MK_TRACE("Check plugin hook | ret = %i", ret);
99 #endif
100 if (ret != MK_PLUGIN_RET_EVENT_NOT_ME) {
101 return ret;
104 #ifdef TRACE
105 MK_TRACE("[FD %i] Normal connection write handling", socket);
106 #endif
108 sched = mk_sched_get_thread_conf();
109 mk_sched_update_conn_status(sched, socket, MK_SCHEDULER_CONN_PROCESS);
111 /* Get node from schedule list node which contains
112 * the information regarding to the current client/socket
114 cr = mk_request_client_get(socket);
116 if (!cr) {
117 return -1;
120 ret = mk_handler_write(socket, cr);
122 /* if ret < 0, means that some error
123 * happened in the writer call, in the
124 * other hand, 0 means a successful request
125 * processed, if ret > 0 means that some data
126 * still need to be send.
128 if (ret < 0) {
129 mk_request_free_list(cr);
130 mk_request_client_remove(socket);
131 return -1;
133 else if (ret == 0) {
134 if (mk_http_request_end(socket) < 0) {
135 mk_request_free_list(cr);
136 return -1;
138 else {
139 return 0;
142 else if (ret > 0) {
143 return 0;
146 /* avoid to make gcc cry :_( */
147 return -1;
150 int mk_conn_error(int socket)
152 int ret = -1;
153 struct client_request *cr;
154 struct sched_list_node *sched;
156 #ifdef TRACE
157 MK_TRACE("Connection Handler, error on FD %i", socket);
158 #endif
160 /* Plugin hook */
161 ret = mk_plugin_event_error(socket);
162 if (ret != MK_PLUGIN_RET_EVENT_NOT_ME) {
163 if (ret == MK_PLUGIN_RET_END || ret == MK_PLUGIN_RET_CLOSE_CONX){
164 #ifdef TRACE
165 MK_TRACE("CLOSING REQUEST");
166 #endif
167 return -1;
169 return ret;
172 sched = mk_sched_get_thread_conf();
173 mk_sched_remove_client(NULL, socket);
174 cr = mk_request_client_get(socket);
175 if (cr) {
176 mk_request_client_remove(socket);
179 return 0;
182 int mk_conn_close(int socket)
184 int ret = -1;
185 struct sched_list_node *sched;
187 #ifdef TRACE
188 MK_TRACE("[FD %i] Connection Handler, closed", socket);
189 #endif
191 /* Plugin hook */
192 ret = mk_plugin_event_close(socket);
193 if (ret != MK_PLUGIN_RET_EVENT_NOT_ME) {
194 return ret;
196 sched = mk_sched_get_thread_conf();
197 mk_sched_remove_client(sched, socket);
198 return 0;
201 int mk_conn_timeout(int socket)
203 int ret = -1;
204 struct sched_list_node *sched;
206 #ifdef TRACE
207 MK_TRACE("[FD %i] Connection Handler, timeout", socket);
208 #endif
210 /* Plugin hook */
211 ret = mk_plugin_event_timeout(socket);
212 if (ret != MK_PLUGIN_RET_EVENT_NOT_ME) {
213 return ret;
216 sched = mk_sched_get_thread_conf();
217 mk_sched_check_timeouts(sched);
219 return 0;