From 9a2cadc6cb92b3b9ea516bc51431e4383d7ba59f Mon Sep 17 00:00:00 2001 From: nishi Date: Wed, 17 Jan 2024 12:23:33 +0000 Subject: [PATCH] user-agent git-svn-id: file:///raid/svn-main/nishi-libw3/trunk@22 d27a3e52-49c5-7645-884c-6793ebffc270 --- Example/fetch.c | 1 + Library/Core.c | 42 +++++++++++++++++++++++++++++++++++++++++- Library/HTTP.c | 21 +++++++++++++++++++++ Library/Util.c | 23 +++++++++++++++++++++++ Library/W3Core.h | 2 ++ Library/W3Util.h | 4 ++++ 6 files changed, 92 insertions(+), 1 deletion(-) diff --git a/Example/fetch.c b/Example/fetch.c index 40c033a..aa5f942 100644 --- a/Example/fetch.c +++ b/Example/fetch.c @@ -18,6 +18,7 @@ int main(int argc, char** argv){ struct W3* w3 = W3_Create("http", argv[1], 80); W3_Set_Method(w3, "GET"); W3_Set_Path(w3, "/sunhttpd"); + //W3_Set_Header(w3, "User-Agent", "W3-Fetch"); W3_Send_Request(w3); W3_Free(w3); } diff --git a/Library/Core.c b/Library/Core.c index f115f00..4ce4b21 100644 --- a/Library/Core.c +++ b/Library/Core.c @@ -9,7 +9,7 @@ #include #include #include - +#include #ifdef __MINGW32__ #include @@ -52,6 +52,7 @@ struct W3* W3_Create(const char* protocol, const char* hostname, int port){ } w3->method = NULL; w3->path = NULL; + w3->headers = NULL; w3->protocol = __W3_Strdup(protocol); w3->hostname = __W3_Strdup(hostname); if(ssl) __W3_Debug("Protocol", "Enabled SSL"); @@ -81,11 +82,50 @@ void W3_Send_Request(struct W3* w3){ } } +void W3_Set_Header(struct W3* w3, const char* key, const char* value){ + char* tmp = __W3_Concat3("Setting the header `", key, "` to `"); + char* str = __W3_Concat3(tmp, value, "`"); + free(tmp); + __W3_Debug("Header", str); + free(str); + int len = 0; + if(w3->headers == NULL){ + w3->headers = malloc(sizeof(*w3->headers) * (len + 3)); + 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]); + } + w3->headers[len + 2] = NULL; + }else{ + for(len = 0; w3->headers[len] != NULL; len++); + char** headers = w3->headers; + w3->headers = malloc(sizeof(*w3->headers) * (len + 3)); + for(len = 0; headers[len] != NULL; len++){ + w3->headers[len] = headers[len]; + } + w3->headers[len] = __W3_Strdup(key); + 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]); + } + free(headers); + } +} + void W3_Free(struct W3* w3){ __W3_Debug("LibW3", "Freeing"); if(w3->method != NULL) free(w3->method); if(w3->path != NULL) free(w3->path); if(w3->protocol != NULL) free(w3->protocol); if(w3->hostname != NULL) free(w3->hostname); + if(w3->headers != NULL){ + int i; + for(i = 0; w3->headers[i] != 0; i++) free(w3->headers[i]); + free(w3->headers); + } free(w3); } diff --git a/Library/HTTP.c b/Library/HTTP.c index 4be8a05..65e395e 100644 --- a/Library/HTTP.c +++ b/Library/HTTP.c @@ -17,5 +17,26 @@ void __W3_HTTP_Request(struct W3* w3){ __W3_Auto_Write(w3, "Host: ", 6); __W3_Auto_Write(w3, w3->hostname, strlen(w3->hostname)); __W3_Auto_Write(w3, "\r\n", 2); + if(!__W3_Have_Header(w3, "user-agent")){ + __W3_Auto_Write(w3, "User-Agent: ", 12); + __W3_Auto_Write(w3, "LibW3/", 6); + __W3_Auto_Write(w3, LIBW3_VERSION, strlen(LIBW3_VERSION)); + char* platform = __W3_Get_Platform(); + __W3_Auto_Write(w3, " (", 2); + __W3_Auto_Write(w3, platform, strlen(platform)); + free(platform); + __W3_Auto_Write(w3, ")", 1); + __W3_Auto_Write(w3, "\r\n", 2); + } + if(w3->headers != NULL){ + int i; + for(i = 0; w3->headers[i] != NULL; i += 2){ + __W3_Auto_Write(w3, w3->headers[i], strlen(w3->headers[i])); + __W3_Auto_Write(w3, ": ", 2); + __W3_Auto_Write(w3, w3->headers[i + 1], strlen(w3->headers[i + 1])); + __W3_Auto_Write(w3, "\r\n", 2); + } + } + __W3_Auto_Write(w3, "\r\n", 2); __W3_Auto_Write(w3, "\r\n", 2); } diff --git a/Library/Util.c b/Library/Util.c index fba72f2..54614a9 100644 --- a/Library/Util.c +++ b/Library/Util.c @@ -6,6 +6,7 @@ #include #include #include +#include #ifdef __MINGW32__ #include @@ -14,6 +15,7 @@ #include #include #include +#include #endif #ifdef SSL_SUPPORT @@ -75,3 +77,24 @@ unsigned long __W3_Auto_Read(struct W3* w3, char* data, unsigned long length){ return recv(w3->sock, data, length, 0); #endif } + +bool __W3_Have_Header(struct W3* w3, const char* name){ + if(w3->headers == NULL) return false; + int i; + for(i = 0; w3->headers[i] != NULL; i += 2){ + if(strcmp(w3->headers[i], name) == 0){ + return true; + } + } + return false; +} + +char* __W3_Get_Platform(void){ +#ifdef __MINGW32__ + return __W3_Strdup("Windows"); +#else + struct utsname un; + uname(&un); + return __W3_Concat3(un.sysname, "/", un.release); +#endif +} diff --git a/Library/W3Core.h b/Library/W3Core.h index b0c2c1a..6b18524 100644 --- a/Library/W3Core.h +++ b/Library/W3Core.h @@ -12,6 +12,7 @@ struct W3 { char* method; /* Used in HTTP */ 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 */ #ifdef SSL_SUPPORT void* ssl; /* Actually SSL*, NULL if no SSL */ void* ssl_ctx; /* Actually SSL_CTX* */ @@ -24,6 +25,7 @@ struct W3* W3_Create(const char* protocol, const char* hostname, int port); /* C void W3_Set_Method(struct W3* w3, const char* method); /* Set the method */ 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 */ #endif diff --git a/Library/W3Util.h b/Library/W3Util.h index 37c99da..b03f55c 100644 --- a/Library/W3Util.h +++ b/Library/W3Util.h @@ -4,11 +4,15 @@ #include "W3Core.h" +#include + void __W3_Debug(const char* title, const char* message); char* __W3_Concat(const char* str1, const char* str2); char* __W3_Concat3(const char* str1, const char* str2, const char* str3); 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); +char* __W3_Get_Platform(void); #endif -- 2.43.0