Added interface for the file upload
This commit is contained in:
parent
54dd5bae12
commit
6dfd30e508
|
@ -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
|
||||
|
|
|
@ -20,6 +20,8 @@ struct ConnectionState {
|
|||
char localFileName[PATH_MAX];
|
||||
struct stat targetStat;
|
||||
|
||||
uint8_t uploadRequest;
|
||||
|
||||
FILE *upload_fd;
|
||||
|
||||
enum ResultCode result;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
39
src/main.c
39
src/main.c
|
@ -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.",
|
||||
|
|
Loading…
Reference in a new issue