From 2f90e9ecb8425deca5080aebf765294c45b5afd9 Mon Sep 17 00:00:00 2001 From: Davide Beatrici Date: Sun, 20 Oct 2019 02:17:42 +0200 Subject: [PATCH] Mayaqua: move HTTP functions from "Network" to "HTTP" --- src/Mayaqua/HTTP.c | 854 +++++++++++++++++++++++++++++++++++++++++ src/Mayaqua/HTTP.h | 65 ++++ src/Mayaqua/Network.c | 863 ------------------------------------------ src/Mayaqua/Network.h | 73 ---- 4 files changed, 919 insertions(+), 936 deletions(-) diff --git a/src/Mayaqua/HTTP.c b/src/Mayaqua/HTTP.c index 153d9854..7869a55c 100644 --- a/src/Mayaqua/HTTP.c +++ b/src/Mayaqua/HTTP.c @@ -2,6 +2,11 @@ #include +static char http_404_str[] = "\r\n\r\n404 Not Found\r\n\r\n

Not Found

\r\nThe requested URL $TARGET$ was not found on this server.

\r\n


\r\n
HTTP Server at $HOST$ Port $PORT$
\r\n\r\n"; +static char http_403_str[] = "\r\n\r\n403 Forbidden\r\n\r\n

Forbidden

\r\nYou don't have permission to access $TARGET$\r\non this server.

\r\n


\r\n
HTTP Server at $HOST$ Port $PORT$
\r\n\r\n"; +static char http_500_str[] = "\r\n\r\n500 Server Error\r\n\r\n

Server Error

\r\nServer Error

\r\n


\r\n
HTTP Server at $HOST$ Port $PORT$
\r\n\r\n"; +static char http_501_str[] = "\r\n\r\n501 Method Not Implemented\r\n\r\n

Method Not Implemented

\r\n$METHOD$ to $TARGET$ not supported.

\r\nInvalid method in request $METHOD$ $TARGET$ $VERSION$

\r\n


