]> Git repositories of Nishi - repoview.git/commitdiff
multipart kinda works
authorNishi <nishi@nishi.boats>
Thu, 22 Aug 2024 04:26:35 +0000 (04:26 +0000)
committerNishi <nishi@nishi.boats>
Thu, 22 Aug 2024 04:26:35 +0000 (04:26 +0000)
git-svn-id: file:///raid/svn-personal/repoview/trunk@41 7e8b2a19-8934-dd40-8cb3-db22cdd5a80f

CGI/Makefile
CGI/main.c
CGI/multipart.c [new file with mode: 0644]
CGI/query.c
CGI/rv_multipart.h [new file with mode: 0644]

index 28bebfecbc7fe8e06cf540f066cf64c433049ef6..ed0229972ab7d138050f2c1b26682338f92d6526 100644 (file)
@@ -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
 
index e71687888a34826236f1936872b1f2f4da84a871..dd7171e057c3788aa60dbb25e7064565f1a8839e 100644 (file)
@@ -10,6 +10,7 @@
 #include "rv_util.h"
 #include "rv_db.h"
 #include "rv_auth.h"
+#include "rv_multipart.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -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 (file)
index 0000000..0f3f3c4
--- /dev/null
@@ -0,0 +1,71 @@
+/* $Id$ */
+
+#include "rv_multipart.h"
+
+#include "rv_util.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+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);
+}
index 7f3b7548b4b9c9e003b7af785ce286ec3f1a2b57..a661ba3d3a748e9f36133b49b83b9da432f52c68 100644 (file)
@@ -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 (file)
index 0000000..fb8a4e2
--- /dev/null
@@ -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