Security Plugin: set http status for URL rule match
[MonkeyD.git] / src / connection.c
blobbcfde531469abf0a7810ca2b362f1349f6b4d7be
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"
31 #include "http_status.h"
33 #include <string.h>
34 #include <stdio.h>
36 int mk_conn_read(int socket)
38 int ret;
39 struct client_request *cr;
40 struct sched_list_node *sched;
42 #ifdef TRACE
43 MK_TRACE("Connection Handler, read on FD %i", socket);
44 #endif
46 /* Plugin hook */
47 ret = mk_plugin_event_read(socket);
48 if (ret != MK_PLUGIN_RET_EVENT_NOT_ME) {
49 if (ret == MK_PLUGIN_RET_END || ret == MK_PLUGIN_RET_CLOSE_CONX){
50 return -1;
52 return ret;
55 sched = mk_sched_get_thread_conf();
57 cr = mk_request_client_get(socket);
58 if (!cr) {
59 /* Note: Linux don't set TCP_NODELAY socket flag by default,
61 mk_socket_set_tcp_nodelay(socket);
63 /* Create client */
64 cr = mk_request_client_create(socket);
67 /* Read incomming data */
68 ret = mk_handler_read(socket, cr);
70 if (ret > 0) {
71 if (mk_http_pending_request(cr) == 0) {
72 mk_epoll_change_mode(sched->epoll_fd,
73 socket, MK_EPOLL_WRITE);
75 else if (cr->body_length + 1 >= config->max_request_size) {
76 /* Request is incomplete and our buffer is full,
77 * close connection
79 mk_request_client_remove(socket);
80 return -1;
83 return ret;
86 int mk_conn_write(int socket)
88 int ret = -1;
89 struct client_request *cr;
90 struct sched_list_node *sched;
92 #ifdef TRACE
93 MK_TRACE("[FD %i] Connection Handler, write", socket);
94 #endif
96 /* Plugin hook */
97 ret = mk_plugin_event_write(socket);
98 #ifdef TRACE
99 MK_TRACE("Check plugin hook | ret = %i", ret);
100 #endif
101 if (ret != MK_PLUGIN_RET_EVENT_NOT_ME) {
102 return ret;
105 #ifdef TRACE
106 MK_TRACE("[FD %i] Normal connection write handling", socket);
107 #endif
109 sched = mk_sched_get_thread_conf();
110 mk_sched_update_conn_status(sched, socket, MK_SCHEDULER_CONN_PROCESS);
112 /* Get node from schedule list node which contains
113 * the information regarding to the current client/socket
115 cr = mk_request_client_get(socket);
117 if (!cr) {
118 return -1;
121 ret = mk_handler_write(socket, cr);
123 /* if ret < 0, means that some error
124 * happened in the writer call, in the
125 * other hand, 0 means a successful request
126 * processed, if ret > 0 means that some data
127 * still need to be send.
129 if (ret < 0) {
130 mk_request_free_list(cr);
131 mk_request_client_remove(socket);
132 return -1;
134 else if (ret == 0) {
135 if (mk_http_request_end(socket) < 0) {
136 mk_request_free_list(cr);
137 return -1;
139 else {
140 return 0;
143 else if (ret > 0) {
144 return 0;
147 /* avoid to make gcc cry :_( */
148 return -1;
151 int mk_conn_error(int socket)
153 int ret = -1;
154 struct client_request *cr;
155 struct sched_list_node *sched;
157 #ifdef TRACE
158 MK_TRACE("Connection Handler, error on FD %i", socket);
159 #endif
161 /* Plugin hook */
162 ret = mk_plugin_event_error(socket);
163 if (ret != MK_PLUGIN_RET_EVENT_NOT_ME) {
164 if (ret == MK_PLUGIN_RET_END || ret == MK_PLUGIN_RET_CLOSE_CONX){
165 #ifdef TRACE
166 MK_TRACE("CLOSING REQUEST");
167 #endif
168 return -1;
170 return ret;
173 sched = mk_sched_get_thread_conf();
174 mk_sched_remove_client(NULL, socket);
175 cr = mk_request_client_get(socket);
176 if (cr) {
177 mk_request_client_remove(socket);
180 return 0;
183 int mk_conn_close(int socket)
185 int ret = -1;
186 struct sched_list_node *sched;
188 #ifdef TRACE
189 MK_TRACE("[FD %i] Connection Handler, closed", socket);
190 #endif
192 /* Plugin hook */
193 ret = mk_plugin_event_close(socket);
194 if (ret != MK_PLUGIN_RET_EVENT_NOT_ME) {
195 return ret;
197 sched = mk_sched_get_thread_conf();
198 mk_sched_remove_client(sched, socket);
199 return 0;
202 int mk_conn_timeout(int socket)
204 int ret = -1;
205 struct sched_list_node *sched;
207 #ifdef TRACE
208 MK_TRACE("[FD %i] Connection Handler, timeout", socket);
209 #endif
211 /* Plugin hook */
212 ret = mk_plugin_event_timeout(socket);
213 if (ret != MK_PLUGIN_RET_EVENT_NOT_ME) {
214 return ret;
217 sched = mk_sched_get_thread_conf();
218 mk_sched_check_timeouts(sched);
220 return 0;