essentials implemented

This commit is contained in:
Christian Grothoff
2007-06-13 21:57:36 +00:00
parent b0912d1929
commit 817a963a53
4 changed files with 117 additions and 55 deletions
+7 -5
View File
@@ -5,11 +5,6 @@ things need to be implemented (in list of importance)
before certain features can be used at all:
For ANYTHING:
=============
session.c:
- MHD_session_get_fdset (essentially not implemented)
For GET args:
=============
session.c:
@@ -26,6 +21,13 @@ For COOKIES:
session.c:
- MHD_parse_session_headers: take cookie header apart
For http-compliance:
====================
session.c:
- send proper error code back if headers are too long
(investigate what we should do with those headers,
read? give user control?)
For IPv6:
=========
daemon.c:
+18 -3
View File
@@ -163,7 +163,8 @@ MHD_handle_connection(void * data) {
if (con == NULL)
abort();
while (! con->daemon->shutdown) {
while ( (! con->daemon->shutdown) &&
(con->socket_fd != -1) ) {
FD_ZERO(&rs);
FD_ZERO(&ws);
FD_ZERO(&es);
@@ -189,8 +190,10 @@ MHD_handle_connection(void * data) {
(MHD_YES != MHD_session_handle_write(con)) ) )
break;
}
close(con->socket_fd);
con->socket_fd = -1;
if (con->socket_fd != -1) {
close(con->socket_fd);
con->socket_fd = -1;
}
return NULL;
}
@@ -260,6 +263,11 @@ MHD_accept_connection(struct MHD_Daemon * daemon) {
* Free resources associated with all closed sessions.
* (destroy responses, free buffers, etc.). A session
* is known to be closed if the socket_fd is -1.
*
* Also performs session actions that need to be run
* even if the session is not selectable (such as
* calling the application again with upload data when
* the upload data buffer is full).
*/
static void
MHD_cleanup_sessions(struct MHD_Daemon * daemon) {
@@ -295,6 +303,13 @@ MHD_cleanup_sessions(struct MHD_Daemon * daemon) {
MHD_destroy_response(pos->response);
free(pos);
}
if ( (pos->headersReceived == 1) &&
(pos->read_buffer_size == pos->readLoc) &&
(pos->readLoc > 0) )
MHD_call_session_handler(pos);
prev = pos;
pos = pos->next;
}
+85 -47
View File
@@ -109,7 +109,9 @@ MHD_queue_response(struct MHD_Session * session,
struct MHD_Response * response) {
if ( (session == NULL) ||
(response == NULL) ||
(session->response != NULL) )
(session->response != NULL) ||
(session->bodyReceived == 0) ||
(session->headers_received == 0) )
return MHD_NO;
MHD_increment_response_rc(response);
session->response = response;
@@ -129,13 +131,15 @@ MHD_session_get_fdset(struct MHD_Session * session,
fd_set * write_fd_set,
fd_set * except_fd_set,
int * max_fd) {
/* FIXME: need to be VERY careful here
determining when the socket is ready for
reading/writing; plenty of cases to handle!
(the current code is one big bug) */
FD_SET(session->socket_fd, read_fd_set);
FD_SET(session->socket_fd, write_fd_set);
if (session->socket_fd > *max_fd)
if ( (session->headers_received == 0) ||
(session->readLoc < session->read_buffer_size) )
FD_SET(session->socket_fd, read_fd_set);
if (session->response != NULL)
FD_SET(session->socket_fd, write_fd_set);
if ( (session->socket_fd > *max_fd) &&
( (session->headers_received == 0) ||
(session->readLoc < session->read_buffer_size) ||
(session->response != NULL) ) )
*max_fd = session->socket_fd;
return MHD_YES;
}
@@ -233,6 +237,7 @@ MHD_parse_session_headers(struct MHD_Session * session) {
httpType = strstr(uri, " ");
if (httpType != NULL)
httpType[0] = '\0';
/* FIXME: parse URI some more here */
session->url = strdup(uri);
/* do we want to do anything with httpType? */
free(line);
@@ -267,9 +272,9 @@ MHD_parse_session_headers(struct MHD_Session * session) {
hdr->kind = MHD_HEADER_KIND;
session->headers_received = hdr;
}
/* FIXME: here: find cookie header and parse that! */
if (session->bodyReceived == 0)
return;
/* FIXME: here: find cookie header and parse that! */
return;
DIE:
close(session->socket_fd);
@@ -294,6 +299,48 @@ MHD_find_access_handler(struct MHD_Session * session) {
return &session->daemon->default_handler;
}
/**
* Call the handler of the application for this
* session.
*/
void
MHD_call_session_handler(struct MHD_Session * session) {
struct MHD_Access_Handler * ah;
unsigned int processed;
if (session->headers_received == 0)
abort(); /* bad timing... */
ah = MHD_find_access_handler(session);
processed = session->readLoc;
if (MHD_NO == ah->dh(ah->dh_cls,
session,
session->url,
session->method,
session->read_buffer,
&processed)) {
/* serios internal error, close connection */
MHD_DLOG(session->daemon,
"Internal application error, closing connection.");
close(session->socket_fd);
session->socket_fd = -1;
return;
}
/* dh left "processed" bytes in buffer for next time... */
memmove(session->read_buffer,
&session->read_buffer[session->readLoc - processed],
processed);
session->readLoc = processed;
session->uploadSize -= processed;
if (session->uploadSize == 0) {
session->bodyReceived = 1;
session->readLoc = 0;
session->read_buffer_size = 0;
free(session->read_buffer);
session->read_buffer = NULL;
}
}
/**
* This function handles a particular connection when it has been
* determined that there is data to be read off a socket. All implementations
@@ -304,16 +351,10 @@ int
MHD_session_handle_read(struct MHD_Session * session) {
int bytes_read;
void * tmp;
struct MHD_Access_Handler * ah;
unsigned int processed;
if (session->bodyReceived) {
MHD_DLOG(session->daemon,
"Unexpected call to %s.\n",
__FUNCTION__);
return MHD_NO;
}
if (session->readLoc >= session->read_buffer_size) {
if ( (session->readLoc >= session->read_buffer_size) &&
(session->headers_received == 0) ) {
/* need to grow read buffer */
tmp = malloc(session->read_buffer_size * 2 + MHD_MAX_BUF_SIZE);
memcpy(tmp,
@@ -321,6 +362,12 @@ MHD_session_handle_read(struct MHD_Session * session) {
session->read_buffer_size);
session->read_buffer_size = session->read_buffer_size * 2 + MHD_MAX_BUF_SIZE;
}
if (session->readLoc >= session->read_buffer_size) {
MHD_DLOG(session->daemon,
"Unexpected call to %s.\n",
__FUNCTION__);
return MHD_NO;
}
bytes_read = recv(session->socket_fd,
&session->read_buffer[session->readLoc],
session->read_buffer_size - session->readLoc,
@@ -331,39 +378,24 @@ MHD_session_handle_read(struct MHD_Session * session) {
MHD_DLOG(session->daemon,
"Failed to receive data: %s\n",
strerror(errno));
return MHD_NO;
close(session->socket_fd);
session->socket_fd = -1;
return MHD_YES;
}
if (bytes_read == 0) {
/* other side closed connection */
/* FIXME: proper handling of end of upload!
If we were receiving an unbounded upload,
we should finish up nicely now! */
close(session->socket_fd);
session->socket_fd = -1;
return MHD_NO;
return MHD_YES;
}
session->readLoc += bytes_read;
if (session->headersReceived == 0)
MHD_parse_session_headers(session);
if (session->headersReceived == 1) {
ah = MHD_find_access_handler(session);
processed = session->readLoc;
if (MHD_NO == ah->dh(ah->dh_cls,
session,
session->url,
session->method,
session->read_buffer,
&processed)) {
/* serios error, close connection */
close(session->socket_fd);
session->socket_fd = -1;
return MHD_NO;
}
/* dh left "processed" bytes in buffer for next time... */
memmove(session->read_buffer,
&session->read_buffer[session->readLoc - processed],
processed);
session->readLoc = processed;
session->uploadSize -= processed;
/* FIXME: proper handling of end of upload! */
}
if (session->headersReceived == 1)
MHD_call_session_handler(session);
return MHD_YES;
}
@@ -447,7 +479,7 @@ MHD_session_handle_write(struct MHD_Session * session) {
strerror(errno));
close(session->socket_fd);
session->socket_fd = -1;
return MHD_NO;
return MHD_YES;
}
session->writeLoc += ret;
if (session->writeLoc == session->write_buffer_size) {
@@ -489,7 +521,7 @@ MHD_session_handle_write(struct MHD_Session * session) {
response->data_start = session->messagePos;
response->data_size = ret;
if (ret == 0)
return MHD_YES; /* or NO? */
return MHD_YES;
}
/* transmit */
@@ -499,17 +531,23 @@ MHD_session_handle_write(struct MHD_Session * session) {
0);
if (response->crc != NULL)
pthread_mutex_unlock(&response->mutex);
if (ret == -1) {
if (ret < 0) {
if (errno == EINTR)
return MHD_YES;
MHD_DLOG(session->daemon,
"Failed to send data: %s\n",
strerror(errno));
return MHD_NO;
close(session->socket_fd);
session->socket_fd = -1;
return MHD_YES;
}
session->messagePos += ret;
if (session->messagePos > response->data_size)
abort(); /* internal error */
if (session->messagePos == response->data_size) {
/* reset session, wait for next request! */
if ( (session->bodyReceived == 0) ||
(session->headers_received == 0) )
abort(); /* internal error */
MHD_destroy_response(response);
session->responseCode = 0;
session->response = NULL;
+7
View File
@@ -43,6 +43,13 @@ MHD_session_get_fdset(struct MHD_Session * session,
int * max_fd);
/**
* Call the handler of the application for this
* session.
*/
void
MHD_call_session_handler(struct MHD_Session * session);
/**
* This function handles a particular connection when it has been
* determined that there is data to be read off a socket. All implementations