aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2007-07-09 03:20:40 +0000
committerChristian Grothoff <christian@grothoff.org>2007-07-09 03:20:40 +0000
commit4884490319a3d0b9f36474412882130529f08078 (patch)
treeb8e2fc46210acbe8d0ae2ca55539af80a01cefa2
parent6bf6682ce48efc246f3d098c1e35de1213509f6b (diff)
downloadlibmicrohttpd-4884490319a3d0b9f36474412882130529f08078.tar.gz
libmicrohttpd-4884490319a3d0b9f36474412882130529f08078.zip
stuff
-rw-r--r--README10
-rw-r--r--src/daemon/Makefile.am4
-rw-r--r--src/daemon/daemon.c76
-rw-r--r--src/daemon/session.c434
-rw-r--r--src/daemon/session.h20
-rw-r--r--src/include/microhttpd.h65
6 files changed, 316 insertions, 293 deletions
diff --git a/README b/README
index e549761f..bbab2805 100644
--- a/README
+++ b/README
@@ -14,7 +14,10 @@ For http-compliance:
14session.c: 14session.c:
15- send proper error code back if headers are too long 15- send proper error code back if headers are too long
16 (investigate what we should do with those headers, 16 (investigate what we should do with those headers,
17 read? give user control?) 17 read? give user control?)
18 ALSO: should this limit be per-line or for the
19 entire header? (currently, we enforce per-line,
20 but the entire header might make more sense!)
18- http 1.0 compatibility (if 1.0, force connection 21- http 1.0 compatibility (if 1.0, force connection
19 close at the end!) 22 close at the end!)
20 23
@@ -22,8 +25,7 @@ For IPv6:
22========= 25=========
23daemon.c: 26daemon.c:
24- fix start daemon and accept handlers 27- fix start daemon and accept handlers
25 (tricky bit will be supporting both on 28
26 the same socket / port!)
27 29
28For SSL: 30For SSL:
29======== 31========
@@ -38,5 +40,7 @@ Other:
38 (API extension) 40 (API extension)
39- allow client to control size of input/output 41- allow client to control size of input/output
40 buffers 42 buffers
43- allow client to limit total number of connections
44
41 45
42 46
diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am
index a948c667..5ce824cc 100644
--- a/src/daemon/Makefile.am
+++ b/src/daemon/Makefile.am
@@ -8,11 +8,11 @@ lib_LTLIBRARIES = \
8libmicrohttpd_la_LDFLAGS = \ 8libmicrohttpd_la_LDFLAGS = \
9 -export-dynamic -version-info 0:0:0 9 -export-dynamic -version-info 0:0:0
10libmicrohttpd_la_SOURCES = \ 10libmicrohttpd_la_SOURCES = \
11 connection.c connection.h \
11 daemon.c \ 12 daemon.c \
12 internal.c internal.h \ 13 internal.c internal.h \
13 plibc.h \ 14 plibc.h \
14 response.c response.h \ 15 response.c response.h
15 session.c session.h
16 16
17# example programs 17# example programs
18 18
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index 379e3cf9..8b4d25dd 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -27,7 +27,7 @@
27 27
28#include "internal.h" 28#include "internal.h"
29#include "response.h" 29#include "response.h"
30#include "session.h" 30#include "connection.h"
31 31
32#define MHD_MAX_CONNECTIONS FD_SETSIZE -4 32#define MHD_MAX_CONNECTIONS FD_SETSIZE -4
33 33
@@ -120,7 +120,7 @@ MHD_get_fdset(struct MHD_Daemon * daemon,
120 fd_set * write_fd_set, 120 fd_set * write_fd_set,
121 fd_set * except_fd_set, 121 fd_set * except_fd_set,
122 int * max_fd) { 122 int * max_fd) {
123 struct MHD_Session * pos; 123 struct MHD_Connection * pos;
124 124
125 if ( (daemon == NULL) || 125 if ( (daemon == NULL) ||
126 (read_fd_set == NULL) || 126 (read_fd_set == NULL) ||
@@ -135,7 +135,7 @@ MHD_get_fdset(struct MHD_Daemon * daemon,
135 *max_fd = daemon->socket_fd; 135 *max_fd = daemon->socket_fd;
136 pos = daemon->connections; 136 pos = daemon->connections;
137 while (pos != NULL) { 137 while (pos != NULL) {
138 if (MHD_YES != MHD_session_get_fdset(pos, 138 if (MHD_YES != MHD_connection_get_fdset(pos,
139 read_fd_set, 139 read_fd_set,
140 write_fd_set, 140 write_fd_set,
141 except_fd_set, 141 except_fd_set,
@@ -153,7 +153,7 @@ MHD_get_fdset(struct MHD_Daemon * daemon,
153 */ 153 */
154static void * 154static void *
155MHD_handle_connection(void * data) { 155MHD_handle_connection(void * data) {
156 struct MHD_Session * con = data; 156 struct MHD_Connection * con = data;
157 int num_ready; 157 int num_ready;
158 fd_set rs; 158 fd_set rs;
159 fd_set ws; 159 fd_set ws;
@@ -168,7 +168,7 @@ MHD_handle_connection(void * data) {
168 FD_ZERO(&ws); 168 FD_ZERO(&ws);
169 FD_ZERO(&es); 169 FD_ZERO(&es);
170 max = 0; 170 max = 0;
171 MHD_session_get_fdset(con, 171 MHD_connection_get_fdset(con,
172 &rs, 172 &rs,
173 &ws, 173 &ws,
174 &es, 174 &es,
@@ -184,14 +184,14 @@ MHD_handle_connection(void * data) {
184 break; 184 break;
185 } 185 }
186 if ( ( (FD_ISSET(con->socket_fd, &rs)) && 186 if ( ( (FD_ISSET(con->socket_fd, &rs)) &&
187 (MHD_YES != MHD_session_handle_read(con)) ) || 187 (MHD_YES != MHD_connection_handle_read(con)) ) ||
188 ( (con->socket_fd != -1) && 188 ( (con->socket_fd != -1) &&
189 (FD_ISSET(con->socket_fd, &ws)) && 189 (FD_ISSET(con->socket_fd, &ws)) &&
190 (MHD_YES != MHD_session_handle_write(con)) ) ) 190 (MHD_YES != MHD_connection_handle_write(con)) ) )
191 break; 191 break;
192 if ( (con->headersReceived == 1) && 192 if ( (con->headersReceived == 1) &&
193 (con->response == NULL) ) 193 (con->response == NULL) )
194 MHD_call_session_handler(con); 194 MHD_call_connection_handler(con);
195 } 195 }
196 if (con->socket_fd != -1) { 196 if (con->socket_fd != -1) {
197 CLOSE(con->socket_fd); 197 CLOSE(con->socket_fd);
@@ -202,13 +202,13 @@ MHD_handle_connection(void * data) {
202 202
203 203
204/** 204/**
205 * Accept an incoming connection and create the MHD_Session object for 205 * Accept an incoming connection and create the MHD_Connection object for
206 * it. This function also enforces policy by way of checking with the 206 * it. This function also enforces policy by way of checking with the
207 * accept policy callback. 207 * accept policy callback.
208 */ 208 */
209static int 209static int
210MHD_accept_connection(struct MHD_Daemon * daemon) { 210MHD_accept_connection(struct MHD_Daemon * daemon) {
211 struct MHD_Session * session; 211 struct MHD_Connection * connection;
212 struct sockaddr addr; 212 struct sockaddr addr;
213 socklen_t addrlen; 213 socklen_t addrlen;
214 int s; 214 int s;
@@ -233,50 +233,50 @@ MHD_accept_connection(struct MHD_Daemon * daemon) {
233 CLOSE(s); 233 CLOSE(s);
234 return MHD_YES; 234 return MHD_YES;
235 } 235 }
236 session = malloc(sizeof(struct MHD_Session)); 236 connection = malloc(sizeof(struct MHD_Connection));
237 memset(session, 237 memset(connection,
238 0, 238 0,
239 sizeof(struct MHD_Session)); 239 sizeof(struct MHD_Connection));
240 session->addr = malloc(addrlen); 240 connection->addr = malloc(addrlen);
241 memcpy(session->addr, 241 memcpy(connection->addr,
242 &addr, 242 &addr,
243 addrlen); 243 addrlen);
244 session->addr_len = addrlen; 244 connection->addr_len = addrlen;
245 session->socket_fd = s; 245 connection->socket_fd = s;
246 session->daemon = daemon; 246 connection->daemon = daemon;
247 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION) ) && 247 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION) ) &&
248 (0 != pthread_create(&session->pid, 248 (0 != pthread_create(&connection->pid,
249 NULL, 249 NULL,
250 &MHD_handle_connection, 250 &MHD_handle_connection,
251 session)) ) { 251 connection)) ) {
252 MHD_DLOG(daemon, 252 MHD_DLOG(daemon,
253 "Failed to create a thread: %s\n", 253 "Failed to create a thread: %s\n",
254 STRERROR(errno)); 254 STRERROR(errno));
255 free(session->addr); 255 free(connection->addr);
256 CLOSE(s); 256 CLOSE(s);
257 free(session); 257 free(connection);
258 return MHD_NO; 258 return MHD_NO;
259 } 259 }
260 session->next = daemon->connections; 260 connection->next = daemon->connections;
261 daemon->connections = session; 261 daemon->connections = connection;
262 return MHD_YES; 262 return MHD_YES;
263} 263}
264 264
265 265
266/** 266/**
267 * Free resources associated with all closed sessions. 267 * Free resources associated with all closed connections.
268 * (destroy responses, free buffers, etc.). A session 268 * (destroy responses, free buffers, etc.). A connection
269 * is known to be closed if the socket_fd is -1. 269 * is known to be closed if the socket_fd is -1.
270 * 270 *
271 * Also performs session actions that need to be run 271 * Also performs connection actions that need to be run
272 * even if the session is not selectable (such as 272 * even if the connection is not selectable (such as
273 * calling the application again with upload data when 273 * calling the application again with upload data when
274 * the upload data buffer is full). 274 * the upload data buffer is full).
275 */ 275 */
276static void 276static void
277MHD_cleanup_sessions(struct MHD_Daemon * daemon) { 277MHD_cleanup_connections(struct MHD_Daemon * daemon) {
278 struct MHD_Session * pos; 278 struct MHD_Connection * pos;
279 struct MHD_Session * prev; 279 struct MHD_Connection * prev;
280 struct MHD_HTTP_Header * hpos; 280 struct MHD_HTTP_Header * hpos;
281 void * unused; 281 void * unused;
282 282
@@ -320,7 +320,7 @@ MHD_cleanup_sessions(struct MHD_Daemon * daemon) {
320 320
321 if ( (pos->headersReceived == 1) && 321 if ( (pos->headersReceived == 1) &&
322 (pos->response == NULL) ) 322 (pos->response == NULL) )
323 MHD_call_session_handler(pos); 323 MHD_call_connection_handler(pos);
324 324
325 prev = pos; 325 prev = pos;
326 pos = pos->next; 326 pos = pos->next;
@@ -337,7 +337,7 @@ MHD_cleanup_sessions(struct MHD_Daemon * daemon) {
337static int 337static int
338MHD_select(struct MHD_Daemon * daemon, 338MHD_select(struct MHD_Daemon * daemon,
339 int may_block) { 339 int may_block) {
340 struct MHD_Session * pos; 340 struct MHD_Connection * pos;
341 int num_ready; 341 int num_ready;
342 fd_set rs; 342 fd_set rs;
343 fd_set ws; 343 fd_set ws;
@@ -397,9 +397,9 @@ MHD_select(struct MHD_Daemon * daemon,
397 continue; 397 continue;
398 } 398 }
399 if (FD_ISSET(ds, &rs)) 399 if (FD_ISSET(ds, &rs))
400 MHD_session_handle_read(pos); 400 MHD_connection_handle_read(pos);
401 if (FD_ISSET(ds, &ws)) 401 if (FD_ISSET(ds, &ws))
402 MHD_session_handle_write(pos); 402 MHD_connection_handle_write(pos);
403 pos = pos->next; 403 pos = pos->next;
404 } 404 }
405 } 405 }
@@ -424,7 +424,7 @@ MHD_run(struct MHD_Daemon * daemon) {
424 (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) ) 424 (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) )
425 return MHD_NO; 425 return MHD_NO;
426 MHD_select(daemon, MHD_NO); 426 MHD_select(daemon, MHD_NO);
427 MHD_cleanup_sessions(daemon); 427 MHD_cleanup_connections(daemon);
428 return MHD_YES; 428 return MHD_YES;
429} 429}
430 430
@@ -438,7 +438,7 @@ MHD_select_thread(void * cls) {
438 struct MHD_Daemon * daemon = cls; 438 struct MHD_Daemon * daemon = cls;
439 while (daemon->shutdown == 0) { 439 while (daemon->shutdown == 0) {
440 MHD_select(daemon, MHD_YES); 440 MHD_select(daemon, MHD_YES);
441 MHD_cleanup_sessions(daemon); 441 MHD_cleanup_connections(daemon);
442 } 442 }
443 return NULL; 443 return NULL;
444} 444}
@@ -559,7 +559,7 @@ MHD_stop_daemon(struct MHD_Daemon * daemon) {
559 CLOSE(daemon->connections->socket_fd); 559 CLOSE(daemon->connections->socket_fd);
560 daemon->connections->socket_fd = -1; 560 daemon->connections->socket_fd = -1;
561 } 561 }
562 MHD_cleanup_sessions(daemon); 562 MHD_cleanup_connections(daemon);
563 } 563 }
564 free(daemon); 564 free(daemon);
565} 565}
diff --git a/src/daemon/session.c b/src/daemon/session.c
index 48f88868..6b82f9e7 100644
--- a/src/daemon/session.c
+++ b/src/daemon/session.c
@@ -19,14 +19,14 @@
19*/ 19*/
20 20
21/** 21/**
22 * @file session.c 22 * @file connection.c
23 * @brief Methods for managing sessions 23 * @brief Methods for managing connections
24 * @author Daniel Pittman 24 * @author Daniel Pittman
25 * @author Christian Grothoff 25 * @author Christian Grothoff
26 */ 26 */
27 27
28#include "internal.h" 28#include "internal.h"
29#include "session.h" 29#include "connection.h"
30#include "response.h" 30#include "response.h"
31 31
32 32
@@ -39,17 +39,17 @@
39 * @return number of entries iterated over 39 * @return number of entries iterated over
40 */ 40 */
41int 41int
42MHD_get_session_values(struct MHD_Session * session, 42MHD_get_connection_values(struct MHD_Connection * connection,
43 enum MHD_ValueKind kind, 43 enum MHD_ValueKind kind,
44 MHD_KeyValueIterator iterator, 44 MHD_KeyValueIterator iterator,
45 void * iterator_cls) { 45 void * iterator_cls) {
46 int ret; 46 int ret;
47 struct MHD_HTTP_Header * pos; 47 struct MHD_HTTP_Header * pos;
48 48
49 if (session == NULL) 49 if (connection == NULL)
50 return -1; 50 return -1;
51 ret = 0; 51 ret = 0;
52 pos = session->headers_received; 52 pos = connection->headers_received;
53 while (pos != NULL) { 53 while (pos != NULL) {
54 if (0 != (pos->kind & kind)) { 54 if (0 != (pos->kind & kind)) {
55 ret++; 55 ret++;
@@ -74,14 +74,14 @@ MHD_get_session_values(struct MHD_Session * session,
74 * @return NULL if no such item was found 74 * @return NULL if no such item was found
75 */ 75 */
76const char * 76const char *
77MHD_lookup_session_value(struct MHD_Session * session, 77MHD_lookup_connection_value(struct MHD_Connection * connection,
78 enum MHD_ValueKind kind, 78 enum MHD_ValueKind kind,
79 const char * key) { 79 const char * key) {
80 struct MHD_HTTP_Header * pos; 80 struct MHD_HTTP_Header * pos;
81 81
82 if (session == NULL) 82 if (connection == NULL)
83 return NULL; 83 return NULL;
84 pos = session->headers_received; 84 pos = connection->headers_received;
85 while (pos != NULL) { 85 while (pos != NULL) {
86 if ( (0 != (pos->kind & kind)) && 86 if ( (0 != (pos->kind & kind)) &&
87 (0 == strcasecmp(key, 87 (0 == strcasecmp(key,
@@ -96,55 +96,55 @@ MHD_lookup_session_value(struct MHD_Session * session,
96 * Queue a response to be transmitted to the client (as soon as 96 * Queue a response to be transmitted to the client (as soon as
97 * possible). 97 * possible).
98 * 98 *
99 * @param session the session identifying the client 99 * @param connection the connection identifying the client
100 * @param status_code HTTP status code (i.e. 200 for OK) 100 * @param status_code HTTP status code (i.e. 200 for OK)
101 * @param response response to transmit 101 * @param response response to transmit
102 * @return MHD_NO on error (i.e. reply already sent), 102 * @return MHD_NO on error (i.e. reply already sent),
103 * MHD_YES on success or if message has been queued 103 * MHD_YES on success or if message has been queued
104 */ 104 */
105int 105int
106MHD_queue_response(struct MHD_Session * session, 106MHD_queue_response(struct MHD_Connection * connection,
107 unsigned int status_code, 107 unsigned int status_code,
108 struct MHD_Response * response) { 108 struct MHD_Response * response) {
109 if ( (session == NULL) || 109 if ( (connection == NULL) ||
110 (response == NULL) || 110 (response == NULL) ||
111 (session->response != NULL) || 111 (connection->response != NULL) ||
112 (session->bodyReceived == 0) || 112 (connection->bodyReceived == 0) ||
113 (session->headersReceived == 0) ) 113 (connection->headersReceived == 0) )
114 return MHD_NO; 114 return MHD_NO;
115 MHD_increment_response_rc(response); 115 MHD_increment_response_rc(response);
116 session->response = response; 116 connection->response = response;
117 session->responseCode = status_code; 117 connection->responseCode = status_code;
118 return MHD_YES; 118 return MHD_YES;
119} 119}
120 120
121 121
122/** 122/**
123 * Obtain the select sets for this session 123 * Obtain the select sets for this connection
124 * 124 *
125 * @return MHD_YES on success 125 * @return MHD_YES on success
126 */ 126 */
127int 127int
128MHD_session_get_fdset(struct MHD_Session * session, 128MHD_connection_get_fdset(struct MHD_Connection * connection,
129 fd_set * read_fd_set, 129 fd_set * read_fd_set,
130 fd_set * write_fd_set, 130 fd_set * write_fd_set,
131 fd_set * except_fd_set, 131 fd_set * except_fd_set,
132 int * max_fd) { 132 int * max_fd) {
133 int fd; 133 int fd;
134 134
135 fd = session->socket_fd; 135 fd = connection->socket_fd;
136 if (fd == -1) 136 if (fd == -1)
137 return MHD_YES; 137 return MHD_YES;
138 if ( (session->read_close == 0) && 138 if ( (connection->read_close == 0) &&
139 ( (session->headersReceived == 0) || 139 ( (connection->headersReceived == 0) ||
140 (session->readLoc < session->read_buffer_size) ) ) 140 (connection->readLoc < connection->read_buffer_size) ) )
141 FD_SET(fd, read_fd_set); 141 FD_SET(fd, read_fd_set);
142 if (session->response != NULL) 142 if (connection->response != NULL)
143 FD_SET(fd, write_fd_set); 143 FD_SET(fd, write_fd_set);
144 if ( (fd > *max_fd) && 144 if ( (fd > *max_fd) &&
145 ( (session->headersReceived == 0) || 145 ( (connection->headersReceived == 0) ||
146 (session->readLoc < session->read_buffer_size) || 146 (connection->readLoc < connection->read_buffer_size) ||
147 (session->response != NULL) ) ) 147 (connection->response != NULL) ) )
148 *max_fd = fd; 148 *max_fd = fd;
149 return MHD_YES; 149 return MHD_YES;
150} 150}
@@ -158,39 +158,39 @@ MHD_session_get_fdset(struct MHD_Session * session,
158 * return NULL. Otherwise return a copy of the line. 158 * return NULL. Otherwise return a copy of the line.
159 */ 159 */
160static char * 160static char *
161MHD_get_next_header_line(struct MHD_Session * session) { 161MHD_get_next_header_line(struct MHD_Connection * connection) {
162 char * rbuf; 162 char * rbuf;
163 size_t pos; 163 size_t pos;
164 size_t start; 164 size_t start;
165 165
166 if (session->readLoc == 0) 166 if (connection->readLoc == 0)
167 return NULL; 167 return NULL;
168 start = 0; 168 start = 0;
169 pos = 0; 169 pos = 0;
170 rbuf = session->read_buffer; 170 rbuf = connection->read_buffer;
171 while ( (pos < session->readLoc - 1) && 171 while ( (pos < connection->readLoc - 1) &&
172 (rbuf[pos] != '\r') && 172 (rbuf[pos] != '\r') &&
173 (rbuf[pos] != '\n') ) 173 (rbuf[pos] != '\n') )
174 pos++; 174 pos++;
175 if (pos == session->readLoc - 1) { 175 if (pos == connection->readLoc - 1) {
176 /* not found, consider growing... */ 176 /* not found, consider growing... */
177 if (session->readLoc == session->read_buffer_size) { 177 if (connection->readLoc == connection->read_buffer_size) {
178 /* grow buffer to read larger header or die... */ 178 /* grow buffer to read larger header or die... */
179 if (session->read_buffer_size < 4 * MHD_MAX_BUF_SIZE) { 179 if (connection->read_buffer_size < 4 * MHD_MAX_BUF_SIZE) {
180 rbuf = malloc(session->read_buffer_size * 2); 180 rbuf = malloc(connection->read_buffer_size * 2);
181 memcpy(rbuf, 181 memcpy(rbuf,
182 session->read_buffer, 182 connection->read_buffer,
183 session->readLoc); 183 connection->readLoc);
184 free(session->read_buffer); 184 free(connection->read_buffer);
185 session->read_buffer = rbuf; 185 connection->read_buffer = rbuf;
186 session->read_buffer_size *= 2; 186 connection->read_buffer_size *= 2;
187 } else { 187 } else {
188 /* die, header far too long to be reasonable */ 188 /* die, header far too long to be reasonable */
189 MHD_DLOG(session->daemon, 189 MHD_DLOG(connection->daemon,
190 "Received excessively long header line (>%u), closing connection.\n", 190 "Received excessively long header line (>%u), closing connection.\n",
191 4 * MHD_MAX_BUF_SIZE); 191 4 * MHD_MAX_BUF_SIZE);
192 CLOSE(session->socket_fd); 192 CLOSE(connection->socket_fd);
193 session->socket_fd = -1; 193 connection->socket_fd = -1;
194 } 194 }
195 } 195 }
196 return NULL; 196 return NULL;
@@ -198,33 +198,33 @@ MHD_get_next_header_line(struct MHD_Session * session) {
198 /* found, check if we have proper CRLF */ 198 /* found, check if we have proper CRLF */
199 rbuf = malloc(pos + 1); 199 rbuf = malloc(pos + 1);
200 memcpy(rbuf, 200 memcpy(rbuf,
201 session->read_buffer, 201 connection->read_buffer,
202 pos); 202 pos);
203 rbuf[pos] = '\0'; 203 rbuf[pos] = '\0';
204 if ( (session->read_buffer[pos] == '\r') && 204 if ( (connection->read_buffer[pos] == '\r') &&
205 (session->read_buffer[pos+1] == '\n') ) 205 (connection->read_buffer[pos+1] == '\n') )
206 pos++; /* skip both r and n */ 206 pos++; /* skip both r and n */
207 pos++; 207 pos++;
208 memmove(session->read_buffer, 208 memmove(connection->read_buffer,
209 &session->read_buffer[pos], 209 &connection->read_buffer[pos],
210 session->readLoc - pos); 210 connection->readLoc - pos);
211 session->readLoc -= pos; 211 connection->readLoc -= pos;
212 return rbuf; 212 return rbuf;
213} 213}
214 214
215static void 215static void
216MHD_session_add_header(struct MHD_Session * session, 216MHD_connection_add_header(struct MHD_Connection * connection,
217 const char * key, 217 const char * key,
218 const char * value, 218 const char * value,
219 enum MHD_ValueKind kind) { 219 enum MHD_ValueKind kind) {
220 struct MHD_HTTP_Header * hdr; 220 struct MHD_HTTP_Header * hdr;
221 221
222 hdr = malloc(sizeof(struct MHD_HTTP_Header)); 222 hdr = malloc(sizeof(struct MHD_HTTP_Header));
223 hdr->next = session->headers_received; 223 hdr->next = connection->headers_received;
224 hdr->header = strdup(key); 224 hdr->header = strdup(key);
225 hdr->value = strdup(value); 225 hdr->value = strdup(value);
226 hdr->kind = kind; 226 hdr->kind = kind;
227 session->headers_received = hdr; 227 connection->headers_received = hdr;
228} 228}
229 229
230/** 230/**
@@ -254,7 +254,7 @@ MHD_http_unescape(char * val) {
254} 254}
255 255
256static void 256static void
257MHD_parse_arguments(struct MHD_Session * session, 257MHD_parse_arguments(struct MHD_Connection * connection,
258 char * args) { 258 char * args) {
259 char * equals; 259 char * equals;
260 char * amper; 260 char * amper;
@@ -272,7 +272,7 @@ MHD_parse_arguments(struct MHD_Session * session,
272 } 272 }
273 MHD_http_unescape(args); 273 MHD_http_unescape(args);
274 MHD_http_unescape(equals); 274 MHD_http_unescape(equals);
275 MHD_session_add_header(session, 275 MHD_connection_add_header(connection,
276 args, 276 args,
277 equals, 277 equals,
278 MHD_GET_ARGUMENT_KIND); 278 MHD_GET_ARGUMENT_KIND);
@@ -284,7 +284,7 @@ MHD_parse_arguments(struct MHD_Session * session,
284 * Parse the cookie header (see RFC 2109). 284 * Parse the cookie header (see RFC 2109).
285 */ 285 */
286static void 286static void
287MHD_parse_cookie_header(struct MHD_Session * session) { 287MHD_parse_cookie_header(struct MHD_Connection * connection) {
288 const char * hdr; 288 const char * hdr;
289 char * cpy; 289 char * cpy;
290 char * pos; 290 char * pos;
@@ -292,7 +292,7 @@ MHD_parse_cookie_header(struct MHD_Session * session) {
292 char * equals; 292 char * equals;
293 int quotes; 293 int quotes;
294 294
295 hdr = MHD_lookup_session_value(session, 295 hdr = MHD_lookup_connection_value(connection,
296 MHD_HEADER_KIND, 296 MHD_HEADER_KIND,
297 "Cookie"); 297 "Cookie");
298 if (hdr == NULL) 298 if (hdr == NULL)
@@ -327,7 +327,7 @@ MHD_parse_cookie_header(struct MHD_Session * session) {
327 equals[strlen(equals)-1] = '\0'; 327 equals[strlen(equals)-1] = '\0';
328 equals++; 328 equals++;
329 } 329 }
330 MHD_session_add_header(session, 330 MHD_connection_add_header(connection,
331 pos, 331 pos,
332 equals, 332 equals,
333 MHD_COOKIE_KIND); 333 MHD_COOKIE_KIND);
@@ -338,7 +338,7 @@ MHD_parse_cookie_header(struct MHD_Session * session) {
338 338
339 339
340/** 340/**
341 * This function is designed to parse the input buffer of a given session. 341 * This function is designed to parse the input buffer of a given connection.
342 * 342 *
343 * Once the header is complete, it should have set the 343 * Once the header is complete, it should have set the
344 * headers_received, url and method values and set 344 * headers_received, url and method values and set
@@ -348,7 +348,7 @@ MHD_parse_cookie_header(struct MHD_Session * session) {
348 * size of the body is unknown, it should be set to -1. 348 * size of the body is unknown, it should be set to -1.
349 */ 349 */
350static void 350static void
351MHD_parse_session_headers(struct MHD_Session * session) { 351MHD_parse_connection_headers(struct MHD_Connection * connection) {
352 char * last; 352 char * last;
353 char * line; 353 char * line;
354 char * colon; 354 char * colon;
@@ -359,10 +359,10 @@ MHD_parse_session_headers(struct MHD_Session * session) {
359 const char * clen; 359 const char * clen;
360 unsigned long long cval; 360 unsigned long long cval;
361 361
362 if (session->bodyReceived == 1) 362 if (connection->bodyReceived == 1)
363 abort(); 363 abort();
364 last = NULL; 364 last = NULL;
365 while (NULL != (line = MHD_get_next_header_line(session))) { 365 while (NULL != (line = MHD_get_next_header_line(connection))) {
366 if (last != NULL) { 366 if (last != NULL) {
367 if ( (line[0] == ' ') || 367 if ( (line[0] == ' ') ||
368 (line[0] == '\t') ) { 368 (line[0] == '\t') ) {
@@ -373,11 +373,11 @@ MHD_parse_session_headers(struct MHD_Session * session) {
373 free(line); 373 free(line);
374 free(last); 374 free(last);
375 last = NULL; 375 last = NULL;
376 MHD_DLOG(session->daemon, 376 MHD_DLOG(connection->daemon,
377 "Received excessively long header line (>%u), closing connection.\n", 377 "Received excessively long header line (>%u), closing connection.\n",
378 4 * MHD_MAX_BUF_SIZE); 378 4 * MHD_MAX_BUF_SIZE);
379 CLOSE(session->socket_fd); 379 CLOSE(connection->socket_fd);
380 session->socket_fd = -1; 380 connection->socket_fd = -1;
381 break; 381 break;
382 } 382 }
383 tmp = malloc(strlen(line) + strlen(last) + 1); 383 tmp = malloc(strlen(line) + strlen(last) + 1);
@@ -392,7 +392,7 @@ MHD_parse_session_headers(struct MHD_Session * session) {
392 free(line); 392 free(line);
393 continue; /* possibly more than 2 lines... */ 393 continue; /* possibly more than 2 lines... */
394 } else { 394 } else {
395 MHD_session_add_header(session, 395 MHD_connection_add_header(connection,
396 last, 396 last,
397 colon, 397 colon,
398 MHD_HEADER_KIND); 398 MHD_HEADER_KIND);
@@ -400,13 +400,13 @@ MHD_parse_session_headers(struct MHD_Session * session) {
400 last = NULL; 400 last = NULL;
401 } 401 }
402 } 402 }
403 if (session->url == NULL) { 403 if (connection->url == NULL) {
404 /* line must be request line */ 404 /* line must be request line */
405 uri = strstr(line, " "); 405 uri = strstr(line, " ");
406 if (uri == NULL) 406 if (uri == NULL)
407 goto DIE; 407 goto DIE;
408 uri[0] = '\0'; 408 uri[0] = '\0';
409 session->method = strdup(line); 409 connection->method = strdup(line);
410 uri++; 410 uri++;
411 httpType = strstr(uri, " "); 411 httpType = strstr(uri, " ");
412 if (httpType != NULL) { 412 if (httpType != NULL) {
@@ -417,14 +417,14 @@ MHD_parse_session_headers(struct MHD_Session * session) {
417 if (args != NULL) { 417 if (args != NULL) {
418 args[0] = '\0'; 418 args[0] = '\0';
419 args++; 419 args++;
420 MHD_parse_arguments(session, 420 MHD_parse_arguments(connection,
421 args); 421 args);
422 } 422 }
423 session->url = strdup(uri); 423 connection->url = strdup(uri);
424 if (httpType == NULL) 424 if (httpType == NULL)
425 session->version = strdup(""); 425 connection->version = strdup("");
426 else 426 else
427 session->version = strdup(httpType); 427 connection->version = strdup(httpType);
428 free(line); 428 free(line);
429 continue; 429 continue;
430 } 430 }
@@ -432,31 +432,31 @@ MHD_parse_session_headers(struct MHD_Session * session) {
432 if (strlen(line) == 0) { 432 if (strlen(line) == 0) {
433 free(line); 433 free(line);
434 /* end of header */ 434 /* end of header */
435 session->headersReceived = 1; 435 connection->headersReceived = 1;
436 clen = MHD_lookup_session_value(session, 436 clen = MHD_lookup_connection_value(connection,
437 MHD_HEADER_KIND, 437 MHD_HEADER_KIND,
438 "Content-Length"); 438 "Content-Length");
439 if (clen != NULL) { 439 if (clen != NULL) {
440 if (1 != sscanf(clen, 440 if (1 != sscanf(clen,
441 "%llu", 441 "%llu",
442 &cval)) { 442 &cval)) {
443 MHD_DLOG(session->daemon, 443 MHD_DLOG(connection->daemon,
444 "Failed to parse Content-Length header `%s', closing connection.\n", 444 "Failed to parse Content-Length header `%s', closing connection.\n",
445 clen); 445 clen);
446 goto DIE; 446 goto DIE;
447 } 447 }
448 session->uploadSize = cval; 448 connection->uploadSize = cval;
449 session->bodyReceived = cval == 0 ? 1 : 0; 449 connection->bodyReceived = cval == 0 ? 1 : 0;
450 } else { 450 } else {
451 if (NULL == MHD_lookup_session_value(session, 451 if (NULL == MHD_lookup_connection_value(connection,
452 MHD_HEADER_KIND, 452 MHD_HEADER_KIND,
453 "Transfer-Encoding")) { 453 "Transfer-Encoding")) {
454 /* this request does not have a body */ 454 /* this request does not have a body */
455 session->uploadSize = 0; 455 connection->uploadSize = 0;
456 session->bodyReceived = 1; 456 connection->bodyReceived = 1;
457 } else { 457 } else {
458 session->uploadSize = -1; /* unknown size */ 458 connection->uploadSize = -1; /* unknown size */
459 session->bodyReceived = 0; 459 connection->bodyReceived = 0;
460 } 460 }
461 } 461 }
462 break; 462 break;
@@ -465,7 +465,7 @@ MHD_parse_session_headers(struct MHD_Session * session) {
465 colon = strstr(line, ":"); 465 colon = strstr(line, ":");
466 if (colon == NULL) { 466 if (colon == NULL) {
467 /* error in header line, die hard */ 467 /* error in header line, die hard */
468 MHD_DLOG(session->daemon, 468 MHD_DLOG(connection->daemon,
469 "Received malformed line (no colon), closing connection.\n"); 469 "Received malformed line (no colon), closing connection.\n");
470 goto DIE; 470 goto DIE;
471 } 471 }
@@ -476,24 +476,24 @@ MHD_parse_session_headers(struct MHD_Session * session) {
476 ( (colon[0] == ' ') || 476 ( (colon[0] == ' ') ||
477 (colon[0] == '\t') ) ) 477 (colon[0] == '\t') ) )
478 colon++; 478 colon++;
479 /* we do the actual adding of the session 479 /* we do the actual adding of the connection
480 header at the beginning of the while 480 header at the beginning of the while
481 loop since we need to be able to inspect 481 loop since we need to be able to inspect
482 the *next* header line (in case it starts 482 the *next* header line (in case it starts
483 with a space...) */ 483 with a space...) */
484 } 484 }
485 if (last != NULL) { 485 if (last != NULL) {
486 MHD_session_add_header(session, 486 MHD_connection_add_header(connection,
487 last, 487 last,
488 colon, 488 colon,
489 MHD_HEADER_KIND); 489 MHD_HEADER_KIND);
490 free(last); 490 free(last);
491 } 491 }
492 MHD_parse_cookie_header(session); 492 MHD_parse_cookie_header(connection);
493 return; 493 return;
494 DIE: 494 DIE:
495 CLOSE(session->socket_fd); 495 CLOSE(connection->socket_fd);
496 session->socket_fd = -1; 496 connection->socket_fd = -1;
497} 497}
498 498
499 499
@@ -501,61 +501,61 @@ MHD_parse_session_headers(struct MHD_Session * session) {
501 * Find the handler responsible for this request. 501 * Find the handler responsible for this request.
502 */ 502 */
503static struct MHD_Access_Handler * 503static struct MHD_Access_Handler *
504MHD_find_access_handler(struct MHD_Session * session) { 504MHD_find_access_handler(struct MHD_Connection * connection) {
505 struct MHD_Access_Handler * pos; 505 struct MHD_Access_Handler * pos;
506 506
507 pos = session->daemon->handlers; 507 pos = connection->daemon->handlers;
508 while (pos != NULL) { 508 while (pos != NULL) {
509 if (0 == strcmp(session->url, 509 if (0 == strcmp(connection->url,
510 pos->uri_prefix)) 510 pos->uri_prefix))
511 return pos; 511 return pos;
512 pos = pos->next; 512 pos = pos->next;
513 } 513 }
514 return &session->daemon->default_handler; 514 return &connection->daemon->default_handler;
515} 515}
516 516
517/** 517/**
518 * Call the handler of the application for this 518 * Call the handler of the application for this
519 * session. 519 * connection.
520 */ 520 */
521void 521void
522MHD_call_session_handler(struct MHD_Session * session) { 522MHD_call_connection_handler(struct MHD_Connection * connection) {
523 struct MHD_Access_Handler * ah; 523 struct MHD_Access_Handler * ah;
524 unsigned int processed; 524 unsigned int processed;
525 525
526 if (session->headersReceived == 0) 526 if (connection->headersReceived == 0)
527 abort(); /* bad timing... */ 527 abort(); /* bad timing... */
528 ah = MHD_find_access_handler(session); 528 ah = MHD_find_access_handler(connection);
529 processed = session->readLoc; 529 processed = connection->readLoc;
530 if (MHD_NO == ah->dh(ah->dh_cls, 530 if (MHD_NO == ah->dh(ah->dh_cls,
531 session, 531 connection,
532 session->url, 532 connection->url,
533 session->method, 533 connection->method,
534 session->read_buffer, 534 connection->read_buffer,
535 &processed)) { 535 &processed)) {
536 /* serios internal error, close connection */ 536 /* serios internal error, close connection */
537 MHD_DLOG(session->daemon, 537 MHD_DLOG(connection->daemon,
538 "Internal application error, closing connection."); 538 "Internal application error, closing connection.");
539 CLOSE(session->socket_fd); 539 CLOSE(connection->socket_fd);
540 session->socket_fd = -1; 540 connection->socket_fd = -1;
541 return; 541 return;
542 } 542 }
543 /* dh left "processed" bytes in buffer for next time... */ 543 /* dh left "processed" bytes in buffer for next time... */
544 memmove(session->read_buffer, 544 memmove(connection->read_buffer,
545 &session->read_buffer[session->readLoc - processed], 545 &connection->read_buffer[connection->readLoc - processed],
546 processed); 546 processed);
547 if (session->uploadSize != -1) 547 if (connection->uploadSize != -1)
548 session->uploadSize -= (session->readLoc - processed); 548 connection->uploadSize -= (connection->readLoc - processed);
549 session->readLoc = processed; 549 connection->readLoc = processed;
550 if ( (session->uploadSize == 0) || 550 if ( (connection->uploadSize == 0) ||
551 ( (session->readLoc == 0) && 551 ( (connection->readLoc == 0) &&
552 (session->uploadSize == -1) && 552 (connection->uploadSize == -1) &&
553 (session->socket_fd == -1) ) ) { 553 (connection->socket_fd == -1) ) ) {
554 session->bodyReceived = 1; 554 connection->bodyReceived = 1;
555 session->readLoc = 0; 555 connection->readLoc = 0;
556 session->read_buffer_size = 0; 556 connection->read_buffer_size = 0;
557 free(session->read_buffer); 557 free(connection->read_buffer);
558 session->read_buffer = NULL; 558 connection->read_buffer = NULL;
559 } 559 }
560} 560}
561 561
@@ -567,54 +567,54 @@ MHD_call_session_handler(struct MHD_Session * session) {
567 * to handle reads. 567 * to handle reads.
568 */ 568 */
569int 569int
570MHD_session_handle_read(struct MHD_Session * session) { 570MHD_connection_handle_read(struct MHD_Connection * connection) {
571 int bytes_read; 571 int bytes_read;
572 void * tmp; 572 void * tmp;
573 573
574 if ( (session->readLoc >= session->read_buffer_size) && 574 if ( (connection->readLoc >= connection->read_buffer_size) &&
575 (session->headersReceived == 0) ) { 575 (connection->headersReceived == 0) ) {
576 /* need to grow read buffer */ 576 /* need to grow read buffer */
577 tmp = malloc(session->read_buffer_size * 2 + MHD_MAX_BUF_SIZE); 577 tmp = malloc(connection->read_buffer_size * 2 + MHD_MAX_BUF_SIZE);
578 memcpy(tmp, 578 memcpy(tmp,
579 session->read_buffer, 579 connection->read_buffer,
580 session->read_buffer_size); 580 connection->read_buffer_size);
581 session->read_buffer_size = session->read_buffer_size * 2 + MHD_MAX_BUF_SIZE; 581 connection->read_buffer_size = connection->read_buffer_size * 2 + MHD_MAX_BUF_SIZE;
582 if (session->read_buffer != NULL) 582 if (connection->read_buffer != NULL)
583 free(session->read_buffer); 583 free(connection->read_buffer);
584 session->read_buffer = tmp; 584 connection->read_buffer = tmp;
585 } 585 }
586 if (session->readLoc >= session->read_buffer_size) { 586 if (connection->readLoc >= connection->read_buffer_size) {
587 MHD_DLOG(session->daemon, 587 MHD_DLOG(connection->daemon,
588 "Unexpected call to %s.\n", 588 "Unexpected call to %s.\n",
589 __FUNCTION__); 589 __FUNCTION__);
590 return MHD_NO; 590 return MHD_NO;
591 } 591 }
592 bytes_read = RECV(session->socket_fd, 592 bytes_read = RECV(connection->socket_fd,
593 &session->read_buffer[session->readLoc], 593 &connection->read_buffer[connection->readLoc],
594 session->read_buffer_size - session->readLoc, 594 connection->read_buffer_size - connection->readLoc,
595 0); 595 0);
596 if (bytes_read < 0) { 596 if (bytes_read < 0) {
597 if (errno == EINTR) 597 if (errno == EINTR)
598 return MHD_NO; 598 return MHD_NO;
599 MHD_DLOG(session->daemon, 599 MHD_DLOG(connection->daemon,
600 "Failed to receive data: %s\n", 600 "Failed to receive data: %s\n",
601 STRERROR(errno)); 601 STRERROR(errno));
602 CLOSE(session->socket_fd); 602 CLOSE(connection->socket_fd);
603 session->socket_fd = -1; 603 connection->socket_fd = -1;
604 return MHD_YES; 604 return MHD_YES;
605 } 605 }
606 if (bytes_read == 0) { 606 if (bytes_read == 0) {
607 /* other side closed connection */ 607 /* other side closed connection */
608 if (session->readLoc > 0) 608 if (connection->readLoc > 0)
609 MHD_call_session_handler(session); 609 MHD_call_connection_handler(connection);
610 shutdown(session->socket_fd, SHUT_RD); 610 shutdown(connection->socket_fd, SHUT_RD);
611 return MHD_YES; 611 return MHD_YES;
612 } 612 }
613 session->readLoc += bytes_read; 613 connection->readLoc += bytes_read;
614 if (session->headersReceived == 0) 614 if (connection->headersReceived == 0)
615 MHD_parse_session_headers(session); 615 MHD_parse_connection_headers(connection);
616 if (session->headersReceived == 1) 616 if (connection->headersReceived == 1)
617 MHD_call_session_handler(session); 617 MHD_call_connection_handler(connection);
618 return MHD_YES; 618 return MHD_YES;
619} 619}
620 620
@@ -623,50 +623,50 @@ MHD_session_handle_read(struct MHD_Session * session) {
623 * for http-compiliance. 623 * for http-compiliance.
624 */ 624 */
625static void 625static void
626MHD_add_extra_headers(struct MHD_Session * session) { 626MHD_add_extra_headers(struct MHD_Connection * connection) {
627 const char * have; 627 const char * have;
628 char buf[128]; 628 char buf[128];
629 629
630 if (session->response->total_size == -1) { 630 if (connection->response->total_size == -1) {
631 have = MHD_get_response_header(session->response, 631 have = MHD_get_response_header(connection->response,
632 "Connection"); 632 "Connection");
633 if (have == NULL) 633 if (have == NULL)
634 MHD_add_response_header(session->response, 634 MHD_add_response_header(connection->response,
635 "Connection", 635 "Connection",
636 "close"); 636 "close");
637 } else if (NULL == MHD_get_response_header(session->response, 637 } else if (NULL == MHD_get_response_header(connection->response,
638 "Content-Length")) { 638 "Content-Length")) {
639 _REAL_SNPRINTF(buf, 639 _REAL_SNPRINTF(buf,
640 128, 640 128,
641 "%llu", 641 "%llu",
642 (unsigned long long) session->response->total_size); 642 (unsigned long long) connection->response->total_size);
643 MHD_add_response_header(session->response, 643 MHD_add_response_header(connection->response,
644 "Content-Length", 644 "Content-Length",
645 buf); 645 buf);
646 } 646 }
647} 647}
648 648
649/** 649/**
650 * Allocate the session's write buffer and 650 * Allocate the connection's write buffer and
651 * fill it with all of the headers from the 651 * fill it with all of the headers from the
652 * HTTPd's response. 652 * HTTPd's response.
653 */ 653 */
654static void 654static void
655MHD_build_header_response(struct MHD_Session * session) { 655MHD_build_header_response(struct MHD_Connection * connection) {
656 size_t size; 656 size_t size;
657 size_t off; 657 size_t off;
658 struct MHD_HTTP_Header * pos; 658 struct MHD_HTTP_Header * pos;
659 char code[32]; 659 char code[32];
660 char * data; 660 char * data;
661 661
662 MHD_add_extra_headers(session); 662 MHD_add_extra_headers(connection);
663 SPRINTF(code, 663 SPRINTF(code,
664 "HTTP/1.1 %u\r\n", 664 "HTTP/1.1 %u\r\n",
665 session->responseCode); 665 connection->responseCode);
666 off = strlen(code); 666 off = strlen(code);
667 /* estimate size */ 667 /* estimate size */
668 size = off + 2; /* extra \r\n at the end */ 668 size = off + 2; /* extra \r\n at the end */
669 pos = session->response->first_header; 669 pos = connection->response->first_header;
670 while (pos != NULL) { 670 while (pos != NULL) {
671 size += strlen(pos->header) + strlen(pos->value) + 4; /* colon, space, linefeeds */ 671 size += strlen(pos->header) + strlen(pos->value) + 4; /* colon, space, linefeeds */
672 pos = pos->next; 672 pos = pos->next;
@@ -676,7 +676,7 @@ MHD_build_header_response(struct MHD_Session * session) {
676 memcpy(data, 676 memcpy(data,
677 code, 677 code,
678 off); 678 off);
679 pos = session->response->first_header; 679 pos = connection->response->first_header;
680 while (pos != NULL) { 680 while (pos != NULL) {
681 SPRINTF(&data[off], 681 SPRINTF(&data[off],
682 "%s: %s\r\n", 682 "%s: %s\r\n",
@@ -690,8 +690,8 @@ MHD_build_header_response(struct MHD_Session * session) {
690 off += 2; 690 off += 2;
691 if (off != size) 691 if (off != size)
692 abort(); 692 abort();
693 session->write_buffer = data; 693 connection->write_buffer = data;
694 session->write_buffer_size = size; 694 connection->write_buffer_size = size;
695} 695}
696 696
697/** 697/**
@@ -701,53 +701,53 @@ MHD_build_header_response(struct MHD_Session * session) {
701 * call this function 701 * call this function
702 */ 702 */
703int 703int
704MHD_session_handle_write(struct MHD_Session * session) { 704MHD_connection_handle_write(struct MHD_Connection * connection) {
705 struct MHD_Response * response; 705 struct MHD_Response * response;
706 int ret; 706 int ret;
707 707
708 response = session->response; 708 response = connection->response;
709 if(response == NULL) { 709 if(response == NULL) {
710 MHD_DLOG(session->daemon, 710 MHD_DLOG(connection->daemon,
711 "Unexpected call to %s.\n", 711 "Unexpected call to %s.\n",
712 __FUNCTION__); 712 __FUNCTION__);
713 return MHD_NO; 713 return MHD_NO;
714 } 714 }
715 if (! session->headersSent) { 715 if (! connection->headersSent) {
716 if (session->write_buffer == NULL) 716 if (connection->write_buffer == NULL)
717 MHD_build_header_response(session); 717 MHD_build_header_response(connection);
718 ret = SEND(session->socket_fd, 718 ret = SEND(connection->socket_fd,
719 &session->write_buffer[session->writeLoc], 719 &connection->write_buffer[connection->writeLoc],
720 session->write_buffer_size - session->writeLoc, 720 connection->write_buffer_size - connection->writeLoc,
721 0); 721 0);
722 if (ret < 0) { 722 if (ret < 0) {
723 if (errno == EINTR) 723 if (errno == EINTR)
724 return MHD_YES; 724 return MHD_YES;
725 MHD_DLOG(session->daemon, 725 MHD_DLOG(connection->daemon,
726 "Failed to send data: %s\n", 726 "Failed to send data: %s\n",
727 STRERROR(errno)); 727 STRERROR(errno));
728 CLOSE(session->socket_fd); 728 CLOSE(connection->socket_fd);
729 session->socket_fd = -1; 729 connection->socket_fd = -1;
730 return MHD_YES; 730 return MHD_YES;
731 } 731 }
732 session->writeLoc += ret; 732 connection->writeLoc += ret;
733 if (session->writeLoc == session->write_buffer_size) { 733 if (connection->writeLoc == connection->write_buffer_size) {
734 session->writeLoc = 0; 734 connection->writeLoc = 0;
735 free(session->write_buffer); 735 free(connection->write_buffer);
736 session->write_buffer = NULL; 736 connection->write_buffer = NULL;
737 session->write_buffer_size = 0; 737 connection->write_buffer_size = 0;
738 session->headersSent = 1; 738 connection->headersSent = 1;
739 } 739 }
740 return MHD_YES; 740 return MHD_YES;
741 } 741 }
742 if (response->total_size <= session->messagePos) 742 if (response->total_size <= connection->messagePos)
743 abort(); /* internal error */ 743 abort(); /* internal error */
744 if (response->crc != NULL) 744 if (response->crc != NULL)
745 pthread_mutex_lock(&response->mutex); 745 pthread_mutex_lock(&response->mutex);
746 746
747 /* prepare send buffer */ 747 /* prepare send buffer */
748 if ( (response->data == NULL) || 748 if ( (response->data == NULL) ||
749 (response->data_start > session->messagePos) || 749 (response->data_start > connection->messagePos) ||
750 (response->data_start + response->data_size < session->messagePos) ) { 750 (response->data_start + response->data_size < connection->messagePos) ) {
751 if (response->data_size == 0) { 751 if (response->data_size == 0) {
752 if (response->data != NULL) 752 if (response->data != NULL)
753 free(response->data); 753 free(response->data);
@@ -755,20 +755,20 @@ MHD_session_handle_write(struct MHD_Session * session) {
755 response->data_size = MHD_MAX_BUF_SIZE; 755 response->data_size = MHD_MAX_BUF_SIZE;
756 } 756 }
757 ret = response->crc(response->crc_cls, 757 ret = response->crc(response->crc_cls,
758 session->messagePos, 758 connection->messagePos,
759 response->data, 759 response->data,
760 MAX(MHD_MAX_BUF_SIZE, 760 MAX(MHD_MAX_BUF_SIZE,
761 response->data_size - session->messagePos)); 761 response->data_size - connection->messagePos));
762 if (ret == -1) { 762 if (ret == -1) {
763 /* end of message, signal other side by closing! */ 763 /* end of message, signal other side by closing! */
764 response->data_size = session->messagePos; 764 response->data_size = connection->messagePos;
765 CLOSE(session->socket_fd); 765 CLOSE(connection->socket_fd);
766 session->socket_fd = -1; 766 connection->socket_fd = -1;
767 if (response->crc != NULL) 767 if (response->crc != NULL)
768 pthread_mutex_unlock(&response->mutex); 768 pthread_mutex_unlock(&response->mutex);
769 return MHD_YES; 769 return MHD_YES;
770 } 770 }
771 response->data_start = session->messagePos; 771 response->data_start = connection->messagePos;
772 response->data_size = ret; 772 response->data_size = ret;
773 if (ret == 0) { 773 if (ret == 0) {
774 if (response->crc != NULL) 774 if (response->crc != NULL)
@@ -778,54 +778,54 @@ MHD_session_handle_write(struct MHD_Session * session) {
778 } 778 }
779 779
780 /* transmit */ 780 /* transmit */
781 ret = SEND(session->socket_fd, 781 ret = SEND(connection->socket_fd,
782 &response->data[session->messagePos - response->data_start], 782 &response->data[connection->messagePos - response->data_start],
783 response->data_size - (session->messagePos - response->data_start), 783 response->data_size - (connection->messagePos - response->data_start),
784 0); 784 0);
785 if (response->crc != NULL) 785 if (response->crc != NULL)
786 pthread_mutex_unlock(&response->mutex); 786 pthread_mutex_unlock(&response->mutex);
787 if (ret < 0) { 787 if (ret < 0) {
788 if (errno == EINTR) 788 if (errno == EINTR)
789 return MHD_YES; 789 return MHD_YES;
790 MHD_DLOG(session->daemon, 790 MHD_DLOG(connection->daemon,
791 "Failed to send data: %s\n", 791 "Failed to send data: %s\n",
792 STRERROR(errno)); 792 STRERROR(errno));
793 CLOSE(session->socket_fd); 793 CLOSE(connection->socket_fd);
794 session->socket_fd = -1; 794 connection->socket_fd = -1;
795 return MHD_YES; 795 return MHD_YES;
796 } 796 }
797 session->messagePos += ret; 797 connection->messagePos += ret;
798 if (session->messagePos > response->data_size) 798 if (connection->messagePos > response->data_size)
799 abort(); /* internal error */ 799 abort(); /* internal error */
800 if (session->messagePos == response->data_size) { 800 if (connection->messagePos == response->data_size) {
801 if ( (session->bodyReceived == 0) || 801 if ( (connection->bodyReceived == 0) ||
802 (session->headersReceived == 0) ) 802 (connection->headersReceived == 0) )
803 abort(); /* internal error */ 803 abort(); /* internal error */
804 MHD_destroy_response(response); 804 MHD_destroy_response(response);
805 session->responseCode = 0; 805 connection->responseCode = 0;
806 session->response = NULL; 806 connection->response = NULL;
807 session->headersReceived = 0; 807 connection->headersReceived = 0;
808 session->headersSent = 0; 808 connection->headersSent = 0;
809 session->bodyReceived = 0; 809 connection->bodyReceived = 0;
810 session->messagePos = 0; 810 connection->messagePos = 0;
811 free(session->method); 811 free(connection->method);
812 session->method = NULL; 812 connection->method = NULL;
813 free(session->url); 813 free(connection->url);
814 session->url = NULL; 814 connection->url = NULL;
815 free(session->version); 815 free(connection->version);
816 session->version = NULL; 816 connection->version = NULL;
817 free(session->write_buffer); 817 free(connection->write_buffer);
818 session->write_buffer = NULL; 818 connection->write_buffer = NULL;
819 session->write_buffer_size = 0; 819 connection->write_buffer_size = 0;
820 if (session->read_close != 0) { 820 if (connection->read_close != 0) {
821 /* closed for reading => close for good! */ 821 /* closed for reading => close for good! */
822 CLOSE(session->socket_fd); 822 CLOSE(connection->socket_fd);
823 session->socket_fd = -1; 823 connection->socket_fd = -1;
824 } 824 }
825 } 825 }
826 return MHD_YES; 826 return MHD_YES;
827} 827}
828 828
829/* end of session.c */ 829/* end of connection.c */
830 830
831 831
diff --git a/src/daemon/session.h b/src/daemon/session.h
index 269c2f17..59b99004 100644
--- a/src/daemon/session.h
+++ b/src/daemon/session.h
@@ -19,23 +19,23 @@
19*/ 19*/
20 20
21/** 21/**
22 * @file session.h 22 * @file connection.h
23 * @brief Methods for managing sessions 23 * @brief Methods for managing connections
24 * @author Daniel Pittman 24 * @author Daniel Pittman
25 * @author Christian Grothoff 25 * @author Christian Grothoff
26 */ 26 */
27 27
28#ifndef SESSION_H 28#ifndef CONNECTION_H
29#define SESSION_H 29#define CONNECTION_H
30 30
31 31
32/** 32/**
33 * Obtain the select sets for this session. 33 * Obtain the select sets for this connection.
34 * 34 *
35 * @return MHD_YES on success 35 * @return MHD_YES on success
36 */ 36 */
37int 37int
38MHD_session_get_fdset(struct MHD_Session * session, 38MHD_connection_get_fdset(struct MHD_Connection * connection,
39 fd_set * read_fd_set, 39 fd_set * read_fd_set,
40 fd_set * write_fd_set, 40 fd_set * write_fd_set,
41 fd_set * except_fd_set, 41 fd_set * except_fd_set,
@@ -44,10 +44,10 @@ MHD_session_get_fdset(struct MHD_Session * session,
44 44
45/** 45/**
46 * Call the handler of the application for this 46 * Call the handler of the application for this
47 * session. 47 * connection.
48 */ 48 */
49void 49void
50MHD_call_session_handler(struct MHD_Session * session); 50MHD_call_connection_handler(struct MHD_Connection * connection);
51 51
52/** 52/**
53 * This function handles a particular connection when it has been 53 * This function handles a particular connection when it has been
@@ -56,7 +56,7 @@ MHD_call_session_handler(struct MHD_Session * session);
56 * to handle reads. 56 * to handle reads.
57 */ 57 */
58int 58int
59MHD_session_handle_read(struct MHD_Session * session); 59MHD_connection_handle_read(struct MHD_Connection * connection);
60 60
61 61
62/** 62/**
@@ -66,7 +66,7 @@ MHD_session_handle_read(struct MHD_Session * session);
66 * (multithreaded, external select, internal select) call this function 66 * (multithreaded, external select, internal select) call this function
67 */ 67 */
68int 68int
69MHD_session_handle_write(struct MHD_Session * session); 69MHD_connection_handle_write(struct MHD_Connection * connection);
70 70
71 71
72#endif 72#endif
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index b8209862..ae918b4a 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -133,19 +133,15 @@ extern "C" {
133 * used, the client wants control over the process and will call the 133 * used, the client wants control over the process and will call the
134 * appropriate microhttpd callbacks.<p> 134 * appropriate microhttpd callbacks.<p>
135 * 135 *
136 * Note that it is legal to specify that both IPv4 and IPv6
137 * should be used. However, if neither IPv4 nor IPv6 is
138 * specified, starting the daemon will fail.<p>
139 *
140 * Starting the daemon may also fail if a particular option is not 136 * Starting the daemon may also fail if a particular option is not
141 * implemented or not supported on the target platform (i.e. no 137 * implemented or not supported on the target platform (i.e. no
142 * support for SSL, threads or IPv6). 138 * support for SSL, threads or IPv6).
143 */ 139 */
144enum MHD_OPTION { 140enum MHD_FLAG {
145 /** 141 /**
146 * No options selected. 142 * No options selected.
147 */ 143 */
148 MHD_NO_OPTION = 0, 144 MHD_NO_FLAG = 0,
149 145
150 /** 146 /**
151 * Run in debug mode. If this flag is used, the 147 * Run in debug mode. If this flag is used, the
@@ -170,14 +166,29 @@ enum MHD_OPTION {
170 MHD_USE_SELECT_INTERNALLY = 8, 166 MHD_USE_SELECT_INTERNALLY = 8,
171 167
172 /** 168 /**
173 * Run using the IPv4 protocol 169 * Run using the IPv6 protocol (otherwise, MHD will
170 * just support IPv4).
171 */
172 MHD_USE_IPv6 = 16,
173
174};
175
176/**
177 * MHD options. Passed in the varargs portion
178 * of MHD_start_daemon.
179 */
180enum MHD_OPTION {
181
182 /**
183 * No more options / last option. This is used
184 * to terminate the VARARGs list.
174 */ 185 */
175 MHD_USE_IPv4 = 16, 186 MHD_OPTION_END = 0,
176 187
177 /** 188 /**
178 * Run using the IPv6 protocol 189 * FIXME: add options for buffer sizes here...
179 */ 190 */
180 MHD_USE_IPv6 = 32, 191
181}; 192};
182 193
183/** 194/**
@@ -215,7 +226,7 @@ enum MHD_ValueKind {
215 226
216struct MHD_Daemon; 227struct MHD_Daemon;
217 228
218struct MHD_Session; 229struct MHD_Connection;
219 230
220struct MHD_Response; 231struct MHD_Response;
221 232
@@ -238,6 +249,9 @@ typedef int
238 * callbacks to provide content to give back to the client and return 249 * callbacks to provide content to give back to the client and return
239 * an HTTP status code (i.e. 200 for OK, 404, etc.). 250 * an HTTP status code (i.e. 200 for OK, 404, etc.).
240 * 251 *
252 * @param url the requested url
253 * @param method the HTTP method used ("GET", "PUT", etc.)
254 * @param version the HTTP version string (i.e. "HTTP/1.1")
241 * @param upload_data_size set initially to the size of the 255 * @param upload_data_size set initially to the size of the
242 * upload_data provided; the method must update this 256 * upload_data provided; the method must update this
243 * value to the number of bytes NOT processed 257 * value to the number of bytes NOT processed
@@ -247,9 +261,10 @@ typedef int
247 */ 261 */
248typedef int 262typedef int
249(*MHD_AccessHandlerCallback)(void * cls, 263(*MHD_AccessHandlerCallback)(void * cls,
250 struct MHD_Session * session, 264 struct MHD_Connection * connection,
251 const char * url, 265 const char * url,
252 const char * method, 266 const char * method,
267 const char * version,
253 const char * upload_data, 268 const char * upload_data,
254 unsigned int * upload_data_size); 269 unsigned int * upload_data_size);
255 270
@@ -312,21 +327,25 @@ typedef void
312 327
313/** 328/**
314 * Start a webserver on the given port. 329 * Start a webserver on the given port.
330 * @param flags combination of MHD_FLAG values
315 * @param port port to bind to 331 * @param port port to bind to
316 * @param apc callback to call to check which clients 332 * @param apc callback to call to check which clients
317 * will be allowed to connect 333 * will be allowed to connect
318 * @param apc_cls extra argument to apc 334 * @param apc_cls extra argument to apc
319 * @param dh default handler for all URIs 335 * @param dh default handler for all URIs
320 * @param dh_cls extra argument to dh 336 * @param dh_cls extra argument to dh
337 * @param ... list of options (type-value pairs,
338 * terminated with MHD_OPTION_END).
321 * @return NULL on error, handle to daemon on success 339 * @return NULL on error, handle to daemon on success
322 */ 340 */
323struct MHD_Daemon * 341struct MHD_Daemon *
324MHD_start_daemon(unsigned int options, 342MHD_start_daemon(unsigned int flags,
325 unsigned short port, 343 unsigned short port,
326 MHD_AcceptPolicyCallback apc, 344 MHD_AcceptPolicyCallback apc,
327 void * apc_cls, 345 void * apc_cls,
328 MHD_AccessHandlerCallback dh, 346 MHD_AccessHandlerCallback dh,
329 void * dh_cls); 347 void * dh_cls,
348 ...);
330 349
331 350
332 351
@@ -401,10 +420,10 @@ MHD_unregister_handler(struct MHD_Daemon * daemon,
401 * @return number of entries iterated over 420 * @return number of entries iterated over
402 */ 421 */
403int 422int
404MHD_get_session_values(struct MHD_Session * session, 423MHD_get_connection_values(struct MHD_Connection * connection,
405 enum MHD_ValueKind kind, 424 enum MHD_ValueKind kind,
406 MHD_KeyValueIterator iterator, 425 MHD_KeyValueIterator iterator,
407 void * iterator_cls); 426 void * iterator_cls);
408 427
409/** 428/**
410 * Get a particular header value. If multiple 429 * Get a particular header value. If multiple
@@ -414,22 +433,22 @@ MHD_get_session_values(struct MHD_Session * session,
414 * @return NULL if no such item was found 433 * @return NULL if no such item was found
415 */ 434 */
416const char * 435const char *
417MHD_lookup_session_value(struct MHD_Session * session, 436MHD_lookup_connection_value(struct MHD_Connection * connection,
418 enum MHD_ValueKind kind, 437 enum MHD_ValueKind kind,
419 const char * key); 438 const char * key);
420 439
421/** 440/**
422 * Queue a response to be transmitted to the client (as soon as 441 * Queue a response to be transmitted to the client (as soon as
423 * possible). 442 * possible).
424 * 443 *
425 * @param session the session identifying the client 444 * @param connection the connection identifying the client
426 * @param status_code HTTP status code (i.e. 200 for OK) 445 * @param status_code HTTP status code (i.e. 200 for OK)
427 * @param response response to transmit 446 * @param response response to transmit
428 * @return MHD_NO on error (i.e. reply already sent), 447 * @return MHD_NO on error (i.e. reply already sent),
429 * MHD_YES on success or if message has been queued 448 * MHD_YES on success or if message has been queued
430 */ 449 */
431int 450int
432MHD_queue_response(struct MHD_Session * session, 451MHD_queue_response(struct MHD_Connection * connection,
433 unsigned int status_code, 452 unsigned int status_code,
434 struct MHD_Response * response); 453 struct MHD_Response * response);
435 454