From d6eff6de364890153baa1c7d68d8b72c27df1b9b Mon Sep 17 00:00:00 2001 From: ame Date: Mon, 26 Feb 2024 12:04:08 -0600 Subject: content-disposition --- src/net.c | 73 +++++++++++++++++++++++++++++++++++------------------- src/types/parray.c | 3 ++- src/types/parray.h | 7 +++++- src/types/str.h | 5 ++++ src/util.c | 49 ++++++++++++++++++++++++++++++++++++ src/util.h | 10 ++++++++ 6 files changed, 119 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/net.c b/src/net.c index c95eff0..d1cd5b4 100644 --- a/src/net.c +++ b/src/net.c @@ -360,7 +360,7 @@ int l_send(lua_State* L){ int client_fd = luaL_checkinteger(L, -1); client_fd_errors(client_fd); - printf("after error\n"); + size_t len; char* content = (char*)luaL_checklstring(L, 2, &len); @@ -373,12 +373,12 @@ int l_send(lua_State* L){ lua_pushvalue(L, 1); lua_pushstring(L, "_request"); lua_gettable(L, -2); - printf("befor write\n"); + if(strcmp(luaL_checkstring(L, -1), "HEAD") == 0){ i_write_header(L, header, &resp, "", 0); } else i_write_header(L, header, &resp, content, len); - printf("after write\n"); + send(client_fd, resp->c, resp->len, 0); lua_pushstring(L, "client_fd"); @@ -423,23 +423,29 @@ int l_serve(lua_State* L){ return 0; } -char* strnstr(const char *s1, const char *s2, size_t n) { - // simplistic algorithm with O(n2) worst case, stolen from stack overflow - size_t i, len; - char c = *s2; - - if(c == '\0') - return (char *)s1; +int content_disposition(str* src, parray_t** _dest){ - for(len = strlen(s2); len <= n; n--, s1++){ - if(*s1 == c){ - for(i = 1;; i++){ - if(i == len) return (char *)s1; - if(s1[i] != s2[i]) break; - } - } + char* end = strnstr(src->c, ";", src->len); + parray_t* dest = parray_init(); + if(end == NULL){ + parray_set(dest, "form-data", (void*)str_init(src->c)); + return 0; } - return NULL; + str* temp = str_init(""); + str_pushl(temp, src->c, end - src->c); + parray_set(dest, "form-data", (void*)temp); + + int len = end - src->c; + char* buffer = end + 1; + + gen_parse(buffer, src->len - len, &dest); + //printf("\n**\n"); + //for(int i = 0; i != dest->len; i++){ + // printf("'%s : %s'\n",((str*)dest->P[i].key)->c,((str*)dest->P[i].value)->c); + //} + *_dest = dest; + + return 1; } /** @@ -486,18 +492,34 @@ int file_parse(lua_State* L, char* buffer, str* content_type, size_t blen){ }; str* current = str_init(""); int key = -1; - + int cont_disp = 0; for(char* s = ind + boundary->len + 2; s != header_eof; s++){ - if(*s == ':'){ //todo: collapse Content-Disposition + if(*s == ':'){ + cont_disp = strcmp(current->c, "Content-Disposition") == 0; lua_pushlstring(L, current->c, current->len); key = lua_gettop(L); str_clear(current); } else if(*s == '\n') { if(key != -1){ - luaI_tsets(L, file_T , luaL_checkstring(L, key), current->c); - key = -1; + + if(cont_disp){ + parray_t* aw; + content_disposition(current, &aw); + lua_newtable(L); + int tt = lua_gettop(L); + for(int i = 0; i != aw->len; i++){ + //printf("'%s : %s'\n",((str*)dest->P[i].key)->c,((str*)dest->P[i].value)->c); + luaI_tsets(L, tt, ((str*)aw->P[i].key)->c, ((str*)aw->P[i].value)->c); + } + luaI_tsetv(L, file_T, "Content-Disposition", tt); + parray_clear(aw, 2); + } else { + luaI_tsets(L, file_T , luaL_checkstring(L, key), current->c); + key = -1; + } str_clear(current); + cont_disp = 0; } } else if(*s != '\r' && !(*s == ' ' && strcmp(current->c, "") == 0)){ str_pushl(current, s, 1); @@ -814,13 +836,12 @@ int l_listen(lua_State* L){ if(lua_gettop(L) != 2) { - printf("not enough args"); - abort(); + p_fatal("not enough args"); } if(lua_type(L, 1) != LUA_TFUNCTION) { - printf("expected a function at arg 1"); - abort(); + p_fatal("(arg:1) expected a function"); } + int port = luaL_checkinteger(L, 2); lua_newtable(L); diff --git a/src/types/parray.c b/src/types/parray.c index 25cd94c..3c2a6cc 100644 --- a/src/types/parray.c +++ b/src/types/parray.c @@ -44,7 +44,8 @@ void parray_lclear(parray_t* p){ void parray_clear(parray_t* p, int clear_val){ for(int i = 0; i != p->len; i++){ str_free(p->P[i].key); - if(clear_val) free(p->P[i].value); + if(clear_val == 1) free(p->P[i].value); + else if(clear_val == 2) str_free(p->P[i].value); } parray_lclear(p); } diff --git a/src/types/parray.h b/src/types/parray.h index 3f33865..9b9927a 100644 --- a/src/types/parray.h +++ b/src/types/parray.h @@ -1,4 +1,7 @@ +#ifndef __PARRAY_H +#define __PARRAY_H + typedef struct { void* value; str* key; @@ -19,4 +22,6 @@ void parray_clear(parray_t*, int); void parray_lclear(parray_t*); -parray_t* parray_find(parray_t*, char*); \ No newline at end of file +parray_t* parray_find(parray_t*, char*); + +#endif //parray_h \ No newline at end of file diff --git a/src/types/str.h b/src/types/str.h index 60b0cb9..ccf379f 100644 --- a/src/types/str.h +++ b/src/types/str.h @@ -1,3 +1,6 @@ +#ifndef __STR_H +#define __STR_H + #include #include #include @@ -13,3 +16,5 @@ void str_free(str*); void str_push(str*, char*); void str_pushl(str*, char*, size_t); void str_clear(str*); + +#endif //__STR_H \ No newline at end of file diff --git a/src/util.c b/src/util.c index 3c2e279..4ba0476 100644 --- a/src/util.c +++ b/src/util.c @@ -3,6 +3,55 @@ #include #include "lua.h" +int gen_parse(char* inp, int len, parray_t** _table){ + str* current = str_init(""), *last = NULL; + int state = 0; + + parray_t* table = *_table; + for(int i = 0; i < len; i++){ + + if(state != 1 && inp[i] == ';'){ + parray_set(table, last->c, (void*)current); + str_free(last); + last = NULL; + current = str_init(""); + state = 0; + } else if(state != 1 && inp[i] == '='){ + last = current; + current = str_init(""); + if(inp[i+1] == '"'){ + state = 1; + i++; + } + } else if(state == 1 && inp[i] == '"'){ + state = 0; + } else if(current->c[0] != '\0' || inp[i] != ' ') str_pushl(current, inp + i, 1); + } + parray_set(table, last->c, (void*)current); + str_free(last); + *_table = table; + return 1; +} + +char* strnstr(const char *s1, const char *s2, size_t n) { + // simplistic algorithm with O(n2) worst case, stolen from stack overflow + size_t i, len; + char c = *s2; + + if(c == '\0') + return (char *)s1; + + for(len = strlen(s2); len <= n; n--, s1++){ + if(*s1 == c){ + for(i = 1;; i++){ + if(i == len) return (char *)s1; + if(s1[i] != s2[i]) break; + } + } + } + return NULL; +} + void p_fatal(const char* m){ fprintf(stderr, "%s[ fatal ] %s %s\n",color_red, m, color_reset); exit(EXIT_FAILURE); diff --git a/src/util.h b/src/util.h index 9a5b295..864108d 100644 --- a/src/util.h +++ b/src/util.h @@ -1,3 +1,9 @@ +#ifndef __UTIL_H +#define __UTIL_H + +#include "types/str.h" +#include "types/parray.h" + #define color_black "\e[30m" #define color_red "\e[31m" #define color_green "\e[32m" @@ -18,5 +24,9 @@ #define i_swap(A,B) double temp = A; A = B; B = temp; +int gen_parse(char*,int, parray_t**); void p_fatal(const char*); void p_error(const char*); +char* strnstr(const char*, const char*, size_t); + +#endif //__UTIL_H \ No newline at end of file -- cgit v1.2.3