Refactoring read/write handlers and pointers
[MonkeyD.git] / src / connection.c
blob49581bbcda4f7361ac18e59621fac3ab67f3f61b
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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"
30 #include <string.h>
31 #include <stdio.h>
33 int mk_conn_read(int socket)
35 int ret;
36 struct client_request *cr;
37 struct sched_list_node *sched;
39 sched = mk_sched_get_thread_conf();
41 cr = mk_request_client_get(socket);
42 if(!cr)
44 /* Note: Linux don't set TCP_NODELAY socket flag by default,
45 * also we set the client socket on non-blocking mode
47 mk_socket_set_tcp_nodelay(socket);
48 mk_socket_set_nonblocking(socket);
50 cr = mk_request_client_create(socket);
52 /* Update requests counter */
53 mk_sched_update_thread_status(NULL,
54 MK_SCHEDULER_ACTIVE_UP,
55 MK_SCHEDULER_CLOSED_DOWN);
57 else{
58 /* If cr struct already exists, that could means that we
59 * are facing a keepalive connection, need to verify, if it
60 * applies we increase the thread status for active connections
62 if(cr->counter_connections > 1 && cr->body_length == 0){
63 mk_sched_update_thread_status(NULL,
64 MK_SCHEDULER_ACTIVE_UP,
65 MK_SCHEDULER_CLOSED_NONE);
69 /* Read incomming data */
70 ret = mk_handler_read(socket, cr);
72 if(ret > 0){
73 if(mk_http_pending_request(cr)==0){
74 mk_epoll_socket_change_mode(sched->epoll_fd,
75 socket,
76 MK_EPOLL_WRITE);
78 else if(cr->body_length+1 >= MAX_REQUEST_BODY)
80 /* Request is incomplete and our buffer is full,
81 * close connection
83 mk_request_client_remove(socket);
84 return -1;
87 return ret;
90 int mk_conn_write(int socket)
92 int ret=-1, ka;
93 struct client_request *cr;
94 struct sched_list_node *sched;
96 sched = mk_sched_get_thread_conf();
97 mk_sched_update_conn_status(sched, socket, MK_SCHEDULER_CONN_PROCESS);
99 /* Get node from schedule list node which contains
100 * the information regarding to the current client/socket
102 cr = mk_request_client_get(socket);
104 if(!cr)
106 return -1;
109 ret = mk_handler_write(socket, cr);
110 ka = mk_http_keepalive_check(socket, cr);
112 /* if ret < 0, means that some error
113 * happened in the writer call, in the
114 * other hand, 0 means a successful request
115 * processed, if ret > 0 means that some data
116 * still need to be send.
119 if(ret <= 0)
121 mk_request_free_list(cr);
123 /* We need to ask to http_keepalive if this
124 * connection can continue working or we must
125 * close it.
128 mk_sched_update_thread_status(sched,
129 MK_SCHEDULER_ACTIVE_DOWN,
130 MK_SCHEDULER_CLOSED_UP);
132 if(ka<0 || ret<0)
134 mk_request_client_remove(socket);
135 return -1;
137 else{
138 mk_request_ka_next(cr);
139 mk_epoll_socket_change_mode(sched->epoll_fd,
140 socket,
141 MK_EPOLL_READ);
142 return 0;
145 else if(ret > 0)
147 return 0;
150 /* avoid to make gcc cry :_( */
151 return -1;
154 int mk_conn_error(int socket)
156 struct client_request *cr;
157 struct sched_list_node *sched;
159 sched = mk_sched_get_thread_conf();
160 mk_sched_remove_client(NULL, socket);
161 cr = mk_request_client_get(socket);
162 if(cr){
163 mk_request_client_remove(socket);
166 return 0;
169 int mk_conn_close(int socket)
171 struct sched_list_node *sched;
173 sched = mk_sched_get_thread_conf();
174 mk_sched_remove_client(sched, socket);
176 return 0;
179 int mk_conn_timeout(int socket)
181 struct sched_list_node *sched;
183 sched = mk_sched_get_thread_conf();
184 mk_sched_check_timeouts(sched);
186 return 0;