aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/net.md45
-rw-r--r--src/crypto.h7
-rw-r--r--src/hash/blake.c12
-rw-r--r--src/hash/md5.c9
-rw-r--r--src/hash/sha01.c17
-rw-r--r--src/hash/sha2-256.c20
-rw-r--r--src/hash/sha2xx.c22
-rw-r--r--src/lua.c3
-rw-r--r--src/net.c21
-rw-r--r--src/net.h4
-rw-r--r--src/net/common.h3
-rw-r--r--src/net/lua.c26
-rw-r--r--src/net/lua.h1
-rw-r--r--src/net/luai.c6
-rw-r--r--src/net/util.c190
-rw-r--r--src/net/util.h7
-rw-r--r--src/thread.c15
-rw-r--r--src/types/str.c2
-rw-r--r--tests/buffer.lua9
-rw-r--r--tests/hash.lua22
-rw-r--r--tests/net.lua5
-rw-r--r--tests/t.lua15
-rw-r--r--tests/thread.lua15
23 files changed, 375 insertions, 101 deletions
diff --git a/docs/net.md b/docs/net.md
index e548cb1..0807c72 100644
--- a/docs/net.md
+++ b/docs/net.md
@@ -12,12 +12,41 @@ right now everything within a server:GET function is partially global, it can re
it can not read/copy local variables or modify globals
**
+allows a third optional argument that offers some other options in a table format
+
+|name|default value|extra info|
+|--|--|--|
+|mime.types.file**|/etc/mime.types|formated similarly to [this](https://wiki.debian.org/MIME/etc/mime.types)|
+|max.connections**|64|maximum number of connections that can be opened at the same time, will respond with error(503)|
+|max.header.size**|1<<20 (1048576)|max header size before refusing connection with error(431)|
+|max.uri.size**|idk yet|maximum uri size before refusing request with error(414)|
+|max.request.timeout**|idk yet|maximum time server will wait for request to be parsed|
+
+
+the server will send these codes for these reasons
+|code|cause|
+|--|--|
+|503**|too many current requests, more than max.connections|
+|500**|anytime a server route crashes|
+|431**|header is larger than max header size, more than max.header.size|
+|414**|request uri is longer than max.uri.size|
+|408**|request took too longer than max.request.timeout|
+|404**|request has no defined route|
+
+(more to come?**)
+
```lua
llib.net.listen(function(server)
...
end, 80)
```
+```lua
+llib.net.listen(function(server)
+ ...
+end, 80, {["mime.types.file"] = "/etc/mime.types"})
+```
+
### server:lock server:unlock
continues on the current thread, but pauses all other threads at that point
@@ -48,13 +77,13 @@ the actual name of the function will change based on what request method you wan
```lua
server:all("*", function(res, req)
if(req['Version'] ~= "HTTP/1.1") then
- res:close()
+ res:stop()
end
end)
...
server:GET("/", function(res, req)
- --version will always be 1.1, as per the middleware
+ --version will always be 1.1, because the request passes through the function sequentially
...
end)
...
@@ -69,7 +98,7 @@ end)
'takes a string
sends the string to the client, constructs a header on first call (whether or not res.header._sent is null)
-(the constructed header can not be changed later on in the request), and sends the string without closing the client
+(the constructed header can not be changed later on in the request*), and sends the string without closing the client
```lua
...
@@ -78,6 +107,8 @@ res:write("<h1>good bye world</h1>")
...
```
+*well it can but it wont do anything
+
#### res:send
'takes a string
@@ -94,6 +125,12 @@ res:send("<h1>hello world</h1>")
closes connection, sets res.client_fd to -1, any calls that use this value will fail
+this will still run any selected functions!
+
+#### res:stop
+
+prevents all further selected functions from running
+
#### res.header
table containing all head information, anything added to it will be used, certain keys will affect other values or have other side effects on res:send, listed below
@@ -119,6 +156,8 @@ res.header["test"] = "wowa"
'takes one string, which is a path that will be served, must be a file
+res.header["Content-Type"] is set automatically depending on the file extention, using /etc/mime.types, or whatever option was supplied to listen (see listen options)
+
```lua
...
res:sendfile("./html/index.html")
diff --git a/src/crypto.h b/src/crypto.h
index b3b0609..ba97f0c 100644
--- a/src/crypto.h
+++ b/src/crypto.h
@@ -44,15 +44,16 @@ int tp(lua_State*);
#define common_hash_init_update(hashname) lua_common_hash_init_update(hashname, hashname)
#define lua_common_hash_init_update(hashname, luaname) lua_common_hash_init(hashname, luaname) lua_common_hash_update(hashname, luaname)
#define lua_common_hash_init(hashname, luaname) lua_common_hash_init_ni(hashname, luaname, hashname##_init())
+#define lua_common_hash_init_l(hashname, luaname) lua_common_hash_init_ni(hashname, luaname, hashname##_init_l(L))
#define common_hash_clone(hashname) lua_common_hash_clone(hashname, hashname)
-#define lua_common_hash_clone(hashname, luaname) lua_common_hash_clone_oargs(hashname, luaname, l_##luaname##_init(L))
-#define lua_common_hash_clone_oargs(hashname, luaname, oinit)\
+#define lua_common_hash_clone(hashname, luaname) lua_common_hash_clone_oargs(hashname, luaname, l_##luaname##_init(L), *b = *a)
+#define lua_common_hash_clone_oargs(hashname, luaname, oinit, copy)\
int l_##luaname##_clone(lua_State* L){\
struct hashname##_hash* a = (struct hashname##_hash*)lua_touserdata(L, -1);\
oinit;\
struct hashname##_hash* b = (struct hashname##_hash*)lua_touserdata(L, -1);\
- *b = *a;\
+ copy;\
return 1;\
}
diff --git a/src/hash/blake.c b/src/hash/blake.c
index 7bf1481..cf948f1 100644
--- a/src/hash/blake.c
+++ b/src/hash/blake.c
@@ -498,7 +498,8 @@ int l_blake256_clone(lua_State* L){
return 1;
}
-common_hash_init_update(blake256);
+lua_common_hash_init_l(blake256, blake256);
+lua_common_hash_update(blake256, blake256);
int l_blake256_final(lua_State* L){
struct blake256_hash* a = (struct blake256_hash*)lua_touserdata(L, 1);
@@ -539,7 +540,8 @@ int l_blake224_clone(lua_State* L){
return 1;
}
-common_hash_init_update(blake224);
+lua_common_hash_init_l(blake224, blake224);
+lua_common_hash_update(blake224, blake224);
int l_blake224_final(lua_State* L){
struct blake224_hash* a = (struct blake224_hash*)lua_touserdata(L, 1);
@@ -580,7 +582,8 @@ int l_blake512_clone(lua_State* L){
return 1;
}
-common_hash_init_update(blake512);
+lua_common_hash_init_l(blake512, blake512);
+lua_common_hash_update(blake512, blake512);
int l_blake512_final(lua_State* L){
struct blake512_hash* a = (struct blake512_hash*)lua_touserdata(L, 1);
@@ -622,7 +625,8 @@ int l_blake384_clone(lua_State* L){
return 1;
}
-common_hash_init_update(blake384);
+lua_common_hash_init_l(blake384, blake384);
+lua_common_hash_update(blake384, blake384);
int l_blake384_final(lua_State* L){
struct blake384_hash* a = (struct blake384_hash*)lua_touserdata(L, 1);
diff --git a/src/hash/md5.c b/src/hash/md5.c
index 1b3f508..45844f2 100644
--- a/src/hash/md5.c
+++ b/src/hash/md5.c
@@ -134,7 +134,14 @@ void md5_final(struct md5_hash* hash, char out_stream[64]){
}
-common_hash_clone(md5);
+//common_hash_clone(md5);
+lua_common_hash_clone_oargs(md5, md5, l_md5_init(L), {
+ uint8_t* old = b->buffer;
+ *b = *a;
+ b->buffer = old;
+ memcpy(b->buffer, a->buffer, bs * sizeof * b->buffer);
+});
+
lua_common_hash_init_ni(md5, md5, md5_init_l(L));
lua_common_hash_update(md5, md5);
//common_hash_init_update(md5);
diff --git a/src/hash/sha01.c b/src/hash/sha01.c
index 9ba3e6c..1711faa 100644
--- a/src/hash/sha01.c
+++ b/src/hash/sha01.c
@@ -174,11 +174,24 @@ void sha1(uint8_t* a, size_t len, char* out_stream){
free(aa.buffer);
}
-common_hash_clone(sha1);
+//common_hash_clone(sha1);
+lua_common_hash_clone_oargs(sha1, sha1, l_sha1_init(L), {
+ uint8_t* old = b->buffer;
+ *b = *a;
+ b->buffer = old;
+ memcpy(b->buffer, a->buffer, bs * sizeof * b->buffer);
+});
+
lua_common_hash_init_ni(sha1, sha1, sha01_init_l(1, L));
lua_common_hash_update(sha1, sha1);
-common_hash_clone(sha0);
+//common_hash_clone(sha0);
+lua_common_hash_clone_oargs(sha0, sha0, l_sha0_init(L), {
+ uint8_t* old = b->buffer;
+ *b = *a;
+ b->buffer = old;
+ memcpy(b->buffer, a->buffer, bs * sizeof * b->buffer);
+});
lua_common_hash_init_ni(sha0, sha0, sha01_init_l(0, L));
lua_common_hash_update(sha0, sha0);
diff --git a/src/hash/sha2-256.c b/src/hash/sha2-256.c
index 7e37d9d..42f6a81 100644
--- a/src/hash/sha2-256.c
+++ b/src/hash/sha2-256.c
@@ -245,7 +245,13 @@ struct iv sha_iv_gen(int i){
return (struct iv){.h0 = a.h0, .h1 = a.h1, .h2 = a.h2, .h3 = a.h3, .h4 = a.h4, .h5 = a.h5, .h6 = a.h6, .h7 = a.h7};
}
-common_hash_clone(sha512);
+//common_hash_clone(sha512);
+lua_common_hash_clone_oargs(sha512, sha512, l_sha512_init(L), {
+ uint8_t* old = b->buffer;
+ *b = *a;
+ b->buffer = old;
+ memcpy(b->buffer, a->buffer, bs * sizeof * b->buffer);
+});
lua_common_hash_init_ni(sha512, sha512, sha512_t_init_l(sha512_iv, L));
lua_common_hash_update(sha512, sha512);
@@ -259,7 +265,13 @@ int l_sha512_final(lua_State* L){
return 1;
}
-common_hash_clone(sha384);
+//common_hash_clone(sha384);
+lua_common_hash_clone_oargs(sha384, sha384, l_sha384_init(L), {
+ uint8_t* old = b->buffer;
+ *b = *a;
+ b->buffer = old;
+ memcpy(b->buffer, a->buffer, bs * sizeof * b->buffer);
+});
lua_common_hash_init_ni(sha384, sha384, sha512_t_init_l(sha384_iv, L));
lua_common_hash_update(sha384, sha384);
@@ -278,7 +290,11 @@ int l_sha512_t_clone(lua_State* L){
lua_pushinteger(L, a->t);
l_sha512_t_init(L);
struct sha512_hash* b = (struct sha512_hash*)lua_touserdata(L, -1);
+
+ uint8_t* old = b->buffer;
*b = *a;
+ b->buffer = old;
+ memcpy(b->buffer, a->buffer, bs * sizeof * b->buffer);
return 1;
}
diff --git a/src/hash/sha2xx.c b/src/hash/sha2xx.c
index f3fbc5d..1ef3f6f 100644
--- a/src/hash/sha2xx.c
+++ b/src/hash/sha2xx.c
@@ -179,16 +179,24 @@ void sha256(uint8_t* in, size_t len, char* out){
struct sha256_hash a = sha256_init();
sha256_update(in, len, &a);
sha256_final(&a, out);
+ free(a.buffer);
}
void sha224(uint8_t* in, size_t len, char* out){
struct sha256_hash a = sha224_init();
sha224_update(in, len, &a);
sha224_final(&a, out);
+ free(a.buffer);
}
-common_hash_clone(sha256);
-lua_common_hash_init(sha256, sha256);
+//common_hash_clone(sha256);
+lua_common_hash_clone_oargs(sha256, sha256, l_sha256_init(L), {
+ uint8_t* old = b->buffer;
+ *b = *a;
+ b->buffer = old;
+ memcpy(b->buffer, a->buffer, bs * sizeof * b->buffer);
+});
+lua_common_hash_init_l(sha256, sha256);
lua_common_hash_update(sha256, sha256);
int l_sha256_final(lua_State* L){
@@ -215,8 +223,14 @@ int l_sha256(lua_State* L){
};
#define sha224_hash sha256_hash
-common_hash_clone(sha224);
-lua_common_hash_init(sha224, sha224);
+//common_hash_clone(sha224);
+lua_common_hash_clone_oargs(sha224, sha224, l_sha224_init(L), {
+ uint8_t* old = b->buffer;
+ *b = *a;
+ b->buffer = old;
+ memcpy(b->buffer, a->buffer, bs * sizeof * b->buffer);
+});
+lua_common_hash_init_l(sha224, sha224);
lua_common_hash_update(sha224, sha224);
int l_sha224_final(lua_State* L){
diff --git a/src/lua.c b/src/lua.c
index 225dfbf..d6a5523 100644
--- a/src/lua.c
+++ b/src/lua.c
@@ -139,6 +139,9 @@ void luaI_deepcopy(lua_State* src, lua_State* dest, enum deep_copy_flags flags){
modi = 1;
lua_pushlightuserdata(dest, lua_touserdata(src, -1));
break;
+ case LUA_TTHREAD:
+ lua_pushnil(dest);
+ break;
default:
printf("unknown type %i vs (old)%i\n",lua_type(src, -1), type);
abort();
diff --git a/src/net.c b/src/net.c
index a356025..9128d89 100644
--- a/src/net.c
+++ b/src/net.c
@@ -161,6 +161,8 @@ void* handle_client(void *_arg){
luaI_tsetcf(L, res_idx, "sendfile", l_sendfile);
luaI_tsetcf(L, res_idx, "write", l_write);
luaI_tsetcf(L, res_idx, "close", l_close);
+ luaI_tsetcf(L, res_idx, "stop", l_stop);
+
//values
luaI_tseti(L, res_idx, "client_fd", client_fd);
@@ -199,7 +201,7 @@ void* handle_client(void *_arg){
struct lchar* wowa = awa->cs[z];
//if request is HEAD, it is valid for GET and HEAD listeners
if(strcmp(wowa->req, "all") == 0 || strcmp(wowa->req, sR->c) == 0 ||
- (strcmp(sR->c, "HEAD") && strcmp(wowa->req, "GET"))){
+ (strcmp(sR->c, "HEAD") == 0 && strcmp(wowa->req, "GET") == 0)){
luaL_loadbuffer(L, wowa->c, wowa->len, "fun");
int func = lua_gettop(L);
@@ -210,10 +212,18 @@ void* handle_client(void *_arg){
//call the function
lua_call(L, 2, 0);
+
+ //check if res:stop() was called
+ lua_pushstring(L, "_stop");
+ lua_gettable(L, res_idx);
+ if(!lua_isnil(L, -1))
+ goto net_end;
}
}
}
+
+net_end:
larray_clear(params);
parray_lclear(owo); //dont free the rest
@@ -255,6 +265,7 @@ void* handle_client(void *_arg){
}
int start_serv(lua_State* L, int port){
+ parse_mimetypes();
//need these on windows for sockets (stupid)
#ifdef _WIN32
WSADATA Data;
@@ -289,6 +300,7 @@ int start_serv(lua_State* L, int port){
if (pthread_mutex_init(&con_mutex, NULL) != 0)
p_fatal("con_mutex init failed\n");
+ int count = 0;
for(;;){
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
@@ -297,6 +309,13 @@ int start_serv(lua_State* L, int port){
if((*client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &client_addr_len)) < 0)
p_fatal("failed to accept\n");
+ if(count >= max_con){
+ //deny request
+ free(client_fd);
+ continue;
+ }
+ count++;
+
//open a state to call shit, should be somewhat thread safe
thread_arg_struct* args = malloc(sizeof * args);
diff --git a/src/net.h b/src/net.h
index 2efab03..d9c8b4c 100644
--- a/src/net.h
+++ b/src/net.h
@@ -20,10 +20,6 @@ int64_t recv_full_buffer(int client_fd, char** _buffer, int* header_eof, int* st
int parse_header(char* buffer, int header_eof, parray_t** _table);
-void http_build(str** _dest, int code, char* code_det, char* header_vs, char* content, size_t len);
-
-void http_code(int code, char* code_det);
-
void i_write_header(lua_State* L, int header_top, str** _resp, char* content, size_t len);
void client_fd_errors(int client_fd);
diff --git a/src/net/common.h b/src/net/common.h
index 4120734..6b1a25a 100644
--- a/src/net/common.h
+++ b/src/net/common.h
@@ -19,6 +19,7 @@
#include "../table.h"
#include "../types/str.h"
#include "../types/parray.h"
+#include "../types/map.h"
#define max_con 200
//2^42
@@ -62,4 +63,6 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t con_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t lua_mutex = PTHREAD_MUTEX_INITIALIZER;
+extern map_t* mime_type;
+
#endif
diff --git a/src/net/lua.c b/src/net/lua.c
index 9600189..06d1b0e 100644
--- a/src/net/lua.c
+++ b/src/net/lua.c
@@ -104,6 +104,16 @@ int l_close(lua_State* L){
return 0;
}
+int l_stop(lua_State* L){
+ int res_idx = 1;
+
+ lua_pushstring(L, "_stop");
+ lua_pushboolean(L, 1);
+ lua_settable(L, res_idx);
+
+ return 0;
+}
+
int l_roll(lua_State* L){
int alen;
if(lua_gettop(L) > 2) {
@@ -207,6 +217,22 @@ int l_sendfile(lua_State* L){
p_fatal("missing permissions");
}
+<<<<<<< HEAD
+=======
+ char* ext = strrchr(path, '.');
+ if(ext){
+ char* content_type = map_get(mime_type, ext + 1);
+
+ if(content_type)
+ {luaI_tsets(L, header, "Content-Type", content_type);}
+ }
+
+ str* r;
+ i_write_header(L, header, &r, "", 0);
+ send(client_fd, r->c, r->len, 0);
+ str_free(r);
+
+>>>>>>> e29d3ea86551380ace8e2c86c9f1f63e901941e1
char* buffer = calloc(sizeof* buffer, bsize + 1);
FILE* fp = fopen(path, "rb");
fseek(fp, 0L, SEEK_END);
diff --git a/src/net/lua.h b/src/net/lua.h
index d3c2371..b1e96fc 100644
--- a/src/net/lua.h
+++ b/src/net/lua.h
@@ -3,5 +3,6 @@
int l_write(lua_State* L);
int l_send(lua_State* L);
int l_close(lua_State* L);
+int l_stop(lua_State* L);
int l_roll(lua_State* L);
int l_sendfile(lua_State* L);
diff --git a/src/net/luai.c b/src/net/luai.c
index ea93285..1929818 100644
--- a/src/net/luai.c
+++ b/src/net/luai.c
@@ -1,5 +1,6 @@
#include "luai.h"
#include "common.h"
+#include "util.h"
void i_write_header(lua_State* L, int header_top, str** _resp, char* content, size_t len){
str* resp;
@@ -24,9 +25,8 @@ void i_write_header(lua_State* L, int header_top, str** _resp, char* content, si
lua_gettable(L, header_top);
int code = luaL_checkinteger(L, -1);
- char code_det[50] = {0};
- http_code(code, code_det);
- http_build(&resp, code, code_det, header_vs->c, content, len);
+ const char* code_det = http_code(code);
+ http_build(&resp, code, code_det, header_vs->c, content, len);
str_free(header_vs);
*_resp = resp;
diff --git a/src/net/util.c b/src/net/util.c
index 1fec987..44a525b 100644
--- a/src/net/util.c
+++ b/src/net/util.c
@@ -128,7 +128,7 @@ int parse_header(char* buffer, int header_eof, parray_t** _table){
* @brief contructs an http request
*
*/
-void http_build(str** _dest, int code, char* code_det, char* header_vs, char* content, size_t len){
+void http_build(str** _dest, int code, const char* code_det, char* header_vs, char* content, size_t len){
char* dest = malloc(HTTP_BUFFER_SIZE);
memset(dest, 0, HTTP_BUFFER_SIZE);
@@ -147,70 +147,70 @@ void http_build(str** _dest, int code, char* code_det, char* header_vs, char* co
* @brief gets a string representation of a http code
*
*/
-void http_code(int code, char* code_det){
+const char* http_code(int code){
switch(code){
- case 100: sprintf(code_det,"Continue"); break;
- case 101: sprintf(code_det,"Switching Protocols"); break;
- case 102: sprintf(code_det,"Processing"); break;
- case 103: sprintf(code_det,"Early Hints"); break;
- case 200: sprintf(code_det,"OK"); break;
- case 201: sprintf(code_det,"Created"); break;
- case 202: sprintf(code_det,"Accepted"); break;
- case 203: sprintf(code_det,"Non-Authoritative Information"); break;
- case 204: sprintf(code_det,"No Content"); break;
- case 205: sprintf(code_det,"Reset Content"); break;
- case 206: sprintf(code_det,"Partial Content"); break;
- case 207: sprintf(code_det,"Multi-Status"); break;
- case 208: sprintf(code_det,"Already Reported"); break;
- case 226: sprintf(code_det,"IM Used"); break;
- case 300: sprintf(code_det,"Multiple Choices"); break;
- case 301: sprintf(code_det,"Moved Permanently"); break;
- case 302: sprintf(code_det,"Found"); break;
- case 303: sprintf(code_det,"See Other"); break;
- case 304: sprintf(code_det,"Not Modified"); break;
- case 307: sprintf(code_det,"Temporary Redirect"); break;
- case 308: sprintf(code_det,"Permanent Redirect"); break;
- case 400: sprintf(code_det,"Bad Request"); break;
- case 401: sprintf(code_det,"Unauthorized"); break;
- case 402: sprintf(code_det,"Payment Required"); break;
- case 403: sprintf(code_det,"Forbidden"); break;
- case 404: sprintf(code_det,"Not Found"); break;
- case 405: sprintf(code_det,"Method Not Allowed"); break;
- case 406: sprintf(code_det,"Not Acceptable"); break;
- case 407: sprintf(code_det,"Proxy Authentication Required"); break;
- case 408: sprintf(code_det,"Request Timeout"); break;
- case 409: sprintf(code_det,"Conflict"); break;
- case 410: sprintf(code_det,"Gone"); break;
- case 411: sprintf(code_det,"Length Required"); break;
- case 412: sprintf(code_det,"Precondition Failed"); break;
- case 413: sprintf(code_det,"Content Too Large"); break;
- case 414: sprintf(code_det,"URI Too Long"); break;
- case 415: sprintf(code_det,"Unsupported Media Type"); break;
- case 416: sprintf(code_det,"Range Not Satisfiable"); break;
- case 417: sprintf(code_det,"Expectation Failed"); break;
- case 418: sprintf(code_det,"I'm a teapot"); break;
- case 421: sprintf(code_det,"Misdirected Request"); break;
- case 422: sprintf(code_det,"Unprocessable Content"); break;
- case 423: sprintf(code_det,"Locked"); break;
- case 424: sprintf(code_det,"Failed Dependency"); break;
- case 425: sprintf(code_det,"Too Early"); break;
- case 426: sprintf(code_det,"Upgrade Required"); break;
- case 428: sprintf(code_det,"Precondition Required"); break;
- case 429: sprintf(code_det,"Too Many Requests"); break;
- case 431: sprintf(code_det,"Request Header Fields Too Large"); break;
- case 451: sprintf(code_det,"Unavailable For Legal Reasons"); break;
- case 500: sprintf(code_det,"Internal Server Error"); break;
- case 501: sprintf(code_det,"Not Implemented"); break;
- case 502: sprintf(code_det,"Bad Gateway"); break;
- case 503: sprintf(code_det,"Service Unavailable"); break;
- case 504: sprintf(code_det,"Gateway Timeout"); break;
- case 505: sprintf(code_det,"HTTP Version Not Supported"); break;
- case 506: sprintf(code_det,"Variant Also Negotiates"); break;
- case 507: sprintf(code_det,"Insufficient Storage"); break;
- case 508: sprintf(code_det,"Loop Detected"); break;
- case 510: sprintf(code_det,"Not Extended"); break;
- case 511: sprintf(code_det,"Network Authentication Required"); break;
- default: sprintf(code_det,"unknown");
+ case 100: return "Continue"; break;
+ case 101: return "Switching Protocols"; break;
+ case 102: return "Processing"; break;
+ case 103: return "Early Hints"; break;
+ case 200: return "OK"; break;
+ case 201: return "Created"; break;
+ case 202: return "Accepted"; break;
+ case 203: return "Non-Authoritative Information"; break;
+ case 204: return "No Content"; break;
+ case 205: return "Reset Content"; break;
+ case 206: return "Partial Content"; break;
+ case 207: return "Multi-Status"; break;
+ case 208: return "Already Reported"; break;
+ case 226: return "IM Used"; break;
+ case 300: return "Multiple Choices"; break;
+ case 301: return "Moved Permanently"; break;
+ case 302: return "Found"; break;
+ case 303: return "See Other"; break;
+ case 304: return "Not Modified"; break;
+ case 307: return "Temporary Redirect"; break;
+ case 308: return "Permanent Redirect"; break;
+ case 400: return "Bad Request"; break;
+ case 401: return "Unauthorized"; break;
+ case 402: return "Payment Required"; break;
+ case 403: return "Forbidden"; break;
+ case 404: return "Not Found"; break;
+ case 405: return "Method Not Allowed"; break;
+ case 406: return "Not Acceptable"; break;
+ case 407: return "Proxy Authentication Required"; break;
+ case 408: return "Request Timeout"; break;
+ case 409: return "Conflict"; break;
+ case 410: return "Gone"; break;
+ case 411: return "Length Required"; break;
+ case 412: return "Precondition Failed"; break;
+ case 413: return "Content Too Large"; break;
+ case 414: return "URI Too Long"; break;
+ case 415: return "Unsupported Media Type"; break;
+ case 416: return "Range Not Satisfiable"; break;
+ case 417: return "Expectation Failed"; break;
+ case 418: return "I'm a teapot"; break;
+ case 421: return "Misdirected Request"; break;
+ case 422: return "Unprocessable Content"; break;
+ case 423: return "Locked"; break;
+ case 424: return "Failed Dependency"; break;
+ case 425: return "Too Early"; break;
+ case 426: return "Upgrade Required"; break;
+ case 428: return "Precondition Required"; break;
+ case 429: return "Too Many Requests"; break;
+ case 431: return "Request Header Fields Too Large"; break;
+ case 451: return "Unavailable For Legal Reasons"; break;
+ case 500: return "Internal Server Error"; break;
+ case 501: return "Not Implemented"; break;
+ case 502: return "Bad Gateway"; break;
+ case 503: return "Service Unavailable"; break;
+ case 504: return "Gateway Timeout"; break;
+ case 505: return "HTTP Version Not Supported"; break;
+ case 506: return "Variant Also Negotiates"; break;
+ case 507: return "Insufficient Storage"; break;
+ case 508: return "Loop Detected"; break;
+ case 510: return "Not Extended"; break;
+ case 511: return "Network Authentication Required"; break;
+ default: return "unknown";
}
}
@@ -356,3 +356,65 @@ parray_t* route_match(parray_t* paths, char* request, larray_t** _params){
*_params = params;
return out;
}
+
+map_t* mime_type = NULL;
+void parse_mimetypes(){
+ mime_type = map_init();
+ FILE* fp = fopen(MIMETYPES, "r");
+ char* buffer = calloc(1024, sizeof * buffer);
+
+ for(;fgets(buffer, 1024, fp); memset(buffer, 0, 1024)){
+ int i;
+ for(i = 0; buffer[i] == ' '; i++);
+ if(buffer[i] == '#') continue;
+
+ //printf("s: '%s'\n",buffer + i);
+ char* type = calloc(512, sizeof * type);
+ int type_len = 0;
+ for(; buffer[i + type_len] != ' ' && buffer[i + type_len] != '\t'; type_len++){
+ //printf("%c", buffer[i + type_len]);
+ type[type_len] = buffer[i + type_len];
+ if(buffer[i + type_len] == '\0' || buffer[i + type_len] == '\n') break;
+ }
+ type[type_len] = '\0';
+
+ //check if the type has an associated file type
+ if(buffer[i + type_len] == '\0' || buffer[i + type_len] == '\n'){
+ free(type);
+ continue;
+ }
+ type = realloc(type, (type_len + 1) * sizeof * type);
+
+
+ int file_type_len = 0;
+ char* file_type = calloc(512, sizeof * file_type);
+ i += type_len;
+
+ for(;buffer[i] == ' ' || buffer[i] == '\t'; i++);
+
+ int used = 0;
+ for(;;){
+ if(buffer[i + file_type_len] == ' ' || buffer[i + file_type_len] == '\n' || buffer[i + file_type_len] == '\0'){
+ used = 1;
+ file_type[file_type_len] = '\0';
+ file_type = realloc(file_type, (file_type_len + 1) * sizeof * file_type);
+ //printf("set %s to %s\n",file_type, type);
+ map_set(&mime_type, file_type, type);
+ file_type = calloc(512, sizeof * file_type);
+ if(buffer[i + file_type_len] != ' ') break;
+ i += file_type_len + 1;
+ file_type_len = 0;
+ //printf("finish\n");
+ } else {
+ file_type[file_type_len] = buffer[i + file_type_len];
+ file_type_len++;
+ }
+ }
+ free(file_type);
+
+ //printf("e: '%s'\n", type);
+ if(!used)free(type);
+ }
+ //printf("done\n");
+
+}
diff --git a/src/net/util.h b/src/net/util.h
index 98d4d93..e592420 100644
--- a/src/net/util.h
+++ b/src/net/util.h
@@ -1,5 +1,7 @@
#include "common.h"
#include "../types/larray.h"
+
+#define MIMETYPES "/etc/mime.types"
/**
* @brief calls recv into buffer until everything is read
*
@@ -32,7 +34,7 @@ int parse_header(char* buffer, int header_eof, parray_t** _table);
* @param {char*} response content
* @param {size_t} content length
*/
-void http_build(str** _dest, int code, char* code_det, char* header_vs, char* content, size_t len);
+void http_build(str** _dest, int code, const char* code_det, char* header_vs, char* content, size_t len);
/**
* @brief gets a string representation of a http code
@@ -40,7 +42,7 @@ void http_build(str** _dest, int code, char* code_det, char* header_vs, char* co
* @param {int} http response code
* @param {char*} allocated destination string
*/
-void http_code(int code, char* code_det);
+const char* http_code(int code);
void client_fd_errors(int client_fd);
@@ -50,3 +52,4 @@ parray_t* route_match(parray_t* paths, char* path, larray_t** params);
int match_param(char* path, char* match, parray_t* arr);
+void parse_mimetypes();
diff --git a/src/thread.c b/src/thread.c
index 033da33..db8e54e 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -269,6 +269,7 @@ int _buffer_mod(lua_State* L){
int l_buffer_index(lua_State* L){
uint64_t len, hash;
+ struct thread_buffer *buffer = lua_touserdata(L, 1);
const char* str = luaL_tolstring(L, 2, &len);
hash = fnv_1((uint8_t*)str, len, v_1);
@@ -284,7 +285,15 @@ int l_buffer_index(lua_State* L){
lua_pushcfunction(L, _buffer_mod);
break;
default:
- lua_pushnil(L);
+ lua_pushstring(buffer->L, str);
+ lua_gettable(buffer->L, 1);
+ if(lua_isnil(buffer->L, -1)){
+ lua_pushnil(L);
+ return 1;
+ }
+
+ luaI_deepcopy(buffer->L, L, SKIP_GC);
+ lua_pop(buffer->L, 1);
break;
}
return 1;
@@ -349,7 +358,6 @@ return __proxy_call(__this_obj,'%s',table.unpack({_a,_b,_c}));end", key);
}
int l_buffer_gc(lua_State* L){
- printf("gc\n");
struct thread_buffer *buffer = lua_touserdata(L, 1);
pthread_mutex_lock(&*buffer->lock);
pthread_mutex_destroy(&*buffer->lock);
@@ -387,9 +395,8 @@ int l_buffer(lua_State* L){
void _lua_getfenv(lua_State* L){
}
-int l_testcopy(lua_State* L){
-
+int l_testcopy(lua_State* L){
lua_State* temp = luaL_newstate();
luaI_deepcopy(L, temp, SKIP_GC);
lua_close(temp);
diff --git a/src/types/str.c b/src/types/str.c
index 0378285..4b257cb 100644
--- a/src/types/str.c
+++ b/src/types/str.c
@@ -12,7 +12,7 @@ str* str_initl(const char* init, size_t len){
if(s->c == NULL) p_fatal("failed to allocate string\n");
s->len = len ;
- memcpy(s->c, init, len + 1);
+ memcpy(s->c, init, (len + 1) * sizeof * init);
return s;
}
diff --git a/tests/buffer.lua b/tests/buffer.lua
new file mode 100644
index 0000000..3309aed
--- /dev/null
+++ b/tests/buffer.lua
@@ -0,0 +1,9 @@
+llby = require "lullaby"
+
+b = llby.thread.buffer(llby.crypto.md5())
+
+print(b.update(b:get(), "meow"):final())
+print(b.update(b:get(), "meow"):final())
+b:mod(function(this) return this:update("meow") end)
+print(b.update(b:get(), "meow"):final())
+
diff --git a/tests/hash.lua b/tests/hash.lua
index 60d33a8..d314167 100644
--- a/tests/hash.lua
+++ b/tests/hash.lua
@@ -1,5 +1,7 @@
llib = require "lullaby"
+--llib.io.log = function() end
+
local hashes_working = 0
local hashes_failed = 0
local functions_working = 0
@@ -14,6 +16,8 @@ function test(name,b,exp,oargs)
local hash5
local hash6
local hash7
+ local hash8
+ local hash9
local add = ""
if oargs == nil then
hash = llib.crypto[name](b)
@@ -28,13 +32,29 @@ function test(name,b,exp,oargs)
hash5 = llib.crypto[name]()
hash6 = hash5 + b;
hash6 = hash6:final()
- hash5 = hash5:update(b):final()
+ hash5 = hash5:update(b):final()
+ hash7 = llib.crypto[name]()
else
hash2 = llib.crypto[name](table.unpack(oargs)):update(b):final()
hash5 = llib.crypto[name](table.unpack(oargs))
hash6 = hash5 + b;
hash6 = hash6:final()
hash5 = hash5:update(b):final()
+ hash7 = llib.crypto[name](table.unpack(oargs))
+ end
+
+ hash8 = hash7 + "test"
+ hash9 = hash8:final()
+ hash7 = hash7:update("meo"):final()
+ hash8 = hash8:final()
+
+ if hash8 ~= hash9 then
+ fail = true
+ functions_failed = functions_failed + 1
+ llib.io.error(name.." __copy not working")
+ else
+ functions_working = functions_working + 1
+ llib.io.log(name.." __copy working")
end
if(hash5 ~= exp) then
diff --git a/tests/net.lua b/tests/net.lua
index 90a18c3..e389fb0 100644
--- a/tests/net.lua
+++ b/tests/net.lua
@@ -18,10 +18,11 @@ net.listen(
io.pprint("online")
_G.server = server
- server:all("/{name}", function(res, req)
+ server:POST("/{name}", function(res, req)
--print("name is "..req.name)
print("name")
io.pprint(req.paramaters)
+ res:stop()
end)
server:all("/{name}/nya/{user}", function(res, req)
@@ -57,7 +58,7 @@ net.listen(
end)
server:GET("/aa", function(res, req)
- res.header["Content-Type"] = "text/plain"
+ --res.header["Content-Type"] = "text/plain"
res:sendfile("readme.md")
end)
diff --git a/tests/t.lua b/tests/t.lua
new file mode 100644
index 0000000..09ee15d
--- /dev/null
+++ b/tests/t.lua
@@ -0,0 +1,15 @@
+a = require "lullaby"
+
+b = coroutine.create(function()
+ os.execute("sleep 2")
+ print("co")
+end)
+
+c = a.thread.async(function(res, req)
+ coroutine.resume(b)
+end)
+
+os.execute("sleep 0.5")
+print("owo")
+
+c:await()
diff --git a/tests/thread.lua b/tests/thread.lua
new file mode 100644
index 0000000..8b7de88
--- /dev/null
+++ b/tests/thread.lua
@@ -0,0 +1,15 @@
+llby = require "lullaby"
+
+llby.thread.async(function(res, rej)
+ print("hi")
+ a = llby.crypto.sha512()
+ a:update("hi")
+ b = a + "meow"
+ print((b + "hi"):final())
+ print((a:update("hi")):final())
+ print((b + "hi"):final())
+end)
+
+os.execute("sleep 1")
+
+