1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 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.
24 #include "connection.h"
25 #include "scheduler.h"
31 #include "http_status.h"
36 int mk_conn_read(int socket
)
39 struct client_request
*cr
;
40 struct sched_list_node
*sched
;
43 MK_TRACE("Connection Handler, read on FD %i", socket
);
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
){
55 sched
= mk_sched_get_thread_conf();
57 cr
= mk_request_client_get(socket
);
59 /* Note: Linux don't set TCP_NODELAY socket flag by default,
61 mk_socket_set_tcp_nodelay(socket
);
64 cr
= mk_request_client_create(socket
);
67 /* Read incomming data */
68 ret
= mk_handler_read(socket
, cr
);
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,
79 mk_request_client_remove(socket
);
86 int mk_conn_write(int socket
)
89 struct client_request
*cr
;
90 struct sched_list_node
*sched
;
93 MK_TRACE("[FD %i] Connection Handler, write", socket
);
97 ret
= mk_plugin_event_write(socket
);
99 MK_TRACE("Check plugin hook | ret = %i", ret
);
101 if (ret
!= MK_PLUGIN_RET_EVENT_NOT_ME
) {
106 MK_TRACE("[FD %i] Normal connection write handling", socket
);
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
);
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.
130 mk_request_free_list(cr
);
131 mk_request_client_remove(socket
);
135 if (mk_http_request_end(socket
) < 0) {
136 mk_request_free_list(cr
);
147 /* avoid to make gcc cry :_( */
151 int mk_conn_error(int socket
)
154 struct client_request
*cr
;
155 struct sched_list_node
*sched
;
158 MK_TRACE("Connection Handler, error on FD %i", socket
);
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
){
166 MK_TRACE("CLOSING REQUEST");
173 sched
= mk_sched_get_thread_conf();
174 mk_sched_remove_client(NULL
, socket
);
175 cr
= mk_request_client_get(socket
);
177 mk_request_client_remove(socket
);
183 int mk_conn_close(int socket
)
186 struct sched_list_node
*sched
;
189 MK_TRACE("[FD %i] Connection Handler, closed", socket
);
193 ret
= mk_plugin_event_close(socket
);
194 if (ret
!= MK_PLUGIN_RET_EVENT_NOT_ME
) {
197 sched
= mk_sched_get_thread_conf();
198 mk_sched_remove_client(sched
, socket
);
202 int mk_conn_timeout(int socket
)
205 struct sched_list_node
*sched
;
208 MK_TRACE("[FD %i] Connection Handler, timeout", socket
);
212 ret
= mk_plugin_event_timeout(socket
);
213 if (ret
!= MK_PLUGIN_RET_EVENT_NOT_ME
) {
217 sched
= mk_sched_get_thread_conf();
218 mk_sched_check_timeouts(sched
);