fixing compile errors

This commit is contained in:
Christian Grothoff
2007-06-13 01:12:50 +00:00
parent 39eda678e0
commit baa26cd045
5 changed files with 325 additions and 360 deletions
+8 -20
View File
@@ -26,16 +26,6 @@
* @version 0.1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <stdarg>
#include <fcntl.h>
#include <pthread.h>
#include <netinet/in.h>
#include "microhttpd.h"
#include "internal.h"
#include "response.h"
@@ -120,10 +110,10 @@ MHD_unregister_handler(struct MHD_Daemon * daemon,
pos = daemon->handlers;
prev = NULL;
while (pos != NULL) {
if ( (dh == ah->dh) &&
(dh_cls == ah->dh_cls) &&
if ( (dh == pos->dh) &&
(dh_cls == pos->dh_cls) &&
(0 == strcmp(uri_prefix,
ah->uri_prefix)) ) {
pos->uri_prefix)) ) {
if (prev == NULL)
daemon->handlers = pos->next;
else
@@ -160,10 +150,10 @@ MHD_get_fdset(struct MHD_Daemon * daemon,
( (daemon->options & MHD_USE_THREAD_PER_CONNECTION) != 0) )
return MHD_NO;
FD_SET(daemon->socket_fd,
&daemon->read_fd_set);
read_fd_set);
if ( (*max_fd) < daemon->socket_fd)
*max_fd = daemon->socket_fd;
pos = daemon->session;
pos = daemon->connections;
while (pos != NULL) {
if (MHD_YES != MHD_session_get_fdset(pos,
read_fd_set,
@@ -249,7 +239,7 @@ MHD_accept_connection(struct MHD_Daemon * daemon) {
strerror(errno));
return MHD_NO;
}
if (MHD_NO == daemon->apc(mhd->apc_cls,
if (MHD_NO == daemon->apc(daemon->apc_cls,
&addr,
addrlen)) {
close(s);
@@ -485,16 +475,14 @@ MHD_start_daemon(unsigned int options,
retVal->port = port;
retVal->apc = apc;
retVal->apc_cls = apc_cls;
retVal->dh = dh;
retVal->dh_cls = dh_cls;
retVal->socket_fd = socket_fd;
retVal->default_handler.dh = dh;
retVal->default_handler.dh_cls = dh_cls;
retVal->default_henader.uri_prefix = "";
retVal->default_handler.uri_prefix = "";
retVal->default_handler.next = NULL;
if ( ( (0 != (options & MHD_USE_THREAD_PER_CONNECTION)) ||
(0 != (options & MHD_USE_SELECT_INTERNALLY)) ) &&
(0 != pthread_create(&daemon->pid,
(0 != pthread_create(&retVal->pid,
NULL,
&MHD_select_thread,
daemon)) ) {
+169 -2
View File
@@ -35,7 +35,8 @@
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <stdarg>
#include <stdarg.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <netinet/in.h>
@@ -45,7 +46,7 @@
#define MHD_MAX_BUF_SIZE 2048
#define MAX(a,b) ((a)<(b)) ? (b) : (a)
/**
* Header or cookie in HTTP request or response.
@@ -72,6 +73,172 @@ struct MHD_Access_Handler {
};
/**
* Representation of a response.
*/
struct MHD_Response {
/**
* Headers to send for the response. Initially
* the linked list is created in inverse order;
* the order should be inverted before sending!
*/
struct MHD_HTTP_Header * first_header;
/**
* Buffer pointing to data that we are supposed
* to send as a response.
*/
char * data;
/**
* Closure to give to the content reader
* free callback.
*/
void * crc_cls;
/**
* How do we get more data? NULL if we are
* given all of the data up front.
*/
MHD_ContentReaderCallback crc;
/**
* NULL if data must not be freed, otherwise
* either user-specified callback or "&free".
*/
MHD_ContentReaderFreeCallback crfc;
/**
* Mutex to synchronize access to data/size and
* reference counts.
*/
pthread_mutex_t mutex;
/**
* Reference count for this response. Free
* once the counter hits zero.
*/
unsigned int reference_count;
/**
* Set to -1 if size is not known.
*/
size_t total_size;
/**
* Size of data.
*/
size_t data_size;
/**
* At what offset in the stream is the
* beginning of data located?
*/
size_t data_start;
};
struct MHD_Session {
struct MHD_Session * next;
struct MHD_Daemon * daemon;
struct MHD_HTTP_Header * headers_received;
struct MHD_Response * response;
char * method;
char * url;
/**
* Buffer for reading requests.
*/
char * read_buffer;
/**
* Buffer for writing response.
*/
char * write_buffer;
/**
* Foreign address (of length addr_len).
*/
struct sockaddr_in * addr;
/**
* Thread for this session (if we are using
* one thread per connection).
*/
pthread_t pid;
size_t read_buffer_size;
size_t readLoc;
size_t write_buffer_size;
size_t writeLoc;
/**
* Current write position in the actual response
* (excluding headers, content only; should be 0
* while sending headers).
*/
size_t messagePos;
/**
* Remaining (!) number of bytes in the upload.
* Set to -1 for unknown (connection will close
* to indicate end of upload).
*/
size_t uploadSize;
/**
* Length of the foreign address.
*/
socklen_t addr_len;
/**
* Socket for this connection. Set to -1 if
* this connection has died (daemon should clean
* up in that case).
*/
int socket_fd;
/**
* Have we finished receiving all of the headers yet?
* Set to 1 once we are done processing all of the
* headers. Note that due to pipelining, it is
* possible that the NEXT request is already
* (partially) waiting in the read buffer.
*/
int headersReceived;
/**
* Have we finished receiving the data from a
* potential file-upload?
*/
int bodyReceived;
/**
* Have we finished sending all of the headers yet?
*/
int headersSent;
/**
* HTTP response code. Only valid if response object
* is already set.
*/
unsigned int responseCode;
};
struct MHD_Daemon {
struct MHD_Access_Handler * handlers;
+4 -84
View File
@@ -26,91 +26,11 @@
* @version 0.1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <stdarg>
#include <fcntl.h>
#include <pthread.h>
#include <netinet/in.h>
#include "microhttpd.h"
#include "response.h"
#include "internal.h"
#include "config.h"
/**
* Representation of a response.
*/
struct MHD_Response {
/**
* Headers to send for the response. Initially
* the linked list is created in inverse order;
* the order should be inverted before sending!
*/
struct MHD_HTTP_Header * first_header;
/**
* Buffer pointing to data that we are supposed
* to send as a response.
*/
void * data;
/**
* Closure to give to the content reader
* free callback.
*/
void * crc_cls;
/**
* How do we get more data? NULL if we are
* given all of the data up front.
*/
MHD_ContentReaderCallback crc;
/**
* NULL if data must not be freed, otherwise
* either user-specified callback or "&free".
*/
MHD_ContentReaderFreeCallback crfc;
/**
* Mutex to synchronize access to data/size and
* reference counts.
*/
pthread_mutex_t mutex;
/**
* Reference count for this response. Free
* once the counter hits zero.
*/
unsigned int reference_count;
/**
* Set to -1 if size is not known.
*/
size_t total_size;
/**
* Size of data.
*/
size_t data_size;
/**
* At what offset in the stream is the
* beginning of data located?
*/
size_t data_start;
};
/**
* Add a header line to the response.
*
@@ -134,9 +54,9 @@ MHD_add_response_header(struct MHD_Response * response,
(NULL != strstr(content, "\r")) ||
(NULL != strstr(content, "\n")) )
return MHD_NO;
hdr = malloc(sizeof(MHD_HTTP_Header));
hdr->header = STRDUP(header);
hdr->value = STRDUP(content);
hdr = malloc(sizeof(struct MHD_HTTP_Header));
hdr->header = strdup(header);
hdr->value = strdup(content);
hdr->kind = MHD_HEADER_KIND;
hdr->next = response->first_header;
response->first_header = hdr;
@@ -188,7 +108,7 @@ MHD_del_response_header(struct MHD_Response * response,
*/
int
MHD_get_response_headers(struct MHD_Response * response,
MHD_KeyValueIterator * iterator,
MHD_KeyValueIterator iterator,
void * iterator_cls) {
struct MHD_HTTP_Header * pos;
int numHeaders = 0;
+144 -157
View File
@@ -26,17 +26,6 @@
* @version 0.1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <stdarg>
#include <fcntl.h>
#include <pthread.h>
#include <netinet/in.h>
#include "microhttpd.h"
#include "session.h"
#include "response.h"
@@ -55,7 +44,7 @@
int
MHD_get_session_values(struct MHD_Session * session,
enum MHD_ValueKind kind,
MHD_KeyValueIterator * iterator,
MHD_KeyValueIterator iterator,
void * iterator_cls) {
int ret;
struct MHD_HTTP_Header * pos;
@@ -95,7 +84,6 @@ MHD_lookup_session_value(struct MHD_Session * session,
if (session == NULL)
return NULL;
ret = 0;
pos = session->headers_received;
while (pos != NULL) {
if ( (0 != (pos->kind & kind)) &&
@@ -145,7 +133,8 @@ MHD_session_get_fdset(struct MHD_Session * session,
int * max_fd) {
/* FIXME: need to be VERY careful here
determining when the socket is ready for
reading/writing; plenty of cases to handle! */
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)
@@ -165,6 +154,7 @@ MHD_session_get_fdset(struct MHD_Session * session,
*/
static void
MHD_parse_URL(struct MHD_Session * session) {
#if 0
char * working;
int pos,i;
@@ -179,10 +169,10 @@ MHD_parse_URL(struct MHD_Session * session) {
pos = 0;
session->documentName = session->headers[0]->value+pos;
#endif
}
/**
* This function is designed to parse the input buffer of a given session.
*
@@ -195,6 +185,7 @@ MHD_parse_URL(struct MHD_Session * session) {
*/
static void
MHD_parse_session_headers(struct MHD_Session * session) {
#if 0
const char * crlfcrlf = "\r\n\r\n";
const char * crlf = "\r\n";
@@ -249,8 +240,7 @@ MHD_parse_session_headers(struct MHD_Session * session) {
session->headers[session->firstFreeHeader++] = newHeader;
curTok = strtok_r(NULL, crlf, &saveptr);
}
return numBytes;
#endif
}
@@ -269,7 +259,7 @@ MHD_find_access_handler(struct MHD_Session * session) {
* (multithreaded, external select, internal select) call this function
* to handle reads.
*/
static int
int
MHD_session_handle_read(struct MHD_Session * session) {
int bytes_read;
void * tmp;
@@ -322,8 +312,8 @@ MHD_session_handle_read(struct MHD_Session * session) {
return MHD_NO;
}
/* dh left "processed" bytes in buffer for next time... */
memmove(session->readBuffer,
&session->readBuffer[session->readLoc - processed],
memmove(session->read_buffer,
&session->read_buffer[session->readLoc - processed],
processed);
session->readLoc = processed;
session->uploadSize -= processed;
@@ -332,157 +322,154 @@ MHD_session_handle_read(struct MHD_Session * session) {
return MHD_YES;
}
/**
* Allocate the session's write buffer and
* fill it with all of the headers from the
* HTTPd's response.
*/
static void
MHD_build_header_response(struct MHD_Session * session) {
size_t size;
size_t off;
struct MHD_HTTP_Header * pos;
char code[32];
char * data;
sprintf(code,
"HTTP/1.1 %u\r\n",
session->responseCode);
off = strlen(code);
/* estimate size */
size = off + 2; /* extra \r\n at the end */
pos = session->response->first_header;
while (pos != NULL) {
size += strlen(pos->header) + strlen(pos->value) + 4; /* colon, space, linefeeds */
pos = pos->next;
}
/* produce data */
data = malloc(size);
memcpy(data,
code,
off);
pos = session->response->first_header;
while (pos != NULL) {
sprintf(&data[off],
"%s: %s\r\n",
pos->header,
pos->value);
off += strlen(pos->header) + strlen(pos->value) + 4;
pos = pos->next;
}
if (off != size)
abort();
session->write_buffer = data;
session->write_buffer_size = size;
}
/**
* This function was created to handle writes to sockets when it has been
* determined that the socket can be written to. If there is no data
* to be written, however, the function call does nothing. All implementations
* (multithreaded, external select, internal select) call this function
* This function was created to handle writes to sockets when it has
* been determined that the socket can be written to. All
* implementations (multithreaded, external select, internal select)
* call this function
*/
int
MHD_session_handle_write(struct MHD_Session * session) {
struct MHD_Response * response;
int i;
char * buffer[2048];
char * responseMessage;
int numBytesInMessage;
int ret;
response = session->response;
if(response == NULL) {
/* FIXME: LOG: why are we here? */
return MHD_NO;
}
numBytesInMessage = 25;
responseMessage = malloc(25);
if (! session->headersSent) {
if (session->write_buffer == NULL)
MHD_build_header_response(session);
ret = send(session->socket_fd,
&session->write_buffer[session->writeLoc],
session->write_buffer_size - session->writeLoc,
0);
if (ret < 0) {
if (errno == EINTR)
return MHD_YES;
/* FIXME: log error */
close(session->socket_fd);
session->socket_fd = -1;
return MHD_NO;
}
session->writeLoc += ret;
if (session->writeLoc == session->write_buffer_size) {
session->writeLoc = 0;
free(session->write_buffer);
session->write_buffer = NULL;
session->write_buffer_size = 0;
session->headersSent = 1;
}
return MHD_YES;
}
if (response->total_size <= session->messagePos)
abort(); /* internal error */
if (response->crc != NULL)
pthread_mutex_lock(&response->mutex);
pthread_mutex_lock(&response->mutex);
if(!response->headersSent) {
sprintf(responseMessage, "HTTP/1.1 %i Go to hell!\r\n", response->responseCode);
fprintf(stderr, "%s\n", responseMessage);
if(send(session->socket_fd, responseMessage, strlen(responseMessage), 0) != strlen(responseMessage)) {
fprintf(stderr, "Error! could not send an entire header in one call to send! unable to handle this case as of this time.\n");
pthread_mutex_unlock(&response->mutex);
return MHD_NO;
}
for(i = 0; i < MHD_MAX_HEADERS; i++) {
if(response->headers[i] == NULL)
continue;
if(strlen(response->headers[i]->header) + strlen(response->headers[i]->value) + 5 > numBytesInMessage) {
free(responseMessage);
responseMessage = malloc(strlen(response->headers[i]->header) + strlen(response->headers[i]->value) + 5);
if(responseMessage == NULL) {
if(daemon->options & MHD_USE_DEBUG)
fprintf(stderr, "Error allocating memory!\n");
pthread_mutex_unlock(&response->mutex);
return MHD_NO;
}
numBytesInMessage = strlen(response->headers[i]->header) + strlen(response->headers[i]->value) + 5;
}
sprintf(responseMessage, "%s: %s\r\n", response->headers[i]->header, response->headers[i]->value);
fprintf(stderr, "%s\n", responseMessage);
if(send(session->socket_fd, responseMessage, strlen(responseMessage), 0) != strlen(responseMessage)) {
fprintf(stderr, "Error! could not send an entire header in one call to send! unable to handle this case as of this time.\n");
pthread_mutex_unlock(&response->mutex);
return MHD_NO;
}
}
response->headersSent = 1;
}
if(response->data != NULL) {
if(response->bytesSentSoFar == 0) {
if(numBytesInMessage < 32) {
free(responseMessage);
responseMessage = malloc(32);
if(responseMessage == NULL) {
if(daemon->options & MHD_USE_DEBUG)
fprintf(stderr, "Error allocating memory!\n");
pthread_mutex_unlock(&response->mutex);
return MHD_NO;
}
}
sprintf(responseMessage, "Content-length: %llu\r\n\r\n", (unsigned long long)response->size);
fprintf(stderr, "%s\n", responseMessage);
if(send(session->socket_fd, responseMessage, strlen(responseMessage),0)!= strlen(responseMessage)) {
fprintf(stderr, "Error! could not send an entire header in one call to send! unable to handle this case as of this time.\n");
pthread_mutex_unlock(&response->mutex);
return MHD_NO;
}
}
i = send(session->socket_fd, response->data+response->bytesSentSoFar, response->size-response->bytesSentSoFar,0);
response->bytesSentSoFar += i;
fprintf(stderr, "Sent %i bytes of data\nTotal to send is %llu bytes\n", i, (unsigned long long)response->size);
if(response->bytesSentSoFar == response->size) {
session->currentResponses[session->currentResponse] = NULL;
session->currentResponse = (session->currentResponse + 1) % MHD_MAX_RESPONSE;
response->currentSession = NULL;
if(response->freeWhenFinished) {
pthread_mutex_unlock(&response->mutex);
MHD_destroy_response(response);
}
/*THIS NEEDS TO BE HANDLED ANOTHER WAY!!! TIMEOUT, ect..., as of now this is the only way to get test case to work
* since client never disconnects on their own!
*/
if(session->currentResponses[session->currentResponse] == NULL) {
MHD_destroy_session(session);
daemon->connections[connection_id] = NULL;
return MHD_NO;
}
}
} else {
if(response->crc == NULL) {
pthread_mutex_unlock(&response->mutex);
return MHD_NO;
}
if(response->bytesSentSoFar == 0) {
if(send(session->socket_fd, "\r\n", response->size,0) != 2) {
fprintf(stderr, "Error! could not send an entire header in one call to send! unable to handle this case as of this time.\n");
pthread_mutex_unlock(&response->mutex);
return MHD_NO;
}
}
memset(buffer, 0, 2048);
i = response->crc(response->crc_cls, response->bytesSentSoFar, (char *)buffer, 2048);
if(i == -1) {
pthread_mutex_unlock(&response->mutex);
session->currentResponses[session->currentResponse] = NULL;
session->currentResponse = (session->currentResponse + 1) % MHD_MAX_RESPONSE;
response->currentSession = NULL;
if(response->freeWhenFinished) {
pthread_mutex_unlock(&response->mutex);
MHD_destroy_response(response);
}
/*THIS NEEDS TO BE HANDLED ANOTHER WAY!!! TIMEOUT, ect..., as of now this is the only way to get test case to work
* since client never disconnects on their own!
*/
if(session->currentResponses[session->currentResponse] == NULL) {
MHD_destroy_session(session);
daemon->connections[connection_id] = NULL;
return MHD_NO;
}
} else {
i = send(session->socket_fd, buffer, i,0);
response->bytesSentSoFar += i;
}
}
pthread_mutex_unlock(&response->mutex);
return MHD_YES;
/* prepare send buffer */
if ( (response->data == NULL) ||
(response->data_start > session->messagePos) ||
(response->data_start + response->data_size < session->messagePos) ) {
if (response->data_size == 0) {
if (response->data != NULL)
free(response->data);
response->data = malloc(MHD_MAX_BUF_SIZE);
response->data_size = MHD_MAX_BUF_SIZE;
}
ret = response->crc(response->crc_cls,
session->messagePos,
response->data,
MAX(MHD_MAX_BUF_SIZE,
response->data_size - session->messagePos));
if (ret == -1) {
/* end of message, signal other side by closing! */
response->data_size = session->messagePos;
close(session->socket_fd);
session->socket_fd = -1;
return MHD_YES;
}
response->data_start = session->messagePos;
response->data_size = ret;
if (ret == 0)
return MHD_YES; /* or NO? */
}
/* transmit */
ret = send(session->socket_fd,
&response->data[session->messagePos - response->data_start],
response->data_size - (session->messagePos - response->data_start),
0);
if (response->crc != NULL)
pthread_mutex_unlock(&response->mutex);
if (ret == -1) {
if (errno == EINTR)
return MHD_YES;
/* FIXME: log */
return MHD_NO;
}
session->messagePos += ret;
if (session->messagePos == response->data_size) {
/* reset session, wait for next request! */
MHD_destroy_response(response);
session->responseCode = 0;
session->response = NULL;
session->headersReceived = 0;
session->headersSent = 0;
session->bodyReceived = 0;
session->messagePos = 0;
free(session->write_buffer);
session->write_buffer = NULL;
session->write_buffer_size = 0;
}
return MHD_YES;
}
/* end of session.c */
-97
View File
@@ -30,103 +30,6 @@
#define SESSION_H
struct MHD_Session {
struct MHD_Session * next;
struct MHD_Daemon * daemon;
struct MHD_HTTP_Header * headers_received;
struct MHD_Response * response;
char * method;
char * url;
/**
* Buffer for reading requests.
*/
void * read_buffer;
/**
* Buffer for writing response.
*/
void * write_buffer;
/**
* Foreign address (of length addr_len).
*/
struct sockaddr_in * addr;
/**
* Thread for this session (if we are using
* one thread per connection).
*/
pthread_t pid;
size_t read_buffer_size;
size_t readLoc;
size_t write_buffer_size;
size_t writeLoc;
/**
* Current write position in the actual response
* (excluding headers, content only; should be 0
* while sending headers).
*/
size_t messagePos;
/**
* Remaining (!) number of bytes in the upload.
* Set to -1 for unknown (connection will close
* to indicate end of upload).
*/
size_t uploadSize;
/**
* Length of the foreign address.
*/
socklen_t addr_len;
/**
* Socket for this connection. Set to -1 if
* this connection has died (daemon should clean
* up in that case).
*/
int socket_fd;
/**
* Have we finished receiving all of the headers yet?
* Set to 1 once we are done processing all of the
* headers. Note that due to pipelining, it is
* possible that the NEXT request is already
* (partially) waiting in the read buffer.
*/
int headersReceived;
/**
* Have we finished receiving the data from a
* potential file-upload?
*/
int bodyReceived;
/**
* Have we finished sending all of the headers yet?
*/
int headersSent;
/**
* HTTP response code. Only valid if response object
* is already set.
*/
unsigned int responseCode;
};
/**
* Obtain the select sets for this session.
*