mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
fixing compile errors
This commit is contained in:
+8
-20
@@ -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
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user