\r\n
HTTP Server at $HOST$ Port $PORT$
\r\n\r\n"; + // MIME list from https://www.freeformatter.com/mime-types-list.html static const HTTP_MIME_TYPE http_mime_types[] = { @@ -721,3 +726,852 @@ char *GetMimeTypeFromFileName(char *filename) return NULL; } + +// Generate the date and time string for the HTTP header +void GetHttpDateStr(char *str, UINT size, UINT64 t) +{ + SYSTEMTIME s; + static char *wday[] = + { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", + }; + static char *month[] = + { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", + "Nov", "Dec", + }; + // Validate arguments + if (str == NULL) + { + return; + } + UINT64ToSystem(&s, t); + + Format(str, size, "%s, %02u %s %04u %02u:%02u:%02u GMT", + wday[s.wDayOfWeek], s.wDay, month[s.wMonth - 1], s.wYear, + s.wHour, s.wMinute, s.wSecond); +} + +// Replace unsafe characters in target +void ReplaceUnsafeCharInHttpTarget(char *target) +{ + UINT i; + for(i = 0; target[i] ; i++) { + if(target[i] == '<') + target[i] = '('; + else if(target[i] == '>') + target[i] = ')'; + } +} + +// Create an HTTP header +HTTP_HEADER *NewHttpHeader(char *method, char *target, char *version) +{ + return NewHttpHeaderEx(method, target, version, false); +} +HTTP_HEADER *NewHttpHeaderEx(char *method, char *target, char *version, bool no_sort) +{ + HTTP_HEADER *header; + // Validate arguments + if (method == NULL || target == NULL || version == NULL) + { + return NULL; + } + + header = ZeroMalloc(sizeof(HTTP_HEADER)); + + header->Method = CopyStr(method); + header->Target = CopyStr(target); + header->Version = CopyStr(version); + header->ValueList = NewListFast(no_sort ? NULL : CompareHttpValue); + + return header; +} + +// Release the HTTP header +void FreeHttpHeader(HTTP_HEADER *header) +{ + UINT i; + HTTP_VALUE **values; + // Validate arguments + if (header == NULL) + { + return; + } + + Free(header->Method); + Free(header->Target); + Free(header->Version); + + values = ToArray(header->ValueList); + for (i = 0;i < LIST_NUM(header->ValueList);i++) + { + FreeHttpValue(values[i]); + } + Free(values); + + ReleaseList(header->ValueList); + + Free(header); +} + +// Create a new HTTP value +HTTP_VALUE *NewHttpValue(char *name, char *data) +{ + HTTP_VALUE *v; + // Validate arguments + if (name == NULL || data == NULL) + { + return NULL; + } + + v = ZeroMalloc(sizeof(HTTP_VALUE)); + + v->Name = CopyStr(name); + v->Data = CopyStr(data); + + Trim(v->Name); + Trim(v->Data); + + return v; +} + +// Release the HTTP value +void FreeHttpValue(HTTP_VALUE *value) +{ + // Validate arguments + if (value == NULL) + { + return; + } + + Free(value->Data); + Free(value->Name); + + Free(value); +} + +// Comparison function of the HTTP value +int CompareHttpValue(void *p1, void *p2) +{ + HTTP_VALUE *v1, *v2; + if (p1 == NULL || p2 == NULL) + { + return 0; + } + v1 = *(HTTP_VALUE **)p1; + v2 = *(HTTP_VALUE **)p2; + if (v1 == NULL || v2 == NULL) + { + return 0; + } + return StrCmpi(v1->Name, v2->Name); +} + +// Look for an HTTP value in an HTTP header +HTTP_VALUE *GetHttpValue(HTTP_HEADER *header, char *name) +{ + HTTP_VALUE *v, t; + // Validate arguments + if (header == NULL || name == NULL) + { + return NULL; + } + + t.Name = name; + v = Search(header->ValueList, &t); + if (v == NULL) + { + return NULL; + } + + return v; +} + +// Add an HTTP value to the HTTP header +void AddHttpValue(HTTP_HEADER *header, HTTP_VALUE *value) +{ + // Validate arguments + if (header == NULL || value == NULL) + { + return; + } + + if (LIST_NUM(header->ValueList) < HTTP_HEADER_MAX_LINES) + { + Insert(header->ValueList, value); + } + else + { + FreeHttpValue(value); + } +} + +// Adds the HTTP value contained in the string to the HTTP header +bool AddHttpValueStr(HTTP_HEADER* header, char *string) +{ + HTTP_VALUE *value = NULL; + UINT pos = 0; + char *value_name = NULL; + char *value_data = NULL; + + // Validate arguments + if (header == NULL || IsEmptyStr(string)) + { + return false; + } + + // Sanitize string + EnSafeHttpHeaderValueStr(string, ' '); + + // Get the position of the colon + pos = SearchStr(string, ":", 0); + if (pos == INFINITE) + { + // The colon does not exist + return false; + } + + if ((pos + 1) >= StrLen(string)) + { + // There is no data + return false; + } + + // Divide into the name and the data + value_name = Malloc(pos + 1); + Copy(value_name, string, pos); + value_name[pos] = 0; + value_data = &string[pos + 1]; + + value = NewHttpValue(value_name, value_data); + if (value == NULL) + { + Free(value_name); + return false; + } + + Free(value_name); + + AddHttpValue(header, value); + + return true; +} + +// Get the Content-Length value from the HTTP header +UINT GetContentLength(HTTP_HEADER *header) +{ + UINT ret; + HTTP_VALUE *v; + // Validate arguments + if (header == NULL) + { + return 0; + } + + v = GetHttpValue(header, "Content-Length"); + if (v == NULL) + { + return 0; + } + + ret = ToInt(v->Data); + + return ret; +} + +// Send HTTP data +bool PostHttp(SOCK *s, HTTP_HEADER *header, void *post_data, UINT post_size) +{ + char *header_str; + BUF *b; + bool ret; + // Validate arguments + if (s == NULL || header == NULL || (post_size != 0 && post_data == NULL)) + { + return false; + } + + // Check whether the Content-Length exists? + if (GetHttpValue(header, "Content-Length") == NULL) + { + char tmp[MAX_SIZE]; + // Add because it does not exist + ToStr(tmp, post_size); + AddHttpValue(header, NewHttpValue("Content-Length", tmp)); + } + + // Convert the header to string + header_str = HttpHeaderToStr(header); + if (header_str == NULL) + { + return false; + } + b = NewBuf(); + WriteBuf(b, header_str, StrLen(header_str)); + Free(header_str); + + // Append the data + WriteBuf(b, post_data, post_size); + + // Send + ret = SendAll(s, b->Buf, b->Size, s->SecureMode); + + FreeBuf(b); + + return ret; +} + +// Convert an HTTP header to a string +char *HttpHeaderToStr(HTTP_HEADER *header) +{ + BUF *b; + char *tmp; + UINT i; + char *s; + // Validate arguments + if (header == NULL) + { + return NULL; + } + + tmp = Malloc(HTTP_HEADER_LINE_MAX_SIZE); + b = NewBuf(); + + // Header + Format(tmp, HTTP_HEADER_LINE_MAX_SIZE, + "%s %s %s\r\n", header->Method, header->Target, header->Version); + WriteBuf(b, tmp, StrLen(tmp)); + + // Value + for (i = 0;i < LIST_NUM(header->ValueList);i++) + { + HTTP_VALUE *v = (HTTP_VALUE *)LIST_DATA(header->ValueList, i); + Format(tmp, HTTP_HEADER_LINE_MAX_SIZE, + "%s: %s\r\n", v->Name, v->Data); + WriteBuf(b, tmp, StrLen(tmp)); + } + + // Trailing newline + WriteBuf(b, "\r\n", 2); + s = Malloc(b->Size + 1); + Copy(s, b->Buf, b->Size); + s[b->Size] = 0; + + FreeBuf(b); + Free(tmp); + + return s; +} + +// Send the HTTP header +bool SendHttpHeader(SOCK *s, HTTP_HEADER *header) +{ + char *str; + bool ret; + // Validate arguments + if (s == NULL || header == NULL) + { + return false; + } + + // Convert to string + str = HttpHeaderToStr(header); + + // Transmission + ret = SendAll(s, str, StrLen(str), s->SecureMode); + + Free(str); + + return ret; +} + +// Receive an HTTP header +HTTP_HEADER *RecvHttpHeader(SOCK *s) +{ + TOKEN_LIST *token = NULL; + char *str = NULL; + HTTP_HEADER *header = NULL; + // Validate arguments + if (s == NULL) + { + return NULL; + } + + // Get the first line + str = RecvLine(s, HTTP_HEADER_LINE_MAX_SIZE); + if (str == NULL) + { + return NULL; + } + + // Split into tokens + token = ParseToken(str, " "); + + FreeSafe(PTR_TO_PTR(str)); + + if (token->NumTokens < 3) + { + FreeToken(token); + return NULL; + } + + // Creating a header object + header = NewHttpHeader(token->Token[0], token->Token[1], token->Token[2]); + FreeToken(token); + + if (StrCmpi(header->Version, "HTTP/0.9") == 0) + { + // The header ends with this line + return header; + } + + // Get the subsequent lines + while (true) + { + str = RecvLine(s, HTTP_HEADER_LINE_MAX_SIZE); + Trim(str); + if (IsEmptyStr(str)) + { + // End of header + FreeSafe(PTR_TO_PTR(str)); + break; + } + + if (AddHttpValueStr(header, str) == false) + { + FreeSafe(PTR_TO_PTR(str)); + FreeHttpHeader(header); + header = NULL; + break; + } + + FreeSafe(PTR_TO_PTR(str)); + } + + return header; +} + +// Send a PACK to the server +bool HttpClientSend(SOCK *s, PACK *p) +{ + BUF *b; + bool ret; + HTTP_HEADER *h; + char date_str[MAX_SIZE]; + char ip_str[MAX_SIZE]; + + // Validate arguments + if (s == NULL || p == NULL) + { + return false; + } + + IPToStr(ip_str, sizeof(ip_str), &s->RemoteIP); + + CreateDummyValue(p); + + b = PackToBuf(p); + if (b == NULL) + { + return false; + } + + h = NewHttpHeader("POST", HTTP_VPN_TARGET, "HTTP/1.1"); + + GetHttpDateStr(date_str, sizeof(date_str), SystemTime64()); + AddHttpValue(h, NewHttpValue("Date", date_str)); + AddHttpValue(h, NewHttpValue("Host", ip_str)); + AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE)); + AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive")); + AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE2)); + + ret = PostHttp(s, h, b->Buf, b->Size); + + FreeHttpHeader(h); + FreeBuf(b); + + return ret; +} + +// Receive a PACK from the server +PACK *HttpClientRecv(SOCK *s) +{ + BUF *b; + PACK *p; + HTTP_HEADER *h; + UINT size; + UCHAR *tmp; + HTTP_VALUE *v; + // Validate arguments + if (s == NULL) + { + return NULL; + } + + h = RecvHttpHeader(s); + if (h == NULL) + { + return NULL; + } + + if (StrCmpi(h->Method, "HTTP/1.1") != 0 || + StrCmpi(h->Target, "200") != 0) + { + FreeHttpHeader(h); + return NULL; + } + + v = GetHttpValue(h, "Content-Type"); + if (v == NULL || StrCmpi(v->Data, HTTP_CONTENT_TYPE2) != 0) + { + FreeHttpHeader(h); + return NULL; + } + + size = GetContentLength(h); + if (size == 0 || size > MAX_PACK_SIZE) + { + FreeHttpHeader(h); + return NULL; + } + + tmp = MallocEx(size, true); + if (RecvAll(s, tmp, size, s->SecureMode) == false) + { + Free(tmp); + FreeHttpHeader(h); + return NULL; + } + + b = NewBuf(); + WriteBuf(b, tmp, size); + Free(tmp); + FreeHttpHeader(h); + + SeekBuf(b, 0, 0); + p = BufToPack(b); + FreeBuf(b); + + return p; +} + +// Send a PACK to the client +bool HttpServerSend(SOCK *s, PACK *p) +{ + BUF *b; + bool ret; + HTTP_HEADER *h; + char date_str[MAX_SIZE]; + // Validate arguments + if (s == NULL || p == NULL) + { + return false; + } + + CreateDummyValue(p); + + b = PackToBuf(p); + if (b == NULL) + { + return false; + } + + h = NewHttpHeader("HTTP/1.1", "200", "OK"); + + GetHttpDateStr(date_str, sizeof(date_str), SystemTime64()); + AddHttpValue(h, NewHttpValue("Date", date_str)); + AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE)); + AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive")); + AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE2)); + + ret = PostHttp(s, h, b->Buf, b->Size); + + FreeHttpHeader(h); + FreeBuf(b); + + return ret; +} + +// Receive a PACK from the client +PACK *HttpServerRecv(SOCK *s) +{ + return HttpServerRecvEx(s, 0); +} +PACK *HttpServerRecvEx(SOCK *s, UINT max_data_size) +{ + BUF *b; + PACK *p; + HTTP_HEADER *h; + UINT size; + UCHAR *tmp; + HTTP_VALUE *v; + UINT num_noop = 0; + if (max_data_size == 0) max_data_size = HTTP_PACK_MAX_SIZE; + // Validate arguments + if (s == NULL) + { + return NULL; + } + +START: + h = RecvHttpHeader(s); + if (h == NULL) + { + goto BAD_REQUEST; + } + + if (StrCmpi(h->Method, "POST") != 0 || + StrCmpi(h->Target, HTTP_VPN_TARGET) != 0 || + StrCmpi(h->Version, "HTTP/1.1") != 0) + { + FreeHttpHeader(h); + goto BAD_REQUEST; + } + + v = GetHttpValue(h, "Content-Type"); + if (v == NULL || StrCmpi(v->Data, HTTP_CONTENT_TYPE2) != 0) + { + FreeHttpHeader(h); + goto BAD_REQUEST; + } + + size = GetContentLength(h); + if (size == 0 || (size > max_data_size)) + { + FreeHttpHeader(h); + goto BAD_REQUEST; + } + + tmp = MallocEx(size, true); + if (RecvAll(s, tmp, size, s->SecureMode) == false) + { + Free(tmp); + FreeHttpHeader(h); + return NULL; + } + + b = NewBuf(); + WriteBuf(b, tmp, size); + Free(tmp); + FreeHttpHeader(h); + + SeekBuf(b, 0, 0); + p = BufToPack(b); + FreeBuf(b); + + // Determine whether it's a NOOP + if (PackGetInt(p, "noop") != 0) + { + Debug("recv: noop\n"); + FreePack(p); + + p = PackError(0); + PackAddInt(p, "noop", 1); + if (HttpServerSend(s, p) == false) + { + FreePack(p); + return NULL; + } + + FreePack(p); + + num_noop++; + + if (num_noop > MAX_NOOP_PER_SESSION) + { + return NULL; + } + + goto START; + } + + return p; + +BAD_REQUEST: + // Return an error + return NULL; +} + +// Send "403 Forbidden" error +bool HttpSendForbidden(SOCK *s, char *target, char *server_id) +{ + HTTP_HEADER *h; + char date_str[MAX_SIZE]; + char *str; + UINT str_size; + char port_str[MAX_SIZE]; + bool ret; + char host[MAX_SIZE]; + UINT port; + // Validate arguments + if (s == NULL || target == NULL) + { + return false; + } + + // Get the host name + //GetMachineName(host, MAX_SIZE); + Zero(host, sizeof(host)); + IPToStr(host, sizeof(host), &s->LocalIP); + // Get the port number + port = s->LocalPort; + + // Creating a header + GetHttpDateStr(date_str, sizeof(date_str), SystemTime64()); + + h = NewHttpHeader("HTTP/1.1", "403", "Forbidden"); + + AddHttpValue(h, NewHttpValue("Date", date_str)); + AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE)); + AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive")); + AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE)); + + // Creating a Data + str_size = sizeof(http_403_str) * 2 + StrLen(target) + StrLen(host); + str = Malloc(str_size); + StrCpy(str, str_size, http_403_str); + + // TARGET + ReplaceUnsafeCharInHttpTarget(target); + ReplaceStri(str, str_size, str, "$TARGET$", target); + + // HOST + ReplaceStri(str, str_size, str, "$HOST$", host); + + // PORT + ToStr(port_str, port); + ReplaceStri(str, str_size, str, "$PORT$", port_str); + + // Transmission + ret = PostHttp(s, h, str, StrLen(str)); + + FreeHttpHeader(h); + Free(str); + + return ret; +} + +// Send "404 Not Found" error +bool HttpSendNotFound(SOCK *s, char *target) +{ + HTTP_HEADER *h; + char date_str[MAX_SIZE]; + char *str; + UINT str_size; + char port_str[MAX_SIZE]; + bool ret; + char host[MAX_SIZE]; + UINT port; + // Validate arguments + if (s == NULL || target == NULL) + { + return false; + } + + // Get the host name + //GetMachineName(host, MAX_SIZE); + Zero(host, sizeof(host)); + IPToStr(host, sizeof(host), &s->LocalIP); + // Get the port number + port = s->LocalPort; + + // Creating a header + GetHttpDateStr(date_str, sizeof(date_str), SystemTime64()); + + h = NewHttpHeader("HTTP/1.1", "404", "Not Found"); + + AddHttpValue(h, NewHttpValue("Date", date_str)); + AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE)); + AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive")); + AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE)); + + // Creating a Data + str_size = sizeof(http_404_str) * 2 + StrLen(target) + StrLen(host); + str = Malloc(str_size); + StrCpy(str, str_size, http_404_str); + + // TARGET + ReplaceUnsafeCharInHttpTarget(target); + ReplaceStri(str, str_size, str, "$TARGET$", target); + + // HOST + ReplaceStri(str, str_size, str, "$HOST$", host); + + // PORT + ToStr(port_str, port); + ReplaceStri(str, str_size, str, "$PORT$", port_str); + + // Transmission + ret = PostHttp(s, h, str, StrLen(str)); + + FreeHttpHeader(h); + Free(str); + + return ret; +} + +// Send "501 Not Implemented" error +bool HttpSendNotImplemented(SOCK *s, char *method, char *target, char *version) +{ + HTTP_HEADER *h; + char date_str[MAX_SIZE]; + char *str; + UINT str_size; + char port_str[MAX_SIZE]; + bool ret; + char host[MAX_SIZE]; + UINT port; + // Validate arguments + if (s == NULL || target == NULL) + { + return false; + } + + // Get the host name + //GetMachineName(host, MAX_SIZE); + Zero(host, sizeof(host)); + IPToStr(host, sizeof(host), &s->LocalIP); + // Get the port number + port = s->LocalPort; + + // Creating a header + GetHttpDateStr(date_str, sizeof(date_str), SystemTime64()); + + h = NewHttpHeader("HTTP/1.1", "501", "Method Not Implemented"); + + AddHttpValue(h, NewHttpValue("Date", date_str)); + AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE)); + AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive")); + AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE)); + + // Creating a Data + str_size = sizeof(http_501_str) * 2 + StrLen(target) + StrLen(host) + StrLen(method) + StrLen(version); + str = Malloc(str_size); + StrCpy(str, str_size, http_501_str); + + // TARGET + ReplaceUnsafeCharInHttpTarget(target); + ReplaceStri(str, str_size, str, "$TARGET$", target); + + // HOST + ReplaceStri(str, str_size, str, "$HOST$", host); + + // PORT + ToStr(port_str, port); + ReplaceStri(str, str_size, str, "$PORT$", port_str); + + // METHOD + ReplaceStri(str, str_size, str, "$METHOD$", method); + + // VERSION + ReplaceStri(str, str_size, str, "$VERSION$", version); + + // Transmission + ret = PostHttp(s, h, str, StrLen(str)); + + FreeHttpHeader(h); + Free(str); + + return ret; +} diff --git a/src/Mayaqua/HTTP.h b/src/Mayaqua/HTTP.h index f5f3b149..84814a8d 100644 --- a/src/Mayaqua/HTTP.h +++ b/src/Mayaqua/HTTP.h @@ -1,6 +1,47 @@ #ifndef HTTP_H #define HTTP_H +#define DEFAULT_USER_AGENT "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0" +#define DEFAULT_ACCEPT "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/msword, application/vnd.ms-powerpoint, application/vnd.ms-excel, */*" +#define DEFAULT_ENCODING "gzip, deflate" +#define HTTP_CONTENT_TYPE "text/html; charset=iso-8859-1" +#define HTTP_CONTENT_TYPE2 "application/octet-stream" +#define HTTP_CONTENT_TYPE3 "image/jpeg" +#define HTTP_CONTENT_TYPE4 "text/html" +#define HTTP_CONTENT_TYPE5 "message/rfc822" +#define HTTP_KEEP_ALIVE "timeout=15; max=19" +#define HTTP_VPN_TARGET "/vpnsvc/vpn.cgi" +#define HTTP_VPN_TARGET2 "/vpnsvc/connect.cgi" +#define HTTP_VPN_TARGET_POSTDATA "VPNCONNECT" +#define HTTP_SAITAMA "/saitama.jpg" +#define HTTP_PICTURES "/picture" +// Maximum size of the custom HTTP header +#define HTTP_CUSTOM_HEADER_MAX_SIZE 1024 +// Maximum size of a single line in the HTTP header +#define HTTP_HEADER_LINE_MAX_SIZE 4096 +// Maximum number of lines in the HTTP header +#define HTTP_HEADER_MAX_LINES 128 +// Maximum size of the random number to be included in the PACK +#define HTTP_PACK_RAND_SIZE_MAX 1000 +// Maximum PACK size in the HTTP +#define HTTP_PACK_MAX_SIZE 65536 + +// HTTP value +struct HTTP_VALUE +{ + char *Name; // Name + char *Data; // Data +}; + +// HTTP header +struct HTTP_HEADER +{ + char *Method; // Method + char *Target; // Target + char *Version; // Version + LIST *ValueList; // Value list +}; + // MIME type struct HTTP_MIME_TYPE { @@ -9,5 +50,29 @@ struct HTTP_MIME_TYPE }; char *GetMimeTypeFromFileName(char *filename); +void GetHttpDateStr(char *str, UINT size, UINT64 t); +void ReplaceUnsafeCharInHttpTarget(char *target); +HTTP_HEADER *NewHttpHeader(char *method, char *target, char *version); +HTTP_HEADER *NewHttpHeaderEx(char *method, char *target, char *version, bool no_sort); +void FreeHttpHeader(HTTP_HEADER *header); +HTTP_VALUE *NewHttpValue(char *name, char *data); +void FreeHttpValue(HTTP_VALUE *value); +int CompareHttpValue(void *p1, void *p2); +HTTP_VALUE *GetHttpValue(HTTP_HEADER *header, char *name); +void AddHttpValue(HTTP_HEADER *header, HTTP_VALUE *value); +bool AddHttpValueStr(HTTP_HEADER* header, char *string); +UINT GetContentLength(HTTP_HEADER *header); +bool PostHttp(SOCK *s, HTTP_HEADER *header, void *post_data, UINT post_size); +char *HttpHeaderToStr(HTTP_HEADER *header); +bool SendHttpHeader(SOCK *s, HTTP_HEADER *header); +HTTP_HEADER *RecvHttpHeader(SOCK *s); +bool HttpClientSend(SOCK *s, PACK *p); +PACK *HttpClientRecv(SOCK *s); +bool HttpServerSend(SOCK *s, PACK *p); +PACK *HttpServerRecv(SOCK *s); +PACK *HttpServerRecvEx(SOCK *s, UINT max_data_size); +bool HttpSendForbidden(SOCK *s, char *target, char *server_id); +bool HttpSendNotFound(SOCK *s, char *target); +bool HttpSendNotImplemented(SOCK *s, char *method, char *target, char *version); #endif diff --git a/src/Mayaqua/Network.c b/src/Mayaqua/Network.c index 1bb2f6d1..ce9cf798 100644 --- a/src/Mayaqua/Network.c +++ b/src/Mayaqua/Network.c @@ -76,13 +76,7 @@ struct ROUTE_CHANGE_DATA #endif // IPV6_V6ONLY #endif // UNIX_SOLARIS - - // HTTP constant -static char http_404_str[] = "\r\n\r\n404 Not Found\r\n\r\n

