Moved content generators from connection handler to separate functions
This commit is contained in:
parent
1a30d22de8
commit
eb16317dff
103
main.c
103
main.c
|
@ -53,6 +53,61 @@ void request_completed(void *cls,
|
||||||
free(connstate);
|
free(connstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int serv_regular_file(struct MHD_Connection *connection, struct ConnectionState *connstate) {
|
||||||
|
struct MHD_Response *response;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
LOG(LVL_DEBUG, "Serving %s as a regular file.", connstate->localFileName);
|
||||||
|
|
||||||
|
// open a file descriptor to the file
|
||||||
|
int fd = open(connstate->localFileName, O_RDONLY);
|
||||||
|
|
||||||
|
if(fd == -1) {
|
||||||
|
LOG(LVL_ERR, "Cannot open %s: %s",
|
||||||
|
connstate->localFileName, strerror(errno));
|
||||||
|
|
||||||
|
return MHD_queue_response(connection, MHD_HTTP_FORBIDDEN, error403Response);
|
||||||
|
}
|
||||||
|
|
||||||
|
// no error so far -> serve the file
|
||||||
|
response = MHD_create_response_from_fd(
|
||||||
|
connstate->targetStat.st_size,
|
||||||
|
fd);
|
||||||
|
|
||||||
|
#ifdef HAVE_MAGIC
|
||||||
|
// if libmagic is available, determine the correct MIME type for the file
|
||||||
|
const char *mimeType = magic_file(magicCookie, connstate->localFileName);
|
||||||
|
LOG(LVL_DEBUG, "MIME type for %s: %s", connstate->localFileName, mimeType);
|
||||||
|
MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, mimeType);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
|
||||||
|
MHD_destroy_response(response);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int serv_directory(struct MHD_Connection *connection, struct ConnectionState *connstate) {
|
||||||
|
struct MHD_Response *response;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
LOG(LVL_DEBUG, "Generating directory listing for %s.", connstate->localFileName);
|
||||||
|
|
||||||
|
char *result = create_dirlisting(connstate->cleanedURL, connstate->localFileName);
|
||||||
|
if(!result) {
|
||||||
|
LOG(LVL_ERR, "Failed to generate dirlisting for %s.", connstate->localFileName);
|
||||||
|
return MHD_queue_response(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, error500Response);
|
||||||
|
}
|
||||||
|
|
||||||
|
response = MHD_create_response_from_buffer(
|
||||||
|
strlen(result), result, MHD_RESPMEM_MUST_FREE);
|
||||||
|
|
||||||
|
MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, "text/html");
|
||||||
|
|
||||||
|
ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
|
||||||
|
MHD_destroy_response(response);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int connection_handler(void * cls,
|
static int connection_handler(void * cls,
|
||||||
struct MHD_Connection *connection,
|
struct MHD_Connection *connection,
|
||||||
const char *url,
|
const char *url,
|
||||||
|
@ -63,9 +118,6 @@ static int connection_handler(void * cls,
|
||||||
void **ptr) {
|
void **ptr) {
|
||||||
struct ConnectionState *connstate;
|
struct ConnectionState *connstate;
|
||||||
|
|
||||||
struct MHD_Response *response;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (0 != strcmp(method, "GET")) {
|
if (0 != strcmp(method, "GET")) {
|
||||||
LOG(LVL_WARN, "Unexpected method: %s.", method);
|
LOG(LVL_WARN, "Unexpected method: %s.", method);
|
||||||
return MHD_NO;
|
return MHD_NO;
|
||||||
|
@ -118,50 +170,9 @@ static int connection_handler(void * cls,
|
||||||
}
|
}
|
||||||
|
|
||||||
if(S_ISREG(connstate->targetStat.st_mode)) {
|
if(S_ISREG(connstate->targetStat.st_mode)) {
|
||||||
LOG(LVL_DEBUG, "Serving %s as a regular file.", connstate->localFileName);
|
return serv_regular_file(connection, connstate);
|
||||||
|
|
||||||
// open a file descriptor to the file
|
|
||||||
int fd = open(connstate->localFileName, O_RDONLY);
|
|
||||||
|
|
||||||
if(fd == -1) {
|
|
||||||
LOG(LVL_ERR, "Cannot open %s: %s",
|
|
||||||
connstate->localFileName, strerror(errno));
|
|
||||||
|
|
||||||
return MHD_queue_response(connection, MHD_HTTP_FORBIDDEN, error403Response);
|
|
||||||
}
|
|
||||||
|
|
||||||
// no error so far -> serve the file
|
|
||||||
response = MHD_create_response_from_fd(
|
|
||||||
connstate->targetStat.st_size,
|
|
||||||
fd);
|
|
||||||
|
|
||||||
#ifdef HAVE_MAGIC
|
|
||||||
// if libmagic is available, determine the correct MIME type for the file
|
|
||||||
const char *mimeType = magic_file(magicCookie, connstate->localFileName);
|
|
||||||
LOG(LVL_DEBUG, "MIME type for %s: %s", connstate->localFileName, mimeType);
|
|
||||||
MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, mimeType);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
|
|
||||||
MHD_destroy_response(response);
|
|
||||||
return ret;
|
|
||||||
} else if(S_ISDIR(connstate->targetStat.st_mode)) {
|
} else if(S_ISDIR(connstate->targetStat.st_mode)) {
|
||||||
LOG(LVL_DEBUG, "Generating directory listing for %s.", connstate->localFileName);
|
return serv_directory(connection, connstate);
|
||||||
|
|
||||||
char *result = create_dirlisting(connstate->cleanedURL, connstate->localFileName);
|
|
||||||
if(!result) {
|
|
||||||
LOG(LVL_ERR, "Failed to generate dirlisting for %s.", connstate->localFileName);
|
|
||||||
return MHD_queue_response(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, error500Response);
|
|
||||||
}
|
|
||||||
|
|
||||||
response = MHD_create_response_from_buffer(
|
|
||||||
strlen(result), result, MHD_RESPMEM_MUST_FREE);
|
|
||||||
|
|
||||||
MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, "text/html");
|
|
||||||
|
|
||||||
ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
|
|
||||||
MHD_destroy_response(response);
|
|
||||||
return ret;
|
|
||||||
} else {
|
} else {
|
||||||
LOG(LVL_WARN,
|
LOG(LVL_WARN,
|
||||||
"%s is neither a directory nor a regular file. Don't allow the access.",
|
"%s is neither a directory nor a regular file. Don't allow the access.",
|
||||||
|
|
Loading…
Reference in a new issue