From: Nishi Date: Thu, 22 Aug 2024 04:26:35 +0000 (+0000) Subject: multipart kinda works X-Git-Url: https://git.chaotic.ninja/gitweb/nishi/?a=commitdiff_plain;h=98017a11e463cc1478389e3b11c8a7ff56f7cb83;p=repoview.git multipart kinda works git-svn-id: file:///raid/svn-personal/repoview/trunk@41 7e8b2a19-8934-dd40-8cb3-db22cdd5a80f --- diff --git a/CGI/Makefile b/CGI/Makefile index 28bebfe..ed02299 100644 --- a/CGI/Makefile +++ b/CGI/Makefile @@ -5,7 +5,7 @@ include $(PWD)/Platform/$(PLATFORM).mk .PHONY: all clean .SUFFIXES: .c .o -OBJS = main.o sanity.o version.o util.o query.o page.o sha512.o md5.o repo.o $(EXTOBJS) +OBJS = main.o sanity.o version.o util.o query.o page.o sha512.o md5.o repo.o multipart.o $(EXTOBJS) all: repoview.cgi diff --git a/CGI/main.c b/CGI/main.c index e716878..dd7171e 100644 --- a/CGI/main.c +++ b/CGI/main.c @@ -10,6 +10,7 @@ #include "rv_util.h" #include "rv_db.h" #include "rv_auth.h" +#include "rv_multipart.h" #include #include @@ -26,6 +27,7 @@ int main() { postdata = malloc(1); postdata[0] = 0; int hasauth = 0; + int use_multi = 0; char* type = getenv("CONTENT_TYPE"); if(type == NULL) { type = rv_strdup(""); @@ -49,16 +51,18 @@ int main() { type[i] = 0; i++; bool found = false; - rv_error_http(); + char* bd = NULL; for(; type[i] != 0; i++) { if(type[i] != ' ' && type[i] != '\t') { int j; char* boundary = type + i; - for(j = 0; boundary[j] != 0; j++){ - if(boundary[j] == '='){ + for(j = 0; boundary[j] != 0; j++) { + if(boundary[j] == '=') { boundary[j] = 0; - printf("%s\n%s\n", boundary, boundary + j + 1); - found = true; + if(strcmp(boundary, "boundary") == 0) { + bd = rv_strdup(boundary + j + 1); + found = true; + } break; } } @@ -66,27 +70,62 @@ int main() { } } if(!found) { + rv_error_http(); printf("Bad multipart/form-data. Parsing fail."); goto freeall; + } else { + char* multipart = NULL; + unsigned long long length = 0; + char buffer[512]; + while(1) { + int len = fread(buffer, 1, 512, stdin); + if(length > 0) { + char* old = multipart; + multipart = malloc(length + len); + int i; + for(i = 0; i < length; i++) { + multipart[i] = old[i]; + } + free(old); + memcpy(multipart + length, buffer, len); + length += len; + } else { + length += len; + multipart = malloc(length); + memcpy(multipart, buffer, len); + } + if(feof(stdin)) break; + } + if(multipart != NULL) { + rv_parse_multipart(multipart, bd, length); + free(multipart); + } } + if(bd != NULL) free(bd); + use_multi = 1; break; } } } - rv_parse_query(postdata); - rv_save_query('P'); + if(use_multi == 0) { + rv_parse_query(postdata); + rv_save_query('P'); + } rv_init_auth(); hasauth = 1; rv_process_page(); printf("Content-Type: text/html\r\n"); printf("\r\n"); rv_print_page(); - rv_load_query('P'); - rv_free_query(); + if(use_multi == 0) { + rv_load_query('P'); + rv_free_query(); + } freeall: rv_load_query('Q'); rv_free_query(); rv_close_db(); + rv_free_multipart(); if(hasauth) rv_free_auth(); free(type); } diff --git a/CGI/multipart.c b/CGI/multipart.c new file mode 100644 index 0000000..0f3f3c4 --- /dev/null +++ b/CGI/multipart.c @@ -0,0 +1,71 @@ +/* $Id$ */ + +#include "rv_multipart.h" + +#include "rv_util.h" + +#include +#include +#include + +struct multipart_entry** multipart_entries = NULL; + +void rv_free_multipart(void) { + if(multipart_entries == NULL) return; + int i; + for(i = 0; multipart_entries[i] != NULL; i++) { + free(multipart_entries[i]->name); + free(multipart_entries[i]->data); + free(multipart_entries[i]); + } + free(multipart_entries); +} + +struct multipart_entry* rv_get_multipart(const char* name) { + if(multipart_entries == NULL) return NULL; + int i; + for(i = 0; multipart_entries[i] != NULL; i++) { + if(strcmp(multipart_entries[i]->name, name) == 0) { + return multipart_entries[i]; + } + } + return NULL; +} + +void rv_parse_multipart(unsigned char* buffer, char* boundary, unsigned long long length) { + unsigned long long i; + int incr = 0; + int phase = 0; + unsigned long long fstart = 0; + char* b = rv_strcat3("--", boundary, "\r"); + char* eb = rv_strcat3("--", boundary, "--\r"); + for(i = 0;; i++) { + if(i == length || buffer[i] == '\n') { + char* line = malloc(i - incr + 1); + memcpy(line, buffer + incr, i - incr); + line[i - incr] = 0; + if(line[0] == '\r' && phase == 0) { + phase = 1; + fstart = i + 1; + } else if(strcmp(b, line) == 0 || strcmp(eb, line) == 0) { + if(phase == 1) { + unsigned long long fend = i - strlen(line) - 2; + char* data = buffer + fstart; + unsigned long long datalen = fend - fstart; + } + phase = 0; + if(strcmp(eb, line) == 0) { + free(line); + break; + } + } else if(phase == 0) { + line[strlen(line) - 1] = 0; + fprintf(stderr, "%s\n", line); + } + free(line); + incr = i + 1; + if(i == length) break; + } + } + free(b); +} diff --git a/CGI/query.c b/CGI/query.c index 7f3b754..a661ba3 100644 --- a/CGI/query.c +++ b/CGI/query.c @@ -15,8 +15,8 @@ struct query_entry { struct query_entry** qentries; -struct query_entry** query; -struct query_entry** postquery; +struct query_entry** query = NULL; +struct query_entry** postquery = NULL; void rv_save_query(char c) { if(c == 'Q') { @@ -91,6 +91,7 @@ void rv_free_query(void) { char* rv_get_query(const char* key) { int i; + if(qentries == NULL) return NULL; for(i = 0; qentries[i] != NULL; i++) { if(strcmp(qentries[i]->key, key) == 0) { return qentries[i]->value; diff --git a/CGI/rv_multipart.h b/CGI/rv_multipart.h new file mode 100644 index 0000000..fb8a4e2 --- /dev/null +++ b/CGI/rv_multipart.h @@ -0,0 +1,16 @@ +/* $Id$ */ + +#ifndef __RV_MULTIPART_H__ +#define __RV_MULTIPART_H__ + +struct multipart_entry { + unsigned char* data; + char* name; + unsigned long long length; +}; + +void rv_parse_multipart(unsigned char* buffer, char* boundary, unsigned long long length); +struct multipart_entry* rv_get_multipart(const char* name); +void rv_free_multipart(void); + +#endif