Not Found

\r\nThe requested URL $TARGET$ was not found on this server.

\r\n


\r\n
HTTP Server at $HOST$ Port $PORT$
\r\n\r\n"; -static char http_403_str[] = "\r\n\r\n403 Forbidden\r\n\r\n

Forbidden

\r\nYou don't have permission to access $TARGET$\r\non this server.

\r\n


\r\n
HTTP Server at $HOST$ Port $PORT$
\r\n\r\n"; -static char http_500_str[] = "\r\n\r\n500 Server Error\r\n\r\n

Server Error

\r\nServer Error

\r\n


\r\n
HTTP Server at $HOST$ Port $PORT$
\r\n\r\n"; -static char http_501_str[] = "\r\n\r\n501 Method Not Implemented\r\n\r\n

Method Not Implemented

\r\n$METHOD$ to $TARGET$ not supported.

\r\nInvalid method in request $METHOD$ $TARGET$ $VERSION$

\r\n


\r\n
HTTP Server at $HOST$ Port $PORT$
\r\n\r\n"; static char http_detect_server_startwith[] = "\r\n\r\n403 Forbidden\r\n\r\n

Forbidden

\r\nYou don't have permission to access "; static char http_detect_server_tag_future[] = "9C37197CA7C2428388C2E6E59B829B30"; @@ -19945,109 +19939,6 @@ void FlushTubeFlushList(TUBE_FLUSH_LIST *f) DeleteAll(f->List); } -// The server receives a PACK from the client -PACK *HttpServerRecv(SOCK *s) -{ - return HttpServerRecvEx(s, 0); -} -PACK *HttpServerRecvEx(SOCK *s, UINT max_data_size) -{ - BUF *b; - PACK *p; - HTTP_HEADER *h; - UINT size; - UCHAR *tmp; - HTTP_VALUE *v; - UINT num_noop = 0; - if (max_data_size == 0) max_data_size = HTTP_PACK_MAX_SIZE; - // Validate arguments - if (s == NULL) - { - return NULL; - } - -START: - - h = RecvHttpHeader(s); - if (h == NULL) - { - goto BAD_REQUEST; - } - - if (StrCmpi(h->Method, "POST") != 0 || - StrCmpi(h->Target, HTTP_VPN_TARGET) != 0 || - StrCmpi(h->Version, "HTTP/1.1") != 0) - { - FreeHttpHeader(h); - goto BAD_REQUEST; - } - - v = GetHttpValue(h, "Content-Type"); - if (v == NULL || StrCmpi(v->Data, HTTP_CONTENT_TYPE2) != 0) - { - FreeHttpHeader(h); - goto BAD_REQUEST; - } - - size = GetContentLength(h); - if (size == 0 || (size > max_data_size)) - { - FreeHttpHeader(h); - goto BAD_REQUEST; - } - - tmp = MallocEx(size, true); - if (RecvAll(s, tmp, size, s->SecureMode) == false) - { - Free(tmp); - FreeHttpHeader(h); - return NULL; - } - - b = NewBuf(); - WriteBuf(b, tmp, size); - Free(tmp); - FreeHttpHeader(h); - - SeekBuf(b, 0, 0); - p = BufToPack(b); - FreeBuf(b); - - // Determine whether it's a NOOP - if (PackGetInt(p, "noop") != 0) - { - Debug("recv: noop\n"); - FreePack(p); - - p = PackError(0); - PackAddInt(p, "noop", 1); - if (HttpServerSend(s, p) == false) - { - FreePack(p); - return NULL; - } - - FreePack(p); - - num_noop++; - - if (num_noop > MAX_NOOP_PER_SESSION) - { - return NULL; - } - - goto START; - } - - return p; - -BAD_REQUEST: - // Return an error - - - return NULL; -} - // Store the error value into PACK PACK *PackError(UINT error) { @@ -20071,68 +19962,6 @@ UINT GetErrorFromPack(PACK *p) return PackGetInt(p, "error"); } -// Client receives a PACK from the server -PACK *HttpClientRecv(SOCK *s) -{ - BUF *b; - PACK *p; - HTTP_HEADER *h; - UINT size; - UCHAR *tmp; - HTTP_VALUE *v; - // Validate arguments - if (s == NULL) - { - return NULL; - } - - h = RecvHttpHeader(s); - if (h == NULL) - { - return NULL; - } - - if (StrCmpi(h->Method, "HTTP/1.1") != 0 || - StrCmpi(h->Target, "200") != 0) - { - FreeHttpHeader(h); - return NULL; - } - - v = GetHttpValue(h, "Content-Type"); - if (v == NULL || StrCmpi(v->Data, HTTP_CONTENT_TYPE2) != 0) - { - FreeHttpHeader(h); - return NULL; - } - - size = GetContentLength(h); - if (size == 0 || size > MAX_PACK_SIZE) - { - FreeHttpHeader(h); - return NULL; - } - - tmp = MallocEx(size, true); - if (RecvAll(s, tmp, size, s->SecureMode) == false) - { - Free(tmp); - FreeHttpHeader(h); - return NULL; - } - - b = NewBuf(); - WriteBuf(b, tmp, size); - Free(tmp); - FreeHttpHeader(h); - - SeekBuf(b, 0, 0); - p = BufToPack(b); - FreeBuf(b); - - return p; -} - // Create an entry to PACK for the dummy void CreateDummyValue(PACK *p) { @@ -20153,497 +19982,6 @@ void CreateDummyValue(PACK *p) Free(buf); } -// Client sends a PACK to the server -bool HttpClientSend(SOCK *s, PACK *p) -{ - BUF *b; - bool ret; - HTTP_HEADER *h; - char date_str[MAX_SIZE]; - char ip_str[MAX_SIZE]; - - // Validate arguments - if (s == NULL || p == NULL) - { - return false; - } - - IPToStr(ip_str, sizeof(ip_str), &s->RemoteIP); - - CreateDummyValue(p); - - b = PackToBuf(p); - if (b == NULL) - { - return false; - } - - h = NewHttpHeader("POST", HTTP_VPN_TARGET, "HTTP/1.1"); - - GetHttpDateStr(date_str, sizeof(date_str), SystemTime64()); - AddHttpValue(h, NewHttpValue("Date", date_str)); - AddHttpValue(h, NewHttpValue("Host", ip_str)); - AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE)); - AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive")); - AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE2)); - - ret = PostHttp(s, h, b->Buf, b->Size); - - FreeHttpHeader(h); - FreeBuf(b); - - return ret; -} - -// Server sends a PACK to the client -bool HttpServerSend(SOCK *s, PACK *p) -{ - BUF *b; - bool ret; - HTTP_HEADER *h; - char date_str[MAX_SIZE]; - // Validate arguments - if (s == NULL || p == NULL) - { - return false; - } - - CreateDummyValue(p); - - b = PackToBuf(p); - if (b == NULL) - { - return false; - } - - h = NewHttpHeader("HTTP/1.1", "200", "OK"); - - GetHttpDateStr(date_str, sizeof(date_str), SystemTime64()); - AddHttpValue(h, NewHttpValue("Date", date_str)); - AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE)); - AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive")); - AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE2)); - - ret = PostHttp(s, h, b->Buf, b->Size); - - FreeHttpHeader(h); - FreeBuf(b); - - return ret; -} - -// Replace unsafe characters in target -void ReplaceUnsafeCharInTarget(char *target){ - UINT i; - for(i = 0; target[i] ; i++) { - if(target[i] == '<') - target[i] = '('; - else if(target[i] == '>') - target[i] = ')'; - } -} - -// Sending the 501 Not Implemented error -bool HttpSendNotImplemented(SOCK *s, char *method, char *target, char *version) -{ - HTTP_HEADER *h; - char date_str[MAX_SIZE]; - char *str; - UINT str_size; - char port_str[MAX_SIZE]; - bool ret; - char host[MAX_SIZE]; - UINT port; - // Validate arguments - if (s == NULL || target == NULL) - { - return false; - } - - // Get the host name - //GetMachineName(host, MAX_SIZE); - Zero(host, sizeof(host)); - IPToStr(host, sizeof(host), &s->LocalIP); - // Get the port number - port = s->LocalPort; - - // Creating a header - GetHttpDateStr(date_str, sizeof(date_str), SystemTime64()); - - h = NewHttpHeader("HTTP/1.1", "501", "Method Not Implemented"); - - AddHttpValue(h, NewHttpValue("Date", date_str)); - AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE)); - AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive")); - AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE)); - - // Creating a Data - str_size = sizeof(http_501_str) * 2 + StrLen(target) + StrLen(host) + StrLen(method) + StrLen(version); - str = Malloc(str_size); - StrCpy(str, str_size, http_501_str); - - // TARGET - ReplaceUnsafeCharInTarget(target); - ReplaceStri(str, str_size, str, "$TARGET$", target); - - // HOST - ReplaceStri(str, str_size, str, "$HOST$", host); - - // PORT - ToStr(port_str, port); - ReplaceStri(str, str_size, str, "$PORT$", port_str); - - // METHOD - ReplaceStri(str, str_size, str, "$METHOD$", method); - - // VERSION - ReplaceStri(str, str_size, str, "$VERSION$", version); - - // Transmission - ret = PostHttp(s, h, str, StrLen(str)); - - FreeHttpHeader(h); - Free(str); - - return ret; -} - -// Sending a 404 Not Found error -bool HttpSendNotFound(SOCK *s, char *target) -{ - HTTP_HEADER *h; - char date_str[MAX_SIZE]; - char *str; - UINT str_size; - char port_str[MAX_SIZE]; - bool ret; - char host[MAX_SIZE]; - UINT port; - // Validate arguments - if (s == NULL || target == NULL) - { - return false; - } - - // Get the host name - //GetMachineName(host, MAX_SIZE); - Zero(host, sizeof(host)); - IPToStr(host, sizeof(host), &s->LocalIP); - // Get the port number - port = s->LocalPort; - - // Creating a header - GetHttpDateStr(date_str, sizeof(date_str), SystemTime64()); - - h = NewHttpHeader("HTTP/1.1", "404", "Not Found"); - - AddHttpValue(h, NewHttpValue("Date", date_str)); - AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE)); - AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive")); - AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE)); - - // Creating a Data - str_size = sizeof(http_404_str) * 2 + StrLen(target) + StrLen(host); - str = Malloc(str_size); - StrCpy(str, str_size, http_404_str); - - // TARGET - ReplaceUnsafeCharInTarget(target); - ReplaceStri(str, str_size, str, "$TARGET$", target); - - // HOST - ReplaceStri(str, str_size, str, "$HOST$", host); - - // PORT - ToStr(port_str, port); - ReplaceStri(str, str_size, str, "$PORT$", port_str); - - // Transmission - ret = PostHttp(s, h, str, StrLen(str)); - - FreeHttpHeader(h); - Free(str); - - return ret; -} - -// Sending a 403 Forbidden error -bool HttpSendForbidden(SOCK *s, char *target, char *server_id) -{ - HTTP_HEADER *h; - char date_str[MAX_SIZE]; - char *str; - UINT str_size; - char port_str[MAX_SIZE]; - bool ret; - char host[MAX_SIZE]; - UINT port; - // Validate arguments - if (s == NULL || target == NULL) - { - return false; - } - - // Get the host name - //GetMachineName(host, MAX_SIZE); - Zero(host, sizeof(host)); - IPToStr(host, sizeof(host), &s->LocalIP); - // Get the port number - port = s->LocalPort; - - // Creating a header - GetHttpDateStr(date_str, sizeof(date_str), SystemTime64()); - - h = NewHttpHeader("HTTP/1.1", "403", "Forbidden"); - - AddHttpValue(h, NewHttpValue("Date", date_str)); - AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE)); - AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive")); - AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE)); - - // Creating a Data - str_size = sizeof(http_403_str) * 2 + StrLen(target) + StrLen(host); - str = Malloc(str_size); - StrCpy(str, str_size, http_403_str); - - // TARGET - ReplaceUnsafeCharInTarget(target); - ReplaceStri(str, str_size, str, "$TARGET$", target); - - // HOST - ReplaceStri(str, str_size, str, "$HOST$", host); - - // PORT - ToStr(port_str, port); - ReplaceStri(str, str_size, str, "$PORT$", port_str); - - // Transmission - ret = PostHttp(s, h, str, StrLen(str)); - - FreeHttpHeader(h); - Free(str); - - return ret; -} - -// Get the date and time string for the HTTP header -void GetHttpDateStr(char *str, UINT size, UINT64 t) -{ - SYSTEMTIME s; - static char *wday[] = - { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", - }; - static char *month[] = - { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", - "Nov", "Dec", - }; - // Validate arguments - if (str == NULL) - { - return; - } - UINT64ToSystem(&s, t); - - Format(str, size, "%s, %02u %s %04u %02u:%02u:%02u GMT", - wday[s.wDayOfWeek], s.wDay, month[s.wMonth - 1], s.wYear, - s.wHour, s.wMinute, s.wSecond); -} - -// Get the Content-Length from the HTTP header -UINT GetContentLength(HTTP_HEADER *header) -{ - UINT ret; - HTTP_VALUE *v; - // Validate arguments - if (header == NULL) - { - return 0; - } - - v = GetHttpValue(header, "Content-Length"); - if (v == NULL) - { - return 0; - } - - ret = ToInt(v->Data); - - return ret; -} - -// Send the data in the HTTP -bool PostHttp(SOCK *s, HTTP_HEADER *header, void *post_data, UINT post_size) -{ - char *header_str; - BUF *b; - bool ret; - // Validate arguments - if (s == NULL || header == NULL || (post_size != 0 && post_data == NULL)) - { - return false; - } - - // Check whether the Content-Length exists? - if (GetHttpValue(header, "Content-Length") == NULL) - { - char tmp[MAX_SIZE]; - // Add because it does not exist - ToStr(tmp, post_size); - AddHttpValue(header, NewHttpValue("Content-Length", tmp)); - } - - // Convert the header to string - header_str = HttpHeaderToStr(header); - if (header_str == NULL) - { - return false; - } - b = NewBuf(); - WriteBuf(b, header_str, StrLen(header_str)); - Free(header_str); - - // Append the data - WriteBuf(b, post_data, post_size); - - // Send - ret = SendAll(s, b->Buf, b->Size, s->SecureMode); - - FreeBuf(b); - - return ret; -} - -// Convert a HTTP header to a string -char *HttpHeaderToStr(HTTP_HEADER *header) -{ - BUF *b; - char *tmp; - UINT i; - char *s; - // Validate arguments - if (header == NULL) - { - return NULL; - } - - tmp = Malloc(HTTP_HEADER_LINE_MAX_SIZE); - b = NewBuf(); - - // Header - Format(tmp, HTTP_HEADER_LINE_MAX_SIZE, - "%s %s %s\r\n", header->Method, header->Target, header->Version); - WriteBuf(b, tmp, StrLen(tmp)); - - // Value - for (i = 0;i < LIST_NUM(header->ValueList);i++) - { - HTTP_VALUE *v = (HTTP_VALUE *)LIST_DATA(header->ValueList, i); - Format(tmp, HTTP_HEADER_LINE_MAX_SIZE, - "%s: %s\r\n", v->Name, v->Data); - WriteBuf(b, tmp, StrLen(tmp)); - } - - // Trailing newline - WriteBuf(b, "\r\n", 2); - s = Malloc(b->Size + 1); - Copy(s, b->Buf, b->Size); - s[b->Size] = 0; - - FreeBuf(b); - Free(tmp); - - return s; -} - -// Send the HTTP header -bool SendHttpHeader(SOCK *s, HTTP_HEADER *header) -{ - char *str; - bool ret; - // Validate arguments - if (s == NULL || header == NULL) - { - return false; - } - - // Convert to string - str = HttpHeaderToStr(header); - - // Transmission - ret = SendAll(s, str, StrLen(str), s->SecureMode); - - Free(str); - - return ret; -} - -// Receive an HTTP header -HTTP_HEADER *RecvHttpHeader(SOCK *s) -{ - TOKEN_LIST *token = NULL; - char *str = NULL; - HTTP_HEADER *header = NULL; - // Validate arguments - if (s == NULL) - { - return NULL; - } - - // Get the first line - str = RecvLine(s, HTTP_HEADER_LINE_MAX_SIZE); - if (str == NULL) - { - return NULL; - } - - // Split into tokens - token = ParseToken(str, " "); - - FreeSafe(PTR_TO_PTR(str)); - - if (token->NumTokens < 3) - { - FreeToken(token); - return NULL; - } - - // Creating a header object - header = NewHttpHeader(token->Token[0], token->Token[1], token->Token[2]); - FreeToken(token); - - if (StrCmpi(header->Version, "HTTP/0.9") == 0) - { - // The header ends with this line - return header; - } - - // Get the subsequent lines - while (true) - { - str = RecvLine(s, HTTP_HEADER_LINE_MAX_SIZE); - Trim(str); - if (IsEmptyStr(str)) - { - // End of header - FreeSafe(PTR_TO_PTR(str)); - break; - } - - if (AddHttpValueStr(header, str) == false) - { - FreeSafe(PTR_TO_PTR(str)); - FreeHttpHeaderSafe(&header); - break; - } - - FreeSafe(PTR_TO_PTR(str)); - } - - return header; -} - // Receive a line char *RecvLine(SOCK *s, UINT max_size) { @@ -20695,207 +20033,6 @@ char *RecvLine(SOCK *s, UINT max_size) } } -// Creating a new HTTP value -HTTP_VALUE *NewHttpValue(char *name, char *data) -{ - HTTP_VALUE *v; - // Validate arguments - if (name == NULL || data == NULL) - { - return NULL; - } - - v = ZeroMalloc(sizeof(HTTP_VALUE)); - - v->Name = CopyStr(name); - v->Data = CopyStr(data); - - Trim(v->Name); - Trim(v->Data); - - return v; -} - -// Look for the HTTP value from the HTTP header -HTTP_VALUE *GetHttpValue(HTTP_HEADER *header, char *name) -{ - HTTP_VALUE *v, t; - // Validate arguments - if (header == NULL || name == NULL) - { - return NULL; - } - - t.Name = name; - v = Search(header->ValueList, &t); - if (v == NULL) - { - return NULL; - } - - return v; -} - -// Add a HTTP value to the HTTP header -void AddHttpValue(HTTP_HEADER *header, HTTP_VALUE *value) -{ - // Validate arguments - if (header == NULL || value == NULL) - { - return; - } - - if (LIST_NUM(header->ValueList) < HTTP_HEADER_MAX_LINES) - { - Insert(header->ValueList, value); - } - else - { - FreeHttpValue(value); - } -} - -// Adds the HTTP value contained in the string to the HTTP header -bool AddHttpValueStr(HTTP_HEADER* header, char *string) -{ - HTTP_VALUE *value = NULL; - UINT pos = 0; - char *value_name = NULL; - char *value_data = NULL; - - // Validate arguments - if (header == NULL || IsEmptyStr(string)) - { - return false; - } - - // Sanitize string - EnSafeHttpHeaderValueStr(string, ' '); - - // Get the position of the colon - pos = SearchStr(string, ":", 0); - if (pos == INFINITE) - { - // The colon does not exist - return false; - } - - if ((pos + 1) >= StrLen(string)) - { - // There is no data - return false; - } - - // Divide into the name and the data - value_name = Malloc(pos + 1); - Copy(value_name, string, pos); - value_name[pos] = 0; - value_data = &string[pos + 1]; - - value = NewHttpValue(value_name, value_data); - if (value == NULL) - { - Free(value_name); - return false; - } - - Free(value_name); - - AddHttpValue(header, value); - - return true; -} - -// Create an HTTP header -HTTP_HEADER *NewHttpHeader(char *method, char *target, char *version) -{ - return NewHttpHeaderEx(method, target, version, false); -} -HTTP_HEADER *NewHttpHeaderEx(char *method, char *target, char *version, bool no_sort) -{ - HTTP_HEADER *header; - // Validate arguments - if (method == NULL || target == NULL || version == NULL) - { - return NULL; - } - - header = ZeroMalloc(sizeof(HTTP_HEADER)); - - header->Method = CopyStr(method); - header->Target = CopyStr(target); - header->Version = CopyStr(version); - header->ValueList = NewListFast(no_sort ? NULL : CompareHttpValue); - - return header; -} - -// Comparison function of the HTTP value -int CompareHttpValue(void *p1, void *p2) -{ - HTTP_VALUE *v1, *v2; - if (p1 == NULL || p2 == NULL) - { - return 0; - } - v1 = *(HTTP_VALUE **)p1; - v2 = *(HTTP_VALUE **)p2; - if (v1 == NULL || v2 == NULL) - { - return 0; - } - return StrCmpi(v1->Name, v2->Name); -} - -// Release the HTTP value -void FreeHttpValue(HTTP_VALUE *value) -{ - // Validate arguments - if (value == NULL) - { - return; - } - - Free(value->Data); - Free(value->Name); - - Free(value); -} - -// Release the HTTP header -void FreeHttpHeader(HTTP_HEADER *header) -{ - UINT i; - HTTP_VALUE **values; - // Validate arguments - if (header == NULL) - { - return; - } - - Free(header->Method); - Free(header->Target); - Free(header->Version); - - values = ToArray(header->ValueList); - for (i = 0;i < LIST_NUM(header->ValueList);i++) - { - FreeHttpValue(values[i]); - } - Free(values); - - ReleaseList(header->ValueList); - - Free(header); -} - -// Release the HTTP header and set pointer's value to NULL -void FreeHttpHeaderSafe(HTTP_HEADER **header) -{ - FreeHttpHeader(*header); - *header = NULL; -} - // Receive a PACK PACK *RecvPack(SOCK *s) { diff --git a/src/Mayaqua/Network.h b/src/Mayaqua/Network.h index 5689a8ee..06dbc6fd 100644 --- a/src/Mayaqua/Network.h +++ b/src/Mayaqua/Network.h @@ -874,53 +874,6 @@ struct NIC_ENTRY UCHAR MacAddress[6]; }; - -// HTTP value -struct HTTP_VALUE -{ - char *Name; // Name - char *Data; // Data -}; - -// HTTP header -struct HTTP_HEADER -{ - char *Method; // Method - char *Target; // Target - char *Version; // Version - LIST *ValueList; // Value list -}; - -// HTTPS server / client related string constant -#define DEFAULT_USER_AGENT "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0" -#define DEFAULT_ACCEPT "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/msword, application/vnd.ms-powerpoint, application/vnd.ms-excel, */*" -#define DEFAULT_ENCODING "gzip, deflate" -#define HTTP_CONTENT_TYPE "text/html; charset=iso-8859-1" -#define HTTP_CONTENT_TYPE2 "application/octet-stream" -#define HTTP_CONTENT_TYPE3 "image/jpeg" -#define HTTP_CONTENT_TYPE4 "text/html" -#define HTTP_CONTENT_TYPE5 "message/rfc822" -#define HTTP_KEEP_ALIVE "timeout=15; max=19" -#define HTTP_VPN_TARGET "/vpnsvc/vpn.cgi" -#define HTTP_VPN_TARGET2 "/vpnsvc/connect.cgi" -#define HTTP_VPN_TARGET_POSTDATA "VPNCONNECT" -#define HTTP_SAITAMA "/saitama.jpg" -#define HTTP_PICTURES "/picture" -// Maximum size of the custom HTTP header -#define HTTP_CUSTOM_HEADER_MAX_SIZE 1024 -// Maximum size of a single line in the HTTP header -#define HTTP_HEADER_LINE_MAX_SIZE 4096 -// Maximum number of lines in the HTTP header -#define HTTP_HEADER_MAX_LINES 128 -// Maximum size of the random number to be included in the PACK -#define HTTP_PACK_RAND_SIZE_MAX 1000 -// Maximum PACK size in the HTTP -#define HTTP_PACK_MAX_SIZE 65536 - - - - - int GetCurrentTimezone(); bool GetSniNameFromSslPacket(UCHAR *packet_buf, UINT packet_size, char *sni, UINT sni_size); @@ -934,16 +887,6 @@ bool IsUseAlternativeHostname(); int GetCurrentTimezoneWin32(); #endif // OS_WIN32 -HTTP_VALUE *GetHttpValue(HTTP_HEADER *header, char *name); -void AddHttpValue(HTTP_HEADER *header, HTTP_VALUE *value); -bool AddHttpValueStr(HTTP_HEADER* header, char *string); -HTTP_HEADER *NewHttpHeader(char *method, char *target, char *version); -HTTP_HEADER *NewHttpHeaderEx(char *method, char *target, char *version, bool no_sort); -int CompareHttpValue(void *p1, void *p2); -void FreeHttpValue(HTTP_VALUE *value); -void FreeHttpHeader(HTTP_HEADER *header); -void FreeHttpHeaderSafe(HTTP_HEADER **header); - bool SendPack(SOCK *s, PACK *p); PACK *RecvPack(SOCK *s); PACK *RecvPackWithHash(SOCK *s); @@ -954,23 +897,7 @@ PACK *PackError(UINT error); void CreateDummyValue(PACK *p); -HTTP_VALUE *NewHttpValue(char *name, char *data); char *RecvLine(SOCK *s, UINT max_size); -HTTP_HEADER *RecvHttpHeader(SOCK *s); -bool SendHttpHeader(SOCK *s, HTTP_HEADER *header); -char *HttpHeaderToStr(HTTP_HEADER *header); -bool PostHttp(SOCK *s, HTTP_HEADER *header, void *post_data, UINT post_size); -UINT GetContentLength(HTTP_HEADER *header); -void GetHttpDateStr(char *str, UINT size, UINT64 t); -bool HttpSendForbidden(SOCK *s, char *target, char *server_id); -bool HttpSendNotFound(SOCK *s, char *target); -bool HttpSendBody(SOCK *s, void *data, UINT size, char *contents_type); -bool HttpSendNotImplemented(SOCK *s, char *method, char *target, char *version); -bool HttpServerSend(SOCK *s, PACK *p); -bool HttpClientSend(SOCK *s, PACK *p); -PACK *HttpServerRecv(SOCK *s); -PACK *HttpServerRecvEx(SOCK *s, UINT max_data_size); -PACK *HttpClientRecv(SOCK *s); bool GetIPViaDnsProxyForJapanFlets(IP *ip_ret, char *hostname, bool ipv6, UINT timeout, bool *cancel, char *dns_proxy_hostname); bool GetDnsProxyIPAddressForJapanBFlets(IP *ip_ret, UINT timeout, bool *cancel);