summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClayton <nrootconauto@gmail.com>2023-02-28 20:09:07 -0500
committerClayton <nrootconauto@gmail.com>2023-02-28 20:09:07 -0500
commit7faa4e295525624b331a3b838b256a2d2d7bbca2 (patch)
treee863546c3f9abce9b101ad274c53404918016400
parent83fbfa6b6ebc84b3a604c80a4269bb32e2edd5d3 (diff)
Added HTTP cache mechanism
Uses ETags to track the file cache
-rw-r--r--T/Server/backup.HC2
-rw-r--r--T/Server/etags.HC41
-rw-r--r--T/Server/gen_html.HC3
-rw-r--r--T/Server/http.HC46
-rw-r--r--T/Server/run.HC5
5 files changed, 87 insertions, 10 deletions
diff --git a/T/Server/backup.HC b/T/Server/backup.HC
index d7911d1..563134f 100644
--- a/T/Server/backup.HC
+++ b/T/Server/backup.HC
@@ -67,7 +67,7 @@ ent:
}
timestamp=MStrPrint(WIKI_BACKUP_HEADER,t1,clone,user,Now,Now);
Free(t1);
-  timestamp2=MStrPrint("%D_%T",time,time);
+ timestamp2=MStrPrint("%D_%T",time,time);
while(StrFirstOcc(timestamp2,"/"))
*StrFirstOcc(timestamp2,"/")='-';
while(StrFirstOcc(timestamp2,":"))
diff --git a/T/Server/etags.HC b/T/Server/etags.HC
new file mode 100644
index 0000000..0b1582a
--- /dev/null
+++ b/T/Server/etags.HC
@@ -0,0 +1,41 @@
+U8 *RegisterETag(CServer *srv,U8 *file) {
+ CDirEntry dent;
+ CHashGeneric *gen;
+ U8 *tmp,*h;
+ file=ChrootFile(file);
+ if(FileFind(file,&dent)) {
+ gen=CAlloc(sizeof(CHashGeneric)+StrLen(file)+1,srv->task);
+ gen->type=HTT_FRAME_PTR;
+ tmp=MStrPrint("%s@%D@%T",file,dent.datetime,dent.datetime);
+ h=FNV64Str(tmp);
+ gen->str=StrNew(h,srv->task);
+ StrCpy(gen+1,file);
+ gen->user_data0=dent.datetime;
+ gen->user_data1=gen+1;
+ HashAdd(gen,srv->task->hash_table);
+ Free(h);
+ Free(tmp);
+ Free(dent.full_name);
+ tmp=MStrPrint("%s",gen->str);
+ } else
+ tmp=NULL;
+ Free(file);
+ return tmp;
+}
+Bool ETagChanged(CServer *srv,U8 *etag) {
+ CHashGeneric *gen=HashFind(etag,srv->task->hash_table,HTT_FRAME_PTR);
+ CDirEntry dent;
+ Bool ret=TRUE;
+ if(gen) {
+ if(!FileFind(gen->user_data1,&dent)) {
+ ret=TRUE;
+ goto fin;
+ }
+ Free(dent.full_name);
+ ret=dent.datetime>gen->user_data0;
+ }
+fin:
+ if(gen&&ret)
+ HashRemDel(gen,srv->task->hash_table);
+ return ret;
+} \ No newline at end of file
diff --git a/T/Server/gen_html.HC b/T/Server/gen_html.HC
index d8fccdc..6581928 100644
--- a/T/Server/gen_html.HC
+++ b/T/Server/gen_html.HC
@@ -21,6 +21,7 @@ U0 FileGet(CServer *srv,CDyadStream*stream,CURL *url,CHTTPRequest *req) {
StrCpy(con->response_mime,mime);
con->response_code=200;
WriteNBytes(stream,NULL,f,len);
+ con->cache_age=24*60*60*3; //3Days lol
Free(f);
} else {
R404(stream,&len,url->abs_path);
@@ -588,4 +589,4 @@ fin:
CServer *srv=CreateServer(8080);
srv->get=&Get;
srv->post=&Post;
-Serve(srv); \ No newline at end of file
+Serve(srv);
diff --git a/T/Server/http.HC b/T/Server/http.HC
index a04236f..df6baa9 100644
--- a/T/Server/http.HC
+++ b/T/Server/http.HC
@@ -28,7 +28,8 @@ class CConnection:CQue {
CUniqueToken *unique_token;
I64 is_dead,lock,response_length;
U8 *session_cookie,*response_text;
- I64 response_code,cache_age;
+ I64 response_code,cache_age;
+ Bool etag_changed,provided_etag;
U8 response_mime[STR_LEN];
U8 boundary[STR_LEN];
U8 field[STR_LEN];
@@ -254,12 +255,18 @@ CConnection *connects=MAlloc(sizeof(CQue));
QueInit(connects);
I64 con_locked=0;
U0 SendRequest(CDyadStream *s) {
- U8 *tmp,*cookie;
+ U8 *tmp,*tmp2,*cookie;
U8 *msg="200 OK";
CConnection *con=Fs->user_data;
+ if(con->provided_etag&&!con->etag_changed)
+ con->response_code=304;
switch(con->response_code) {
break;case 200: msg="200 OK";
- break;case 404: msg="404 NOT FOUND";
+ break;case 404: msg="404 Not Found";
+ break;case 304: msg="304 Not Modified";
+//If we have a 304(not-modefied)
+//We will ommit the body
+ con->response_length=0;
}
tmp=MStrPrint(
"HTTP/1.1 %s\x0d\n"
@@ -269,6 +276,19 @@ U0 SendRequest(CDyadStream *s) {
);
DyadWrite(s,tmp,StrLen(tmp));
Free(tmp);
+ if(con->cache_age) {
+ tmp2=RegisterETag(con->server,con->url->abs_path);
+ if(tmp2) {
+ tmp=MStrPrint(
+ "Date: %D\x0d\n"
+ "Cache-Control: max-age=%d\x0d\n"
+ "ETag: \"%q\"\x0d\n"
+ ,Now,con->cache_age,tmp2);
+ DyadWrite(s,tmp,StrLen(tmp));
+ Free(tmp);
+ }
+ Free(tmp2);
+ }
if(cookie=FramePtr(WIKI_SESSION_COOKIE)) {
tmp="Credentials: include\x0d\n"
"Mode: cors\x0d\n"
@@ -365,7 +385,7 @@ U0 SReadLine(CDyadStream *s,U8 *data,I64 len,CUniqueToken *ut) {
Yield;
CConnection *first,*con,*con2;
CHashGeneric *hash;
- U8 *buf=MAlloc(len+1),*buf2=MAlloc(len+1);
+ U8 *buf,*buf2;
U8 *fb,*http2,*t1,*t2,*odata;
first=connects;
for(con=first->next;con!=first;con=con->next) {
@@ -382,6 +402,7 @@ U0 SReadLine(CDyadStream *s,U8 *data,I64 len,CUniqueToken *ut) {
con->name=StrNew("",con->hc);
con->post_data=HashTableNew(0x10,con->hc);
found:
+ buf=MAlloc(len+1,con->hc),buf2=MAlloc(len+1,con->hc);
while(LBts(&con->lock,0))
Yield;
if(len==2) con->state.u8[0]=CON_S_BLANK_LINE;
@@ -441,7 +462,21 @@ qloop:
}
}
}
- if(!Bt(&con->state,CONf_DATA)&&!StrNCmp(data,"Connection",StrLen("Connection"))) {
+ if(!Bt(&con->state,CONf_DATA)&&!StrNICmp(data,"If-None-Match",StrLen("If-None-Match"))) {
+ con->provided_etag=TRUE;
+ data=SkipWhitespace(StrFirstOcc(data,":")+1);
+etag_loop:
+ t1=buf;
+ data=StrScan(data,"\"%s\"",&t1);
+ if(ETagChanged(con->server,buf)){
+ TOSPrint("ETAG_CHANGED:%s\n",buf);
+ con->etag_changed=1;
+ }
+ if(*data==',') {
+ data=SkipWhitespace(data+1);
+ goto etag_loop;
+ }
+ } else if(!Bt(&con->state,CONf_DATA)&&!StrNCmp(data,"Connection",StrLen("Connection"))) {
data=SkipWhitespace(StrFirstOcc(data,":")+1);
BEqu(&con->state,CONf_KEEP_ALIVE,ToBool(StrIMatch("keep-alive",data)));
} else if(!Bt(&con->state,CONf_DATA)&&!StrNCmp(data,"Cookie",StrLen("Cookie"))) {
@@ -604,7 +639,6 @@ found:
U0 ListenCallback(CDyadStream *s,CServer *srv) {
CUniqueToken *ut=MAlloc(sizeof(CUniqueToken));
ut->srv=srv;
- DyadSetTimeout(s,1);
DyadSetReadCallback(s,&SReadLine,ut);
DyadSetOnCloseCallback(s,&CloseCallback,ut);
}
diff --git a/T/Server/run.HC b/T/Server/run.HC
index 4b36970..0a61834 100644
--- a/T/Server/run.HC
+++ b/T/Server/run.HC
@@ -27,7 +27,7 @@ extern U0 FinalizeHTTPHeader(CDyadStream*);
extern U8 *GetCurrentUserName();
extern U8 *GetCurrentUser();
extern Bool CurrentUserIsBanned();
-//Checks if not logged in too
+//Checks if not logged in too
extern Bool UserPrivCheck(CServer *srv,CDyadStream *stream,CURL *url,CHTTPRequest *req,U8 *file);
extern Bool FileIsSalted(U8 *file);
extern Bool CurrentUserIsAdmin();
@@ -62,8 +62,10 @@ if(!FileFind(WIKI_PREVIEW))
DirMk(WIKI_PREVIEW);
if(!FileFind(WIKI_BACKUP))
DirMk(WIKI_BACKUP);
+#include "AUTH.HC"
#include "DynamStr.HC"
#include "utils.HC"
+#include "etags.HC"
#include "http.HC"
#include "header_footer.HC"
#include "find.HC"
@@ -74,6 +76,5 @@ if(!FileFind(WIKI_BACKUP))
#include "edit.HC"
#include "index.HC"
#include "cache.HC"
-#include "AUTH.HC"
#include "users.HC"
#include "gen_html.HC"; \ No newline at end of file