Add plugin handlers for events
[MonkeyD.git] / src / connection.c
blob19e6e22c9551c1184aa584836f31ad52c88a95e5
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 return ret;
51 sched = mk_sched_get_thread_conf();
53 cr = mk_request_client_get(socket);
54 if (!cr) {
55 /* Note: Linux don't set TCP_NODELAY socket flag by default,
57 mk_socket_set_tcp_nodelay(socket);
59 /* Create client */
60 cr = mk_request_client_create(socket);
62 else {
63 /* If cr struct already exists, that could means that we
64 * are facing a keepalive connection, need to verify, if it
65 * applies we increase the thread status for active connections
67 if (cr->counter_connections > 1 && cr->body_length == 0) {
68 /* FIXME: KA Connection */
72 /* Read incomming data */
73 ret = mk_handler_read(socket, cr);
75 if (ret > 0) {
76 if (mk_http_pending_request(cr) == 0) {
77 mk_epoll_socket_change_mode(sched->epoll_fd,
78 socket, MK_EPOLL_WRITE);
80 else if (cr->body_length + 1 >= MAX_REQUEST_BODY) {
81 /* Request is incomplete and our buffer is full,
82 * close connection
84 mk_request_client_remove(socket);
85 return -1;
88 return ret;
91 int mk_conn_write(int socket)
93 int ret = -1, ka;
94 struct client_request *cr;
95 struct sched_list_node *sched;
97 #ifdef TRACE
98 MK_TRACE("Connection Handler, write on FD %i", socket);
99 #endif
101 /* Plugin hook */
102 ret = mk_plugin_event_write(socket);
103 #ifdef TRACE
104 MK_TRACE("Check plugin hook | ret = %i", ret);
105 #endif
106 if (ret != MK_PLUGIN_RET_EVENT_NOT_ME) {
107 return ret;
110 #ifdef TRACE
111 MK_TRACE("Normal connection write handling...");
112 #endif
114 sched = mk_sched_get_thread_conf();
115 mk_sched_update_conn_status(sched, socket, MK_SCHEDULER_CONN_PROCESS);
117 /* Get node from schedule list node which contains
118 * the information regarding to the current client/socket
120 cr = mk_request_client_get(socket);
122 if (!cr) {
123 return -1;
126 ret = mk_handler_write(socket, cr);
127 ka = mk_http_keepalive_check(socket, cr);
129 /* if ret < 0, means that some error
130 * happened in the writer call, in the
131 * other hand, 0 means a successful request
132 * processed, if ret > 0 means that some data
133 * still need to be send.
135 if (ret <= 0) {
136 mk_request_free_list(cr);
138 /* We need to ask to http_keepalive if this
139 * connection can continue working or we must
140 * close it.
142 if (ka < 0 || ret < 0) {
143 mk_request_client_remove(socket);
144 return -1;
146 else {
147 mk_request_ka_next(cr);
148 mk_epoll_socket_change_mode(sched->epoll_fd,
149 socket, MK_EPOLL_READ);
150 return 0;
153 else if (ret > 0) {
154 return 0;
157 /* avoid to make gcc cry :_( */
158 return -1;
161 int mk_conn_error(int socket)
163 int ret = -1;
164 struct client_request *cr;
165 struct sched_list_node *sched;
167 #ifdef TRACE
168 MK_TRACE("Connection Handler, error on FD %i", socket);
169 #endif
171 /* Plugin hook */
172 ret = mk_plugin_event_error(socket);
173 if (ret != MK_PLUGIN_RET_EVENT_NOT_ME) {
174 return ret;
177 sched = mk_sched_get_thread_conf();
178 mk_sched_remove_client(NULL, socket);
179 cr = mk_request_client_get(socket);
180 if (cr) {
181 mk_request_client_remove(socket);
184 return 0;
187 int mk_conn_close(int socket)
189 int ret = -1;
190 struct sched_list_node *sched;
192 #ifdef TRACE
193 MK_TRACE("Connection Handler, closed on FD %i", socket);
194 #endif
196 /* Plugin hook */
197 ret = mk_plugin_event_close(socket);
198 if (ret != MK_PLUGIN_RET_EVENT_NOT_ME) {
199 return ret;
202 sched = mk_sched_get_thread_conf();
203 mk_sched_remove_client(sched, socket);
205 return 0;
208 int mk_conn_timeout(int socket)
210 int ret = -1;
211 struct sched_list_node *sched;
213 #ifdef TRACE
214 MK_TRACE("Connection Handler, timeout on FD %i", socket);
215 #endif
217 /* Plugin hook */
218 ret = mk_plugin_event_timeout(socket);
219 if (ret != MK_PLUGIN_RET_EVENT_NOT_ME) {
220 return ret;
223 sched = mk_sched_get_thread_conf();
224 mk_sched_check_timeouts(sched);
226 return 0;