From 87d6b741e893c25783803a6ce652635ca5dc15dc Mon Sep 17 00:00:00 2001 From: nishi Date: Sat, 20 Jan 2024 09:11:49 +0000 Subject: [PATCH] status git-svn-id: file:///raid/svn-main/nishi-libw3/trunk@33 d27a3e52-49c5-7645-884c-6793ebffc270 --- Example/fetch.c | 12 ++++++++++- Library/Core.c | 43 ++++++++++++++++++++++++++++++++++---- Library/HTTP.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ Library/Makefile | 2 +- Library/Util.c | 11 ++++++++++ Library/W3Core.h | 3 +++ Library/W3Util.h | 1 + Makefile | 12 +++++------ 8 files changed, 126 insertions(+), 12 deletions(-) diff --git a/Example/fetch.c b/Example/fetch.c index 060e976..5040dc3 100644 --- a/Example/fetch.c +++ b/Example/fetch.c @@ -7,8 +7,16 @@ #include #include -#include #include +#include + +void fetch_data(struct W3* w3, size_t size, char* data){ + write(1, data, size); +} + +void status(struct W3* w3, int status){ + printf("Response code is %d\n", status); +} int main(int argc, char** argv){ if(argv[1] != NULL && strcmp(argv[1], "--version") == 0){ @@ -24,6 +32,8 @@ int main(int argc, char** argv){ if(w3 != NULL){ W3_Set_Method(w3, "GET"); W3_Set_Path(w3, argv[2]); + W3_On(w3, "status", (void*)status); + W3_On(w3, "data", (void*)fetch_data); W3_Send_Request(w3); W3_Free(w3); }else{ diff --git a/Library/Core.c b/Library/Core.c index b04c10a..02fbc80 100644 --- a/Library/Core.c +++ b/Library/Core.c @@ -52,6 +52,7 @@ struct W3* W3_Create(const char* protocol, const char* hostname, int port){ } w3->method = NULL; w3->path = NULL; + w3->events = NULL; w3->headers = NULL; w3->protocol = __W3_Strdup(protocol); w3->hostname = __W3_Strdup(hostname); @@ -98,8 +99,8 @@ void W3_Set_Header(struct W3* w3, const char* key, const char* value){ w3->headers[len] = __W3_Strdup(key); w3->headers[len + 1] = __W3_Strdup(value); int i; - for(i = 0; w3->headers[len + 1][i] != 0; i++){ - w3->headers[len + 1][i] = tolower(w3->headers[len + 1][i]); + for(i = 0; w3->headers[len][i] != 0; i++){ + w3->headers[len][i] = tolower(w3->headers[len][i]); } w3->headers[len + 2] = NULL; }else{ @@ -113,13 +114,42 @@ void W3_Set_Header(struct W3* w3, const char* key, const char* value){ w3->headers[len + 1] = __W3_Strdup(value); w3->headers[len + 2] = NULL; int i; - for(i = 0; w3->headers[len + 1][i] != 0; i++){ - w3->headers[len + 1][i] = tolower(w3->headers[len + 1][i]); + for(i = 0; w3->headers[len][i] != 0; i++){ + w3->headers[len][i] = tolower(w3->headers[len][i]); } free(headers); } } +void W3_On(struct W3* w3, const char* eventname, void* func){ + int len = 0; + if(w3->events == NULL){ + w3->events = malloc(sizeof(*w3->events) * (len + 3)); + w3->events[len] = __W3_Strdup(eventname); + w3->events[len + 1] = func; + int i; + for(i = 0; ((char*)w3->events[len])[i] != 0; i++){ + ((char*)w3->events[len])[i] = tolower(((char*)w3->events[len])[i]); + } + w3->events[len + 2] = NULL; + }else{ + for(len = 0; w3->events[len] != NULL; len++); + void** events = w3->events; + w3->events = malloc(sizeof(*w3->events) * (len + 3)); + for(len = 0; events[len] != NULL; len++){ + w3->events[len] = events[len]; + } + w3->events[len] = __W3_Strdup(eventname); + w3->events[len + 1] = func; + w3->events[len + 2] = NULL; + int i; + for(i = 0; ((char*)w3->events[len])[i] != 0; i += 2){ + ((char*)w3->events[len])[i] = tolower(((char*)w3->events[len])[i]); + } + free(events); + } +} + void W3_Free(struct W3* w3){ __W3_Debug("LibW3", "Freeing"); if(w3->method != NULL) free(w3->method); @@ -131,5 +161,10 @@ void W3_Free(struct W3* w3){ for(i = 0; w3->headers[i] != 0; i++) free(w3->headers[i]); free(w3->headers); } + if(w3->events != NULL){ + int i; + for(i = 0; w3->events[i] != 0; i += 2) free(w3->events[i]); + free(w3->events); + } free(w3); } diff --git a/Library/HTTP.c b/Library/HTTP.c index 8e9deeb..35fc622 100644 --- a/Library/HTTP.c +++ b/Library/HTTP.c @@ -44,4 +44,58 @@ void __W3_HTTP_Request(struct W3* w3){ } __W3_Auto_Write(w3, "\r\n", 2); __W3_Auto_Write(w3, "\r\n", 2); + char* buf = malloc(512); + char* statusbuf = malloc(1); + statusbuf[0] = 0; + char* headerbuf = malloc(1); + headerbuf[0] = 0; + int phase = 0; + while(1){ + int l = __W3_Auto_Read(w3, buf, 512); + if(l <= 0) break; + int i; + for(i = 0; i < l; i++){ + if(phase == 0){ + if(buf[i] == '\r'){ + int phase2 = 0; + int j = 0; + int start_status = 0; + for(j = 0; statusbuf[j] != 0; j++){ + if(phase2 == 0){ + if(statusbuf[j] == ' '){ + phase2++; + start_status = j + 1; + } + }else if(phase2 == 1){ + if(statusbuf[j] == ' '){ + char* code = malloc(j - start_status + 1); + code[j - start_status] = 0; + memcpy(code, statusbuf + start_status, j - start_status); + w3->status = atoi(code); + void* funcptr = __W3_Get_Event(w3, "status"); + if(funcptr != NULL){ + void(*func)(struct W3*, int) = (void(*)(struct W3*, int))funcptr; + func(w3, w3->status); + } + free(code); + break; + } + } + } + phase++; + break; + }else{ + char* oldbuf = statusbuf; + statusbuf = malloc(strlen(oldbuf) + 2); + strcpy(statusbuf, oldbuf); + statusbuf[strlen(oldbuf)] = buf[i]; + statusbuf[strlen(oldbuf) + 1] = 0; + free(oldbuf); + } + } + } + } + free(headerbuf); + free(statusbuf); + free(buf); } diff --git a/Library/Makefile b/Library/Makefile index 1cc1276..3d39545 100644 --- a/Library/Makefile +++ b/Library/Makefile @@ -1,7 +1,7 @@ # $Id$ .PHONY: clean install -ifdef WINDOWS +ifeq ($(WINDOWS),YES) ./w3.dll: ./Core.o ./Util.o ./DNS.o ./HTTP.o $(CC) $(LDFLAGS) -shared -Wl,--out-implib,./w3.lib -o $@ $^ $(LIBS) else diff --git a/Library/Util.c b/Library/Util.c index 54614a9..0486987 100644 --- a/Library/Util.c +++ b/Library/Util.c @@ -78,6 +78,17 @@ unsigned long __W3_Auto_Read(struct W3* w3, char* data, unsigned long length){ #endif } +void* __W3_Get_Event(struct W3* w3, const char* eventname){ + if(w3->events == NULL) return NULL; + int i; + for(i = 0; w3->events[i] != NULL; i += 2){ + if(strcmp(w3->events[i], eventname) == 0){ + return w3->events[i + 1]; + } + } + return NULL; +} + bool __W3_Have_Header(struct W3* w3, const char* name){ if(w3->headers == NULL) return false; int i; diff --git a/Library/W3Core.h b/Library/W3Core.h index bc103af..3927f55 100644 --- a/Library/W3Core.h +++ b/Library/W3Core.h @@ -17,6 +17,8 @@ struct W3 { char* path; /* As you can read from its name */ char* hostname; /* As you can read from its name */ char** headers; /* As you can read from its name */ + void** events; /* As you can read from its name */ + int status; /* As you can read from its name */ #ifdef SSL_SUPPORT void* ssl; /* Actually SSL*, NULL if no SSL */ void* ssl_ctx; /* Actually SSL_CTX* */ @@ -31,6 +33,7 @@ void W3_Set_Path(struct W3* w3, const char* path); /* Set the path */ void W3_Send_Request(struct W3* w3); /* Send the request */ void W3_Set_Header(struct W3* w3, const char* key, const char* value); /* Set the header */ void W3_Free(struct W3* w3); /* Free the struct */ +void W3_On(struct W3* w3, const char* eventname, void* func); /* Set Handlers */ #ifdef __cplusplus } diff --git a/Library/W3Util.h b/Library/W3Util.h index 6fb36a3..500b24b 100644 --- a/Library/W3Util.h +++ b/Library/W3Util.h @@ -17,6 +17,7 @@ char* __W3_Strdup(const char* str); unsigned long __W3_Auto_Write(struct W3* w3, char* data, unsigned long length); unsigned long __W3_Auto_Read(struct W3* w3, char* data, unsigned long length); bool __W3_Have_Header(struct W3* w3, const char* name); +void* __W3_Get_Event(struct W3* w3, const char* eventname); char* __W3_Get_Platform(void); #ifdef __cplusplus diff --git a/Makefile b/Makefile index 69e65a5..25937a9 100644 --- a/Makefile +++ b/Makefile @@ -9,30 +9,30 @@ PREFIX := /usr/local VERSION = $(shell cat Library/W3Version.h | grep -m 1 LIBW3_VERSION | sed -E "s/.+\"([^\"]+)\".+/\1/g")$(shell cat Library/W3Version.h | grep -A 1 -Eo "LIBW3_VERSION" | tail -n1 | grep -Eo "W") -ifdef SSL +ifeq ($(SSL),YES) CFLAGS += -DSSL_SUPPORT LIBS += -lssl -lcrypto endif -ifdef WIN32 +ifeq ($(WIN32),YES) CC := i686-w64-mingw32-gcc WINDOWS := YES endif -ifdef WIN64 +ifeq ($(WIN64),YES) CC := x86_64-w64-mingw32-gcc WINDOWS := YES endif -ifdef WINDOWS +ifeq ($(WINDOWS),YES) LIBS += -lws2_32 endif -ifdef DEBUG +ifeq ($(DEBUG),YES) CFLAGS += -g -D__DEBUG__ endif -ifdef WINDOWS +ifeq ($(WINDOWS),YES) .PHONY: all clean ./Library/w3.dll ./Example/fetch ALL := ./Library/w3.dll ./Example/fetch.exe -- 2.43.0