Added interface for the file upload

This commit is contained in:
Thomas Kolb 2013-08-19 18:27:19 +02:00
parent 54dd5bae12
commit 6dfd30e508
5 changed files with 62 additions and 7 deletions

View file

@ -11,6 +11,6 @@
#ifndef DIRLISTING_H
#define DIRLISTING_H
char* create_dirlisting(const char *url, const char *localpath);
char* create_dirlisting(const char *url, const char *localpath, int uploadEnabled);
#endif // DIRLISTING_H

View file

@ -20,6 +20,8 @@ struct ConnectionState {
char localFileName[PATH_MAX];
struct stat targetStat;
uint8_t uploadRequest;
FILE *upload_fd;
enum ResultCode result;

View file

@ -87,4 +87,18 @@
" </ul>" \
FOOTER
#define UPLOAD_FORM \
HEADER1 \
" <title>Upload</title>" \
HEADER2 \
" <h1>Upload</h1>" \
" <p>You can upload a file to the current directory here.<p>" \
" <p>" \
" <form method=\"POST\" action=\".\" enctype=\"multipart/form-data\">" \
" <input name=\"data\" type=\"file\" size=\"30\">" \
" <input type=\"submit\" value=\"Go!\">" \
" </form>" \
" </p>" \
FOOTER
#endif // TEMPLATES_H

View file

@ -63,7 +63,7 @@ static int compare_entries(const void *sp1,const void *sp2 ) {
return( strcasecmp(e1->name, e2->name) );
}
char* gen_html(const char *url, struct Entry *entries, size_t numentries) {
char* gen_html(const char *url, struct Entry *entries, size_t numentries, int uploadEnabled) {
char *result;
size_t allocated;
size_t i;
@ -198,12 +198,18 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries) {
}
strcat(result, "</ul>");
if(uploadEnabled) {
strcat(result, "<h2>Upload</h2>");
strcat(result, "<p><a href=\"?upload=1\">Upload a file to this directory</a></p>");
}
strcat(result, FOOTER);
return result;
}
char* create_dirlisting(const char *url, const char *localpath) {
char* create_dirlisting(const char *url, const char *localpath, int uploadEnabled) {
char *result;
struct Entry *entries;
@ -288,7 +294,7 @@ char* create_dirlisting(const char *url, const char *localpath) {
qsort(entries, numentries, sizeof(struct Entry), compare_entries);
result = gen_html(url, entries, numentries);
result = gen_html(url, entries, numentries, uploadEnabled);
for(i = 0; i < numentries; i++) {
if(entries[i].flags & FLG_USED) free(entries[i].name);

View file

@ -55,6 +55,7 @@ magic_t magicCookie;
#endif
int running = 1;
int uploadEnabled = 1;
void request_completed(void *cls,
struct MHD_Connection * connection,
@ -208,7 +209,7 @@ int serv_directory(struct MHD_Connection *connection, struct ConnectionState *co
LOG(LVL_DEBUG, "Generating directory listing for %s.", connstate->localFileName);
char *result = create_dirlisting(connstate->cleanedURL, connstate->localFileName);
char *result = create_dirlisting(connstate->cleanedURL, connstate->localFileName, uploadEnabled);
if(!result) {
LOG(LVL_ERR, "Failed to generate dirlisting for %s.", connstate->localFileName);
return MHD_queue_response(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, error500Response);
@ -259,7 +260,13 @@ int serv_result_page(struct MHD_Connection *connection, struct ConnectionState *
char *buffer = malloc(strlen(HEADER1 HEADER2 FOOTER) + 1024);
sprintf(buffer, HEADER1 "<title>%s</title>" HEADER2 "<h1>%s</h1><p>%s</p>" FOOTER,
sprintf(buffer,
HEADER1
"<title>%s</title>"
HEADER2
"<h1>%s</h1><p>%s</p>"
"<p><a href=\".\">Back to the directory listing.</a></p>"
FOOTER,
title, title, message);
response = MHD_create_response_from_buffer(
@ -333,6 +340,24 @@ static int post_processor(void *cls,
return MHD_NO;
}
int key_value_iterator(void *cls,
enum MHD_ValueKind kind,
const char *key, const char *value) {
struct ConnectionState *connstate = (struct ConnectionState*)cls;
if(kind == MHD_GET_ARGUMENT_KIND) {
if(strcmp(key, "upload") == 0) {
connstate->uploadRequest = 1;
return MHD_NO; // this is the only argument we search for
}
return MHD_YES;
} else {
return MHD_NO;
}
}
static int connection_handler(void * cls,
struct MHD_Connection *connection,
const char *url,
@ -351,6 +376,7 @@ static int connection_handler(void * cls,
connstate->result = RC_OK;
connstate->upload_fd = NULL;
connstate->uploadRequest = 0;
// set the local file name
strncpy(connstate->localFileName, shareRoot, PATH_MAX);
@ -366,6 +392,9 @@ static int connection_handler(void * cls,
method, url, connstate->localFileName);
if (0 == strcmp(method, "GET") || 0 == strcmp(method, "HEAD")) {
// process GET arguments
MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, key_value_iterator, connstate);
connstate->postProcessor = NULL;
connstate->requestType = GET;
} else if(0 == strcmp(method, "POST")) {
@ -413,7 +442,11 @@ static int connection_handler(void * cls,
if(S_ISREG(connstate->targetStat.st_mode)) {
return serv_regular_file(connection, connstate);
} else if(S_ISDIR(connstate->targetStat.st_mode)) {
return serv_directory(connection, connstate);
if(connstate->uploadRequest) {
return MHD_queue_response(connection, MHD_HTTP_OK, uploadFormResponse);
} else {
return serv_directory(connection, connstate);
}
} else {
LOG(LVL_WARN,
"%s is neither a directory nor a regular file. Don't allow the access.",