Inital commit
This commit is contained in:
commit
48b4173a7a
|
@ -0,0 +1,6 @@
|
||||||
|
# Misc notes.
|
||||||
|
|
||||||
|
We need to enable STATX in kore instead of STAT. One of the places seems to have
|
||||||
|
ifdef garuds around it, just added it to the other place.
|
||||||
|
|
||||||
|
We need to comment out the restrictions on mprotect around line 99 of src/seccomp.c in order for luajit to be able to do it's thing
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,14 @@
|
||||||
|
body{
|
||||||
|
margin:40px auto;
|
||||||
|
max-width:80%;
|
||||||
|
line-height:1.6;
|
||||||
|
font-size:18px;
|
||||||
|
color:#444 !important;
|
||||||
|
padding:0 10px
|
||||||
|
}
|
||||||
|
h1,h2,h3{line-height:1.2}
|
||||||
|
a,a:visited{color:#f99}
|
||||||
|
.spoiler,.spoiler2{background:#444}
|
||||||
|
.spoiler:hover,.spoiler2:hover{color:#FFF}
|
||||||
|
.greentext{color:#282}
|
||||||
|
.pinktext{color:#928}
|
|
@ -0,0 +1,38 @@
|
||||||
|
# smr build config
|
||||||
|
# You can switch flavors using: kodev flavor [newflavor]
|
||||||
|
|
||||||
|
# Set to yes if you wish to produce a single binary instead
|
||||||
|
# of a dynamic library. If you set this to yes you must also
|
||||||
|
# set kore_source together with kore_flavor.
|
||||||
|
#single_binary=no
|
||||||
|
#kore_source=/home/joris/src/kore
|
||||||
|
#kore_flavor=
|
||||||
|
|
||||||
|
# The flags below are shared between flavors
|
||||||
|
cflags=-Wall -Wmissing-declarations -Wshadow
|
||||||
|
cflags=-Wstrict-prototypes -Wmissing-prototypes
|
||||||
|
cflags=-Wpointer-arith -Wcast-qual -Wsign-compare
|
||||||
|
|
||||||
|
cxxflags=-Wall -Wmissing-declarations -Wshadow
|
||||||
|
cxxflags=-Wpointer-arith -Wcast-qual -Wsign-compare
|
||||||
|
|
||||||
|
# Mime types for assets served via the builtin asset_serve_*
|
||||||
|
mime_add=txt:text/plain; charset=utf-8
|
||||||
|
mime_add=png:image/png
|
||||||
|
mime_add=html:text/html; charset=utf-8
|
||||||
|
mime_add=css:text/css
|
||||||
|
|
||||||
|
dev {
|
||||||
|
# These flags are added to the shared ones when
|
||||||
|
# you build the "dev" flavor.
|
||||||
|
ldflags=-llua
|
||||||
|
cflags=-g
|
||||||
|
cxxflags=-g
|
||||||
|
}
|
||||||
|
|
||||||
|
prod {
|
||||||
|
cflags=-D BUILD_PROD
|
||||||
|
cflags=-I/usr/include/luajit-2.1
|
||||||
|
cflags=-lluajit-5.1
|
||||||
|
ldflags=-lluajit-5.1
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
# smr configuration
|
||||||
|
|
||||||
|
server tls {
|
||||||
|
bind 0.0.0.0 8888
|
||||||
|
}
|
||||||
|
|
||||||
|
seccomp_tracing yes
|
||||||
|
load ./smr.so
|
||||||
|
root kore_chroot
|
||||||
|
runas root
|
||||||
|
#keymgr_runas demo
|
||||||
|
#keymgr_root ./
|
||||||
|
workers 1
|
||||||
|
|
||||||
|
http_body_max 8388608
|
||||||
|
|
||||||
|
tls_dhparam dh2048.pem
|
||||||
|
|
||||||
|
validator v_any regex .*
|
||||||
|
validator v_storyid regex [a-zA-Z0-9]+
|
||||||
|
validator v_subdomain regex [a-z0-9]{1,30}
|
||||||
|
validator v_markup regex (plain|imageboard)
|
||||||
|
|
||||||
|
domain * {
|
||||||
|
attach tls
|
||||||
|
|
||||||
|
certfile server.pem
|
||||||
|
certkey key.pem
|
||||||
|
|
||||||
|
#I run kore behind a lighttpd reverse proxy, so this is a bit useless to me
|
||||||
|
#accesslog /dev/null
|
||||||
|
accesslog kore_access.log
|
||||||
|
|
||||||
|
route / home
|
||||||
|
route /_css/style.css asset_serve_style_css
|
||||||
|
route /_css/milligram.css asset_serve_milligram_css
|
||||||
|
route /_css/milligram.min.css.map asset_serve_milligram_min_css_map
|
||||||
|
route /favicon.ico asset_serve_favicon_ico
|
||||||
|
route /_paste post_story
|
||||||
|
route /_edit edit_story
|
||||||
|
route /_bio edit_bio
|
||||||
|
route /_login login
|
||||||
|
route /_claim claim
|
||||||
|
# Leading ^ is needed for dynamic routes, kore says the route is dynamic if it does not start with '/'
|
||||||
|
route ^/[^_].* read_story
|
||||||
|
|
||||||
|
params get /_edit {
|
||||||
|
validate story v_storyid
|
||||||
|
}
|
||||||
|
params post /_edit {
|
||||||
|
validate title v_any
|
||||||
|
validate story v_storyid
|
||||||
|
validate text v_any
|
||||||
|
validate pasteas v_subdomain
|
||||||
|
validate markup v_markup
|
||||||
|
}
|
||||||
|
params post /_paste {
|
||||||
|
validate title v_any
|
||||||
|
validate text v_any
|
||||||
|
validate pasteas v_subdomain
|
||||||
|
validate markup v_markup
|
||||||
|
}
|
||||||
|
#params get /[^_].* {
|
||||||
|
#validate story v_storyid
|
||||||
|
#}
|
||||||
|
params post /_login {
|
||||||
|
validate user v_subdomain
|
||||||
|
validate pass v_any
|
||||||
|
}
|
||||||
|
params post /_claim {
|
||||||
|
validate user v_any
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
-----BEGIN DH PARAMETERS-----
|
||||||
|
MIIBCAKCAQEAn4f4Qn5SudFjEYPWTbUaOTLUH85YWmmPFW1+b5bRa9ygr+1wfamv
|
||||||
|
VKVT7jO8c4msSNikUf6eEfoH0H4VTCaj+Habwu+Sj+I416r3mliMD4SjNsUJrBrY
|
||||||
|
Y0QV3ZUgZz4A8ARk/WwQcRl8+ZXJz34IaLwAcpyNhoV46iHVxW0ty8ND0U4DIku/
|
||||||
|
PNayKimu4BXWXk4RfwNVP59t8DQKqjshZ4fDnbotskmSZ+e+FHrd+Kvrq/WButvV
|
||||||
|
Bzy9fYgnUlJ82g/bziCI83R2xAdtH014fR63MpElkqdNeChb94pPbEdFlNUvYIBN
|
||||||
|
xx2vTUQMqRbB4UdG2zuzzr5j98HDdblQ+wIBAg==
|
||||||
|
-----END DH PARAMETERS-----
|
|
@ -0,0 +1,36 @@
|
||||||
|
#define FOR(i,n) for(i=0; i<n; ++i)
|
||||||
|
#include "keccak.h"
|
||||||
|
|
||||||
|
void Keccak(ui r, ui c, const u8 *in, u64 inLen, u8 sfx, u8 *out, u64 outLen);
|
||||||
|
void FIPS202_SHAKE128(const u8 *in, u64 inLen, u8 *out, u64 outLen) { Keccak(1344, 256, in, inLen, 0x1F, out, outLen); }
|
||||||
|
void FIPS202_SHAKE256(const u8 *in, u64 inLen, u8 *out, u64 outLen) { Keccak(1088, 512, in, inLen, 0x1F, out, outLen); }
|
||||||
|
void FIPS202_SHA3_224(const u8 *in, u64 inLen, u8 *out) { Keccak(1152, 448, in, inLen, 0x06, out, 28); }
|
||||||
|
void FIPS202_SHA3_256(const u8 *in, u64 inLen, u8 *out) { Keccak(1088, 512, in, inLen, 0x06, out, 32); }
|
||||||
|
void FIPS202_SHA3_384(const u8 *in, u64 inLen, u8 *out) { Keccak(832, 768, in, inLen, 0x06, out, 48); }
|
||||||
|
void FIPS202_SHA3_512(const u8 *in, u64 inLen, u8 *out) { Keccak(576, 1024, in, inLen, 0x06, out, 64); }
|
||||||
|
|
||||||
|
int LFSR86540(u8 *R) { (*R)=((*R)<<1)^(((*R)&0x80)?0x71:0); return ((*R)&2)>>1; }
|
||||||
|
#define ROL(a,o) ((((u64)a)<<o)^(((u64)a)>>(64-o)))
|
||||||
|
static u64 load64(const u8 *x) { ui i; u64 u=0; FOR(i,8) { u<<=8; u|=x[7-i]; } return u; }
|
||||||
|
static void store64(u8 *x, u64 u) { ui i; FOR(i,8) { x[i]=u; u>>=8; } }
|
||||||
|
static void xor64(u8 *x, u64 u) { ui i; FOR(i,8) { x[i]^=u; u>>=8; } }
|
||||||
|
#define rL(x,y) load64((u8*)s+8*(x+5*y))
|
||||||
|
#define wL(x,y,l) store64((u8*)s+8*(x+5*y),l)
|
||||||
|
#define XL(x,y,l) xor64((u8*)s+8*(x+5*y),l)
|
||||||
|
void KeccakF1600(void *s)
|
||||||
|
{
|
||||||
|
ui r,x,y,i,j,Y; u8 R=0x01; u64 C[5],D;
|
||||||
|
for(i=0; i<24; i++) {
|
||||||
|
/*θ*/ FOR(x,5) C[x]=rL(x,0)^rL(x,1)^rL(x,2)^rL(x,3)^rL(x,4); FOR(x,5) { D=C[(x+4)%5]^ROL(C[(x+1)%5],1); FOR(y,5) XL(x,y,D); }
|
||||||
|
/*ρπ*/ x=1; y=r=0; D=rL(x,y); FOR(j,24) { r+=j+1; Y=(2*x+3*y)%5; x=y; y=Y; C[0]=rL(x,y); wL(x,y,ROL(D,r%64)); D=C[0]; }
|
||||||
|
/*χ*/ FOR(y,5) { FOR(x,5) C[x]=rL(x,y); FOR(x,5) wL(x,y,C[x]^((~C[(x+1)%5])&C[(x+2)%5])); }
|
||||||
|
/*ι*/ FOR(j,7) if (LFSR86540(&R)) XL(0,0,(u64)1<<((1<<j)-1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Keccak(ui r, ui c, const u8 *in, u64 inLen, u8 sfx, u8 *out, u64 outLen)
|
||||||
|
{
|
||||||
|
/*initialize*/ u8 s[200]; ui R=r/8; ui i,b=0; FOR(i,200) s[i]=0;
|
||||||
|
/*absorb*/ while(inLen>0) { b=(inLen<R)?inLen:R; FOR(i,b) s[i]^=in[i]; in+=b; inLen-=b; if (b==R) { KeccakF1600(s); b=0; } }
|
||||||
|
/*pad*/ s[b]^=sfx; if((sfx&0x80)&&(b==(R-1))) KeccakF1600(s); s[R-1]^=0x80; KeccakF1600(s);
|
||||||
|
/*squeeze*/ while(outLen>0) { b=(outLen<R)?outLen:R; FOR(i,b) out[i]=s[i]; out+=b; outLen-=b; if(outLen>0) KeccakF1600(s); }
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
typedef unsigned char u8;
|
||||||
|
typedef unsigned long long int u64;
|
||||||
|
typedef unsigned int ui;
|
||||||
|
void FIPS202_SHA3_512(const u8 *in, u64 inLen, u8 *out);
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
borrowed sha3 implementation from keccak.team
|
||||||
|
*/
|
||||||
|
#ifdef BUILD_PROD
|
||||||
|
#include <luajit.h>
|
||||||
|
#endif
|
||||||
|
#include <lauxlib.h>
|
||||||
|
#include <lua.h>
|
||||||
|
#include <lualib.h>
|
||||||
|
#include "libcrypto.h"
|
||||||
|
#include "keccak.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
sha3(data::string)::string
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lsha3(lua_State *L){
|
||||||
|
size_t len;
|
||||||
|
char out[64];
|
||||||
|
const char *data = luaL_checklstring(L,-1,&len);
|
||||||
|
lua_pop(L,1);
|
||||||
|
printf("All data gotten, about to hash\n");
|
||||||
|
FIPS202_SHA3_512(data, len, out);
|
||||||
|
printf("Finished hashing\n");
|
||||||
|
lua_pushlstring(L,out,64);
|
||||||
|
printf("Finished pushing string to lua\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
string xor
|
||||||
|
sxor(a::string, b::string)::string
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lsxor(lua_State *L){
|
||||||
|
size_t la,lb;
|
||||||
|
const char *a = luaL_checklstring(L,-1,&la);
|
||||||
|
const char *b = luaL_checklstring(L,-2,&lb);
|
||||||
|
size_t outsize = la > lb ? la : lb;
|
||||||
|
size_t loopsize = la > lb ? lb : la;
|
||||||
|
const char *shorter = la > lb ? b : a;
|
||||||
|
const char *longer = la > lb ? a : b;
|
||||||
|
char out[outsize];
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < loopsize; i++)
|
||||||
|
out[i] = shorter[i] ^ longer[i];
|
||||||
|
for(;i < outsize; i++)
|
||||||
|
out[i] = longer[i];
|
||||||
|
lua_pushlstring(L,out,outsize);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const luaL_Reg crypto_funcs[] = {
|
||||||
|
{"sha3", lsha3},
|
||||||
|
{"sxor", lsxor},
|
||||||
|
{NULL,NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
load_crypto_libs(lua_State *L){
|
||||||
|
lua_getglobal(L,"_G");
|
||||||
|
luaL_register(L,NULL,crypto_funcs);
|
||||||
|
lua_pop(L,1);
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
int lsha3(lua_State *L);
|
||||||
|
int lsxor(lua_State *L);
|
||||||
|
void load_crypto_libs(lua_State *L);
|
|
@ -0,0 +1,292 @@
|
||||||
|
/*Export kore's functions to lua*/
|
||||||
|
#include <kore/kore.h>
|
||||||
|
#include <kore/http.h>
|
||||||
|
#ifdef BUILD_PROD
|
||||||
|
#include <luajit.h>
|
||||||
|
#endif
|
||||||
|
#include <lauxlib.h>
|
||||||
|
#include <lua.h>
|
||||||
|
#include <lualib.h>
|
||||||
|
//#include <inet/in.h>//linux only I guess
|
||||||
|
#include "libkore.h"
|
||||||
|
|
||||||
|
struct http_request*
|
||||||
|
luaL_checkrequest(lua_State *L, int pos){
|
||||||
|
if(!lua_isuserdata(L,pos)){
|
||||||
|
lua_pushstring(L,"Bad argument, expected userdata, got ");
|
||||||
|
lua_pushstring(L,lua_typename(L,lua_type(L,pos)));
|
||||||
|
lua_concat(L,2);
|
||||||
|
lua_error(L);
|
||||||
|
}
|
||||||
|
return lua_touserdata(L,pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
http_response(request::userdata, errcode::number, data::string)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lhttp_response(lua_State *L){
|
||||||
|
size_t size;
|
||||||
|
const char *data = luaL_checklstring(L,-1,&size);
|
||||||
|
int httpcode = luaL_checkint(L,-2);
|
||||||
|
struct http_request *req = luaL_checkrequest(L,-3);
|
||||||
|
http_response(req,httpcode,data,size);
|
||||||
|
lua_pop(L,3);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
http_method_text(request::userdata)::string
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lhttp_method_text(lua_State *L){
|
||||||
|
struct http_request *req = luaL_checkrequest(L,-1);
|
||||||
|
lua_pop(L,1);
|
||||||
|
const char *method = http_method_text(req->method);
|
||||||
|
lua_pushstring(L,method);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
http_request_get_path(request::userdata)::string
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lhttp_request_get_path(lua_State *L){
|
||||||
|
struct http_request *req = luaL_checkrequest(L,-1);
|
||||||
|
lua_pop(L,1);
|
||||||
|
const char *path = req->path;
|
||||||
|
lua_pushstring(L,path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
http_request_get_host(request::userdata)::string
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lhttp_request_get_host(lua_State *L){
|
||||||
|
struct http_request *req = luaL_checkrequest(L,-1);
|
||||||
|
lua_pop(L,1);
|
||||||
|
const char *host = req->host;
|
||||||
|
lua_pushstring(L,host);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
http_request_populate_post(request::userdata)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lhttp_request_populate_post(lua_State *L){
|
||||||
|
struct http_request *req = luaL_checkrequest(L,-1);
|
||||||
|
lua_pop(L,1);
|
||||||
|
http_populate_post(req);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
http_request_populate_qs(request::userdata)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lhttp_request_populate_qs(lua_State *L){
|
||||||
|
struct http_request *req = luaL_checkrequest(L,-1);
|
||||||
|
lua_pop(L,1);
|
||||||
|
http_populate_qs(req);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
http_response_header(request::userdata, header::string, value::string)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lhttp_response_header(lua_State *L){
|
||||||
|
const char *value = luaL_checkstring(L,-1);
|
||||||
|
const char *header = luaL_checkstring(L,-2);
|
||||||
|
struct http_request *req = luaL_checkrequest(L,-3);
|
||||||
|
lua_pop(L,3);
|
||||||
|
http_response_header(req, header, value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
http_response_cookie(req::userdata, name::string, value::string, path::string, expires::number, maxage::number)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lhttp_response_cookie(lua_State *L){
|
||||||
|
//int flags = luaL_checkint(L,-1);//TODO: flags
|
||||||
|
int maxage = luaL_checkint(L,-1);
|
||||||
|
int expires = luaL_checkint(L,-2);
|
||||||
|
const char *path = luaL_checkstring(L,-3);
|
||||||
|
const char *value = luaL_checkstring(L,-4);
|
||||||
|
const char *name = luaL_checkstring(L,-5);
|
||||||
|
struct http_request *req = luaL_checkrequest(L,-6);
|
||||||
|
lua_pop(L,6);
|
||||||
|
http_response_cookie(req,name,value,path,expires,maxage,NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
http_request_cookie(req::userdata, name::string)::string | nil
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lhttp_request_cookie(lua_State *L){
|
||||||
|
char *value;
|
||||||
|
const char *name = luaL_checkstring(L,-1);
|
||||||
|
struct http_request *req = luaL_checkrequest(L,-2);
|
||||||
|
lua_pop(L,2);
|
||||||
|
if(http_request_cookie(req,name,&value)){
|
||||||
|
lua_pushstring(L,value);
|
||||||
|
}else{
|
||||||
|
lua_pushnil(L);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This method may fail, if it does, it will return false plus an error message
|
||||||
|
http_argument_get_string(request::userdata, name::string)::(string || false, string)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lhttp_argument_get_string(lua_State *L){
|
||||||
|
const char *name = luaL_checkstring(L,-1);
|
||||||
|
struct http_request *req = luaL_checkrequest(L,-2);
|
||||||
|
lua_pop(L,2);
|
||||||
|
const char *value;
|
||||||
|
int err = http_argument_get_string(req,name,&value);
|
||||||
|
if(err == KORE_RESULT_OK){
|
||||||
|
lua_pushstring(L,value);
|
||||||
|
return 1;
|
||||||
|
}else{
|
||||||
|
lua_pushboolean(L,0);
|
||||||
|
lua_pushstring(L,"Failed to find argument: ");
|
||||||
|
lua_pushstring(L,name);
|
||||||
|
lua_concat(L,2);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Get the ip of this connection, ipv6 supported
|
||||||
|
http_request_get_ip(request::userdata)::string
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lhttp_request_get_ip(lua_State *L){
|
||||||
|
struct http_request *req = luaL_checkrequest(L,-1);
|
||||||
|
lua_pop(L,1);
|
||||||
|
char addr[INET6_ADDRSTRLEN];
|
||||||
|
printf("AF_INET:%d\n",AF_INET);
|
||||||
|
printf("AF_INET6:%d\n",AF_INET6);
|
||||||
|
printf("AF_UNIX:%d\n",AF_UNIX);
|
||||||
|
switch(req->owner->family){
|
||||||
|
case AF_INET:
|
||||||
|
inet_ntop(
|
||||||
|
req->owner->family,
|
||||||
|
&(req->owner->addr.ipv4.sin_addr),
|
||||||
|
addr,
|
||||||
|
sizeof(addr)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
inet_ntop(
|
||||||
|
req->owner->family,
|
||||||
|
&(req->owner->addr.ipv6.sin6_addr),
|
||||||
|
addr,
|
||||||
|
sizeof(addr)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case AF_UNIX:
|
||||||
|
default:
|
||||||
|
lua_pushstring(L,"Tried to get IP from unknown socket family:");
|
||||||
|
lua_getglobal(L,"tostring");
|
||||||
|
lua_pushnumber(L,req->owner->family);
|
||||||
|
lua_call(L,1,1);
|
||||||
|
lua_concat(L,2);
|
||||||
|
lua_error(L);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lua_pushstring(L,addr);
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
http_populate_cookies(request::userdata)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lhttp_populate_cookies(lua_State *L){
|
||||||
|
struct http_request *req = luaL_checkrequest(L,-1);
|
||||||
|
lua_pop(L,1);
|
||||||
|
http_populate_cookies(req);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
http_populate_multipart_form(request::userdata)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lhttp_populate_multipart_form(lua_State *L){
|
||||||
|
struct http_request *req = luaL_checkrequest(L,-1);
|
||||||
|
lua_pop(L,1);
|
||||||
|
http_populate_multipart_form(req);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
http_file_get(request::userdata, name::string)::string
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lhttp_file_get(lua_State *L){
|
||||||
|
const char *name = luaL_checkstring(L,-1);
|
||||||
|
struct http_request *req = luaL_checkrequest(L,-2);
|
||||||
|
lua_pop(L,2);
|
||||||
|
struct http_file *f = http_file_lookup(req, name);
|
||||||
|
if(f == NULL){
|
||||||
|
lua_pushstring(L,"No such file:");
|
||||||
|
lua_pushstring(L,name);
|
||||||
|
lua_concat(L,2);
|
||||||
|
lua_error(L);
|
||||||
|
}
|
||||||
|
printf("file length: %d\n", f->length);
|
||||||
|
char s[f->length + 1];
|
||||||
|
size_t read = http_file_read(f,s,f->length);
|
||||||
|
if(read < f->length){
|
||||||
|
lua_pushstring(L,"Failed to read contents of:");
|
||||||
|
lua_pushstring(L,name);
|
||||||
|
lua_concat(L,2);
|
||||||
|
lua_error(L);
|
||||||
|
}
|
||||||
|
s[f->length] = '\0';
|
||||||
|
lua_pushstring(L,s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const luaL_Reg kore_funcs[] = {
|
||||||
|
{"http_response", lhttp_response},
|
||||||
|
{"http_response_header", lhttp_response_header},
|
||||||
|
{"http_method_text",lhttp_method_text},
|
||||||
|
{"http_request_get_path",lhttp_request_get_path},
|
||||||
|
{"http_request_get_host",lhttp_request_get_host},
|
||||||
|
{"http_request_populate_post",lhttp_request_populate_post},
|
||||||
|
{"http_request_populate_qs",lhttp_request_populate_qs},
|
||||||
|
{"http_request_cookie",lhttp_request_cookie},
|
||||||
|
{"http_response_cookie",lhttp_response_cookie},
|
||||||
|
{"http_argument_get_string",lhttp_argument_get_string},
|
||||||
|
{"http_request_get_ip",lhttp_request_get_ip},
|
||||||
|
{"http_populate_cookies",lhttp_populate_cookies},
|
||||||
|
{"http_populate_multipart_form",lhttp_populate_multipart_form},
|
||||||
|
{"http_file_get",lhttp_file_get},
|
||||||
|
{NULL,NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const luaL_Reg http_request_meta[] = {
|
||||||
|
{NULL,NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
load_kore_libs(lua_State *L){
|
||||||
|
luaL_newmetatable(L,"http_request");//{m_http_request}
|
||||||
|
lua_newtable(L);//{m_http_request},{}
|
||||||
|
luaL_register(L,NULL,http_request_meta);//{m_http_request},{meta}
|
||||||
|
lua_setfield(L,-2,"__index");//{m_http_request}
|
||||||
|
lua_pop(L,1);
|
||||||
|
|
||||||
|
lua_getglobal(L,"_G");
|
||||||
|
luaL_register(L,NULL,kore_funcs);
|
||||||
|
lua_pop(L,1);
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
int lhttp_response(lua_State *L);
|
||||||
|
int lhttp_response_header(lua_State *L);
|
||||||
|
int lhttp_method_text(lua_State *L);
|
||||||
|
int lhttp_request_get_path(lua_State *L);
|
||||||
|
int lhttp_request_get_host(lua_State *L);
|
||||||
|
int lhttp_request_populate_post(lua_State *L);
|
||||||
|
int lhttp_response_cookie(lua_State *L);
|
||||||
|
int lhttp_request_cookie(lua_State *L);
|
||||||
|
int lhttp_argument_get_string(lua_State *L);
|
||||||
|
int lhttp_request_get_ip(lua_State *L);
|
||||||
|
int lhttp_populate_cookies(lua_State *L);
|
||||||
|
int lhttp_file_get(lua_State *L);
|
||||||
|
int lhttp_populate_multipart_form(lua_State *L);
|
||||||
|
void load_kore_libs(lua_State *L);
|
||||||
|
struct http_request* luaL_checkrequest(lua_State *L, int pos);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,111 @@
|
||||||
|
|
||||||
|
local lpeg = require("lpeg")
|
||||||
|
lpeg.locale(lpeg)
|
||||||
|
local V,P,C,S,B,Cs = lpeg.V,lpeg.P,lpeg.C,lpeg.S,lpeg.B,lpeg.Cs
|
||||||
|
--Characters to escape in the body text
|
||||||
|
local escapes = {
|
||||||
|
["&"] = "&",
|
||||||
|
["<"] = "<",
|
||||||
|
[">"] = ">",
|
||||||
|
}
|
||||||
|
local esctbl = {}
|
||||||
|
for char,_ in pairs(escapes) do
|
||||||
|
table.insert(esctbl,char)
|
||||||
|
end
|
||||||
|
local escapematch = string.format("([%s])",table.concat(esctbl))
|
||||||
|
local function sanitize_item(capture)
|
||||||
|
return escapes[capture] or capture
|
||||||
|
end
|
||||||
|
local function sanitize(text)
|
||||||
|
local ret,_ = string.gsub(text,escapematch,sanitize_item)
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
--Grammer
|
||||||
|
local space = S" \t\r"^0
|
||||||
|
local special = P{
|
||||||
|
P"**" + P"''" + P"'''" +
|
||||||
|
P"__" + P"==" + P"~~" +
|
||||||
|
P"\n>" + P"\n<" + P"\n" +
|
||||||
|
P"[code]" + P"[spoiler]"
|
||||||
|
}
|
||||||
|
local word = Cs((1 - special)^1) * space / sanitize
|
||||||
|
|
||||||
|
--Generates a pattern that formats text inside matching 'seq' tags with format
|
||||||
|
--ex wrap("^^",[[<sup>%s</sup>]])
|
||||||
|
--will wrapp text "5^^3^^" as "5<sup>3</sup>"
|
||||||
|
local function wrap(seq,format)
|
||||||
|
return P(seq) * Cs(((1 - P(seq)) * space)^1) * P(seq) * space / function(a)
|
||||||
|
return string.format(format,sanitize(a))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--Generates a pattern that formats text inside openinig and closing "name" tags
|
||||||
|
--with a format, BB forum style
|
||||||
|
local function tag(name,format)
|
||||||
|
local start_tag = P(string.format("[%s]",name))
|
||||||
|
local end_tag = P(string.format("[/%s]",name))
|
||||||
|
return start_tag * Cs(((1 - end_tag) * space)^1) * end_tag * space / function(a)
|
||||||
|
return string.format(format,sanitize(a))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local grammer = P{
|
||||||
|
"chunk";
|
||||||
|
--regular
|
||||||
|
spoiler = wrap("**",[[<span class="spoiler">%s</span>]]),
|
||||||
|
spoiler2 = tag("spoiler",[[<span class="spoiler2">%s</span>]]),
|
||||||
|
italic = wrap("''",[[<i>%s</i>]]),
|
||||||
|
bold = wrap("'''",[[<b>%s</b>]]),
|
||||||
|
underline = wrap("__",[[<u>%s</u>]]),
|
||||||
|
heading = wrap("==",[[<h2>%s</h2>]]),
|
||||||
|
strike = wrap("~~",[[<s>%s</s>]]),
|
||||||
|
code = tag("code",[[<pre><code>%s</code></pre>]]),
|
||||||
|
greentext = P"> " * Cs((V"marked" + word)^0) / function(a)
|
||||||
|
return string.format([[<span class="greentext">>%s</span>]],a)
|
||||||
|
end,
|
||||||
|
pinktext = P"< " * Cs((V"marked" + word)^0) / function(a)
|
||||||
|
return string.format([[<span class="pinktext"><%s</span>]],a)
|
||||||
|
end,
|
||||||
|
marked = V"spoiler" + V"bold" + V"italic" + V"underline" + V"heading" + V"strike" + V"spoiler2" + V"code",
|
||||||
|
plainline = (V"marked" + word)^0,
|
||||||
|
line = Cs(V"greentext" + V"pinktext" + V"plainline" + P"") * P"\n" / function(a)
|
||||||
|
return string.format("%s<br/>",a)
|
||||||
|
end,
|
||||||
|
ending = C(P(1)^0) / sanitize,
|
||||||
|
chunk = V"line"^0 * V"plainline" * V"ending"
|
||||||
|
}
|
||||||
|
|
||||||
|
--local text = [[
|
||||||
|
--this is **a big** test with ''italics''!
|
||||||
|
--we need to > sanitize < things that could be tags
|
||||||
|
--like really <b> badly </b>
|
||||||
|
--words can include any'single item without=penalty
|
||||||
|
--Can you use '''one tag ==within== another tag'''?
|
||||||
|
--let's see if [spoiler]spoiler tags work[/spoiler]
|
||||||
|
--things might even __go over
|
||||||
|
--multiple lines__ blah
|
||||||
|
--Let's test out those [code]
|
||||||
|
--code tag,s and see how well
|
||||||
|
--they work
|
||||||
|
--here's ome
|
||||||
|
--preformated <with injection>
|
||||||
|
--text
|
||||||
|
--[/code]
|
||||||
|
--> Or have blank lines
|
||||||
|
|
||||||
|
--one important thing is that greentext > should not start in the middle of a line
|
||||||
|
--> this next line is a green text, what if I include **markup** inside it?
|
||||||
|
--< and after '''it is''' a pinktext
|
||||||
|
--> because of some of these restrictions **bold text
|
||||||
|
--cannot go over multiple lines** in a green text
|
||||||
|
--__and finally__ there might be some text with '''
|
||||||
|
--incomplete syntax <b> with injection</b> !!!!
|
||||||
|
--]]
|
||||||
|
|
||||||
|
return function(text)
|
||||||
|
return table.concat({grammer:match(text .. "\n")}," ")
|
||||||
|
end
|
||||||
|
--for k,v in pairs({grammer:match(text)}) do
|
||||||
|
--print(k,":",v)
|
||||||
|
--end
|
|
@ -0,0 +1,22 @@
|
||||||
|
--Characters to escape in the body text
|
||||||
|
local escapes = {
|
||||||
|
["&"] = "&",
|
||||||
|
["<"] = "<",
|
||||||
|
[">"] = ">",
|
||||||
|
['"'] = """,
|
||||||
|
["'"] = "'",
|
||||||
|
--Kinda hacky
|
||||||
|
["\n"] = "<br/>",
|
||||||
|
}
|
||||||
|
local esctbl = {}
|
||||||
|
for char,_ in pairs(escapes) do
|
||||||
|
table.insert(esctbl,char)
|
||||||
|
end
|
||||||
|
local escapematch = string.format("([%s])",table.concat(esctbl))
|
||||||
|
|
||||||
|
local function sanitize(capture)
|
||||||
|
return escapes[capture] or capture
|
||||||
|
end
|
||||||
|
return function(text)
|
||||||
|
return string.gsub(text,escapematch,sanitize)
|
||||||
|
end
|
|
@ -0,0 +1,42 @@
|
||||||
|
<% assert(author,"No author specified") %>
|
||||||
|
<% assert(bio,"No bio included") %>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>🍑</title>
|
||||||
|
<link href="/_css/style.css" rel="stylesheet">
|
||||||
|
<link href="/_css/milligram.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body class="container">
|
||||||
|
<h1 class="title">
|
||||||
|
<a href="https://<%= author %>.<%= domain %>"><%= author %></a>.<a href="https://<%= domain %>"><%= domain %></a>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<form action="https://<%= author %>.<%= domain %>/" method="post" class="container">
|
||||||
|
<textarea name="" cols=80 rows=24 class="column">
|
||||||
|
<%= bio %>
|
||||||
|
</textarea><br/>
|
||||||
|
<input type="submit">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<% if #stories == 0 then %>
|
||||||
|
This author has not made any pastes yet.
|
||||||
|
<% else %>
|
||||||
|
<table>
|
||||||
|
<% for k,v in pairs(stories) do %>
|
||||||
|
<tr><td><%= v[1] %></td><td><%= v[2] %></td></tr>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="footer">
|
||||||
|
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
<body>
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
<% assert(author,"No author specified") %>
|
||||||
|
<% assert(bio,"No bio included") %>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>🍑</title>
|
||||||
|
<link href="/_css/style.css" rel="stylesheet">
|
||||||
|
<link href="/_css/milligram.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body class="container">
|
||||||
|
<h1 class="title">
|
||||||
|
<a href="https://<%= author %>.<%= domain %>"><%= author %></a>.<a href="https://<%= domain %>"><%= domain %></a>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<%= bio %>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<% if #stories == 0 then %>
|
||||||
|
This author has not made any pastes yet.
|
||||||
|
<% else %>
|
||||||
|
<table>
|
||||||
|
<% for k,v in pairs(stories) do %>
|
||||||
|
<tr><td>
|
||||||
|
<a href="<%= v.url %>">
|
||||||
|
<%- v.title %>
|
||||||
|
</a>
|
||||||
|
</td><td>
|
||||||
|
By <a href="https://<%= author %>.<%= domain %>"><%= author %></a>
|
||||||
|
</td><td>
|
||||||
|
<%= v.posted %>
|
||||||
|
</td></tr>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="footer">
|
||||||
|
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
<body>
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>🍑</title>
|
||||||
|
<link href="/_css/style.css" rel="stylesheet">
|
||||||
|
<link href="/_css/milligram.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main class="wrapper">
|
||||||
|
<h1 class="title">
|
||||||
|
Paste
|
||||||
|
</h1>
|
||||||
|
<% if err then %><em class="error"><%= err %></em><% end %>
|
||||||
|
<form action="https://<%= user %>.<%= domain %>/_paste" method="post" class="container">
|
||||||
|
<fieldset>
|
||||||
|
<div class="row">
|
||||||
|
<input type="text" name="title" placeholder="Title" class="column column-80"></input>
|
||||||
|
<select id="pasteas" name="pasteas" class="column column-10">
|
||||||
|
<option value="<%= user %>"><%= user %></option>
|
||||||
|
<option value="anonymous">Anonymous</option>
|
||||||
|
</select>
|
||||||
|
<select id="markup" name="markup" class="column column-10">
|
||||||
|
<option value="plain">Plain</option>
|
||||||
|
<option value="imageboard">Imageboard</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<textarea name="text" cols=80 rows=24 class="column"><%= text %></textarea><br/>
|
||||||
|
</div>
|
||||||
|
<input type="submit">
|
||||||
|
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
<footer class="footer">
|
||||||
|
|
||||||
|
</footer>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
<body>
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>🍑</title>
|
||||||
|
<link href="/_css/style.css" rel="stylesheet">
|
||||||
|
<link href="/_css/milligram.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body class="container">
|
||||||
|
<main class="wrapper">
|
||||||
|
<h1 class="title">
|
||||||
|
Register
|
||||||
|
</h1>
|
||||||
|
Once you press submit, you will be prompted to download a file.<br/>
|
||||||
|
slash.monster uses this file in place of a password, keep it safe.<br/>
|
||||||
|
Consider keeping a copy on a USB in case your hard drive fails.<br/>
|
||||||
|
The admin cannot recover your passfile, and will not reset accounts.<br/>
|
||||||
|
Names may be up to 30 characters, alphanumeric, all lower case.<br/>
|
||||||
|
<% if err then %><em class="error"><%= err %></em><% end %>
|
||||||
|
<form action="/_claim" method="post">
|
||||||
|
<fieldset>
|
||||||
|
<label for="user">Name:</label>
|
||||||
|
<input type="text" name="user" id="user" placeholder="name">
|
||||||
|
<input type="submit">
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
Once you have your file, you can <a href="/_login">log in</a>
|
||||||
|
<footer class="footer">
|
||||||
|
|
||||||
|
</footer>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
<body>
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>🍑</title>
|
||||||
|
<link href="/_css/style.css" rel="stylesheet">
|
||||||
|
<link href="/_css/milligram.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main class="wrapper">
|
||||||
|
<h1 class="title">
|
||||||
|
Paste
|
||||||
|
</h1>
|
||||||
|
<% if err then %><em class="error"><%= err %></em><% end %>
|
||||||
|
<form action="https://<%= user %>.<%= domain %>/_paste" method="post" class="container">
|
||||||
|
<fieldset>
|
||||||
|
<div class="row">
|
||||||
|
<input type="text" name="title" placeholder="Title" class="column column-80"></input>
|
||||||
|
<select id="pasteas" class="column column-10">
|
||||||
|
<option value="<%= user %>"><%= user %></option>
|
||||||
|
<option value="anonymous">anonymous</option>
|
||||||
|
</select>
|
||||||
|
<select id="markup" class="column column-10">
|
||||||
|
<option value="plain">Plain</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<textarea name="text" cols=80 rows=24 class="column"><%= text %></textarea><br/>
|
||||||
|
</div>
|
||||||
|
<input type="submit">
|
||||||
|
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
<footer class="footer">
|
||||||
|
|
||||||
|
</footer>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
<body>
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>🍑</title>
|
||||||
|
<link href="/_css/style.css" rel="stylesheet">
|
||||||
|
<link href="/_css/milligram.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body class="container">
|
||||||
|
<main class="wrapper">
|
||||||
|
<h1 class="title">
|
||||||
|
<a href="https://<%= domain %>">
|
||||||
|
<%= domain %>
|
||||||
|
</a>
|
||||||
|
</h1>
|
||||||
|
<div class="container">
|
||||||
|
<p>
|
||||||
|
Welcome to slash.monster, stories of fiction and fantasy<br/>
|
||||||
|
Not safe for work<br/>
|
||||||
|
18+
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<% if #stories == 0 then %>
|
||||||
|
No stories available.
|
||||||
|
<% else %>
|
||||||
|
<table>
|
||||||
|
<% for k,v in pairs(stories) do %>
|
||||||
|
<tr><td>
|
||||||
|
<a href="<%= v.url %>">
|
||||||
|
<%- v.title %>
|
||||||
|
</a>
|
||||||
|
</td><td>
|
||||||
|
<% if v.isanon then %>
|
||||||
|
By Anonymous
|
||||||
|
<% else %>
|
||||||
|
By <a href="https://<%= v.author %>.<%= domain %>"><%= v.author %></a>
|
||||||
|
<% end %>
|
||||||
|
</td><td>
|
||||||
|
<%= v.posted %>
|
||||||
|
</td></tr>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
<body>
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>🍑</title>
|
||||||
|
<link href="/_css/style.css" rel="stylesheet">
|
||||||
|
<link href="/_css/milligram.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body class="container">
|
||||||
|
<main class="wrapper">
|
||||||
|
<h1 class="title">
|
||||||
|
Login
|
||||||
|
</h1>
|
||||||
|
<% if err then %><em class="error"><%= err %></em><% end %>
|
||||||
|
<form action="/_login" method="post" enctype="multipart/form-data">
|
||||||
|
<fieldset>
|
||||||
|
<label for="user">Name:</label>
|
||||||
|
<input type="text" name="user" id="user" placeholder="name">
|
||||||
|
<label for="pass">Passfile:</label>
|
||||||
|
<input type="file" name="pass" id="pass">
|
||||||
|
<input type="submit">
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
<footer class="footer">
|
||||||
|
|
||||||
|
</footer>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
<body>
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>🙁</title>
|
||||||
|
<link href="/_css/style.css" rel="stylesheet">
|
||||||
|
<link href="/_css/milligram.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body class="container">
|
||||||
|
<main class="wrapper">
|
||||||
|
<h1 class="title">
|
||||||
|
🙁
|
||||||
|
</h1>
|
||||||
|
<div class="container">
|
||||||
|
<p>
|
||||||
|
No author found: <%= author %>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
<body>
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>🙁</title>
|
||||||
|
<link href="/_css/style.css" rel="stylesheet">
|
||||||
|
<link href="/_css/milligram.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body class="container">
|
||||||
|
<main class="wrapper">
|
||||||
|
<h1 class="title">
|
||||||
|
🙁
|
||||||
|
</h1>
|
||||||
|
<div class="container">
|
||||||
|
<p>
|
||||||
|
No story found: <%= path %>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
<body>
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>🍑</title>
|
||||||
|
<link href="/_css/style.css" rel="stylesheet">
|
||||||
|
<link href="/_css/milligram.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main class="wrapper">
|
||||||
|
<h1 class="title">
|
||||||
|
Paste
|
||||||
|
</h1>
|
||||||
|
<% if err then %><em class="error"><%= err %></em><% end %>
|
||||||
|
<form action="https://<%= domain %>/_paste" method="post" class="container"><fieldset>
|
||||||
|
<div class="row">
|
||||||
|
<input type="text" name="title" placeholder="Title" class="column column-80"></input>
|
||||||
|
<select id="markup" name="markup" class="column column-20">
|
||||||
|
<option value="plain">Plain</option>
|
||||||
|
<option value="imageboard">Imageboard</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<textarea name="text" cols=80 rows=24 class="column"></textarea><br/>
|
||||||
|
</div>
|
||||||
|
<input type="submit">
|
||||||
|
</fieldset></form>
|
||||||
|
<footer class="footer">
|
||||||
|
|
||||||
|
</footer>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
<body>
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title><%= title %></title>
|
||||||
|
<link href="/_css/style.css" rel="stylesheet">
|
||||||
|
<link href="/_css/milligram.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body class="container">
|
||||||
|
<main class="wrapper">
|
||||||
|
<h1>
|
||||||
|
<a href="https://<%= domain %>"><%= domain %></a>/<a href="https://<%= domain %>/<%= idp %>"><%= idp %></a>
|
||||||
|
</h1>
|
||||||
|
<% if owner then %>
|
||||||
|
<form action="https://<%= domain %>/_edit" method="get"><fieldset>
|
||||||
|
<input type="hidden" name="story" value="<%= idp %>"/>
|
||||||
|
<input type="submit" value="edit" class="button"/>
|
||||||
|
</fieldset></form>
|
||||||
|
<% end %>
|
||||||
|
<h1 class="title">
|
||||||
|
<%- title %>
|
||||||
|
</h1>
|
||||||
|
<% if isanon then %>
|
||||||
|
By Anonymous
|
||||||
|
<% else %>
|
||||||
|
By <a href="https://<%= author %>.<%= domain %>"><%= author %></a>
|
||||||
|
<% end %>
|
||||||
|
<article class="container content">
|
||||||
|
<%- text %>
|
||||||
|
</article>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
|
@ -0,0 +1,173 @@
|
||||||
|
#include <kore/kore.h>
|
||||||
|
#include <kore/http.h>
|
||||||
|
#ifdef BUILD_PROD
|
||||||
|
#include <luajit.h>
|
||||||
|
#else
|
||||||
|
#define LUA_OK 0
|
||||||
|
#endif
|
||||||
|
#include <lauxlib.h>
|
||||||
|
#include <lua.h>
|
||||||
|
#include <lualib.h>
|
||||||
|
#include "smr.h"
|
||||||
|
#include "libkore.h"
|
||||||
|
#include "libcrypto.h"
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
int home(struct http_request *);
|
||||||
|
int post_story(struct http_request *);
|
||||||
|
int edit_story(struct http_request *);
|
||||||
|
int edit_bio(struct http_request *);
|
||||||
|
int read_story(struct http_request *);
|
||||||
|
int login(struct http_request *);
|
||||||
|
int claim(struct http_request *);
|
||||||
|
int style(struct http_request *);
|
||||||
|
int miligram(struct http_request *);
|
||||||
|
int do_lua(struct http_request *req, const char *name);
|
||||||
|
int errhandeler(lua_State *);
|
||||||
|
lua_State *L;
|
||||||
|
|
||||||
|
/*
|
||||||
|
static / index
|
||||||
|
static / _post post
|
||||||
|
static / _edit edit
|
||||||
|
dynamic / .* read
|
||||||
|
static / _login login
|
||||||
|
static / _claim claim
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
errhandeler(lua_State *L){
|
||||||
|
printf("Error: %s\n",lua_tostring(L,1));
|
||||||
|
lua_getglobal(L,"debug");
|
||||||
|
lua_getglobal(L,"print");
|
||||||
|
lua_getfield(L,-2,"traceback");
|
||||||
|
lua_call(L,0,1);
|
||||||
|
lua_call(L,1,0);
|
||||||
|
lua_pop(L,1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
do_lua(struct http_request *req, const char *name){
|
||||||
|
printf("About to do lua %s\n",name);
|
||||||
|
lua_pushcfunction(L,errhandeler);
|
||||||
|
printf("Pushed errhandler function\n");
|
||||||
|
lua_getglobal(L,name);//err(),name()
|
||||||
|
if(!lua_isfunction(L,-1)){
|
||||||
|
printf("Could not find a method named %s\n",name);
|
||||||
|
lua_pop(L,2);//
|
||||||
|
return (KORE_RESULT_OK);
|
||||||
|
}
|
||||||
|
printf("About to push light userdata: %p\n",(void*)req);
|
||||||
|
lua_pushlightuserdata(L,req);//err,name(),ud_req
|
||||||
|
printf("About to pcall\n");
|
||||||
|
int err = lua_pcall(L,1,0,-3);
|
||||||
|
if(err != LUA_OK){
|
||||||
|
printf("Failed to run %s: %s\n",name,lua_tostring(L,-1));
|
||||||
|
http_response(req, 500, NULL, 0);
|
||||||
|
lua_pop(L,lua_gettop(L));
|
||||||
|
return (KORE_RESULT_OK);
|
||||||
|
}
|
||||||
|
return KORE_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
post_story(struct http_request *req){
|
||||||
|
printf("We want to post!\n");
|
||||||
|
return do_lua(req,"paste");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
edit_story(struct http_request *req){
|
||||||
|
printf("We want to edit!\n");
|
||||||
|
return do_lua(req,"edit");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
edit_bio(struct http_request *req){
|
||||||
|
printf("We want to edit bio!\n");
|
||||||
|
return do_lua(req,"edit_bio");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
read_story(struct http_request *req){
|
||||||
|
printf("We want to read!\n");
|
||||||
|
return do_lua(req,"read");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
login(struct http_request *req){
|
||||||
|
printf("We want to login!\n");
|
||||||
|
return do_lua(req,"login");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
claim(struct http_request *req){
|
||||||
|
printf("We want to claim!\n");
|
||||||
|
return do_lua(req,"claim");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
home(struct http_request *req){
|
||||||
|
return do_lua(req,"home");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kore_worker_configure(void){
|
||||||
|
printf("Configuring worker...\n");
|
||||||
|
int err;
|
||||||
|
/*DIR *dp;*/
|
||||||
|
/*struct dirent *ep;*/
|
||||||
|
/*dp = opendir("./");*/
|
||||||
|
/*if(dp != NULL){*/
|
||||||
|
/*while(ep = readdir(dp)){*/
|
||||||
|
/*printf("%s\n",ep->d_name);*/
|
||||||
|
/*}*/
|
||||||
|
/*closedir(dp);*/
|
||||||
|
/*}*/
|
||||||
|
L = luaL_newstate();
|
||||||
|
luaL_openlibs(L);
|
||||||
|
load_kore_libs(L);
|
||||||
|
load_crypto_libs(L);
|
||||||
|
lua_pushcfunction(L,errhandeler);
|
||||||
|
printf("About to run loadfile...\n");
|
||||||
|
luaL_loadfile(L,SM_INIT);
|
||||||
|
printf("Done running loadfile...\n");
|
||||||
|
if(!lua_isfunction(L,-1)){//failed to loadfile()
|
||||||
|
printf("Failed to load %s: %s\n",SM_INIT,lua_tostring(L,-1));
|
||||||
|
lua_pop(L,1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("About to pcall\n");
|
||||||
|
err = lua_pcall(L,0,LUA_MULTRET,-2);
|
||||||
|
printf("Done pcalling\n");
|
||||||
|
//err = luaL_dofile(L,"init.lua");
|
||||||
|
if(err){
|
||||||
|
printf("Failed to run %s\n",SM_INIT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lua_pushcfunction(L,errhandeler);
|
||||||
|
lua_getglobal(L,"configure");
|
||||||
|
err = lua_pcall(L,0,0,-2);
|
||||||
|
if(err != LUA_OK){
|
||||||
|
printf("Failed to run configure(): %s\n",lua_tostring(L,-1));
|
||||||
|
lua_pop(L,2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lua_pop(L,lua_gettop(L));
|
||||||
|
printf("Finished configuring worker\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kore_worker_teardown(void){
|
||||||
|
int err;
|
||||||
|
lua_pushcfunction(L,errhandeler);
|
||||||
|
lua_getglobal(L,"teardown");
|
||||||
|
err = lua_pcall(L,0,0,1);
|
||||||
|
if(err != LUA_OK){
|
||||||
|
printf("Failed to run configure(): %s\n",lua_tostring(L,-1));
|
||||||
|
lua_pop(L,2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lua_close(L);
|
||||||
|
}
|
Loading…
Reference in New Issue