summaryrefslogtreecommitdiff
path: root/src/proxy/proxytrack.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/proxy/proxytrack.c')
-rw-r--r--src/proxy/proxytrack.c2492
1 files changed, 1306 insertions, 1186 deletions
diff --git a/src/proxy/proxytrack.c b/src/proxy/proxytrack.c
index ded2e13..e78f457 100644
--- a/src/proxy/proxytrack.c
+++ b/src/proxy/proxytrack.c
@@ -25,7 +25,6 @@ Please visit our Website: http://www.httrack.com
/* Author: Xavier Roche */
/* ------------------------------------------------------------ */
-
/*
/\/\/\/\/\/\/\/\/\/\/\/\/\ PENDING WORK /\/\/\/\/\/\/\/\/\/\/\/\/\
@@ -45,7 +44,6 @@ Aim: Building a sub-proxy to be linked with other top level proxies (such as Squ
Basic design: Classical HTTP/1.0 proxy server, with ICP server support
Internal data design: HTTrack cache indexing in fast hashtables, with 'pluggable' design (add/removal of caches on-the-fly)
-
Index structure organization:
-----------------------------
@@ -59,7 +57,6 @@ Indexes are hashtables with URL (STRING) -> INTEGER lookup.
URL -----> CIL Ask for index ID
URL -----> Index[ID] Ask for index properties (ZIP cache index)
-
Lookup of an entry:
-------------------
@@ -70,7 +67,6 @@ Else
return FAILURE
EndIf
-
Fetching of an entry:
---------------------
@@ -83,7 +79,6 @@ If ID is valid Then
EndIf
EndIf
-
Removal of index N:
-------------------
@@ -94,7 +89,6 @@ For all entries in Index[N]
Done
Delete Index[N]
-
Adding of index N:
------------------
@@ -146,65 +140,81 @@ Remark: If no cache newer than the added one is found, all entries can be added
/* threads */
#ifdef _WIN32
-#include <process.h> /* _beginthread, _endthread */
+#include <process.h> /* _beginthread, _endthread */
#else
#include <pthread.h>
#endif
/* External references */
// htsErrorCallback htsCallbackErr = NULL;
-int htsMemoryFastXfr = 1; /* fast xfr by default */
-void abortLog__fnc(char* msg, char* file, int line);
-void abortLog__fnc(char* msg, char* file, int line) {
- FILE* fp = fopen("CRASH.TXT", "wb");
- if (!fp) fp = fopen("/tmp/CRASH.TXT", "wb");
- if (!fp) fp = fopen("C:\\CRASH.TXT", "wb");
- if (!fp) fp = fopen("CRASH.TXT", "wb");
+int htsMemoryFastXfr = 1; /* fast xfr by default */
+void abortLog__fnc(char *msg, char *file, int line);
+void abortLog__fnc(char *msg, char *file, int line) {
+ FILE *fp = fopen("CRASH.TXT", "wb");
+
+ if (!fp)
+ fp = fopen("/tmp/CRASH.TXT", "wb");
+ if (!fp)
+ fp = fopen("C:\\CRASH.TXT", "wb");
+ if (!fp)
+ fp = fopen("CRASH.TXT", "wb");
if (fp) {
- fprintf(fp, "HTTrack " HTTRACK_VERSIONID " closed at '%s', line %d\r\n", file, line);
+ fprintf(fp, "HTTrack " HTTRACK_VERSIONID " closed at '%s', line %d\r\n",
+ file, line);
fprintf(fp, "Reason:\r\n%s\r\n", msg);
fflush(fp);
fclose(fp);
}
}
+
// HTSEXT_API t_abortLog abortLog__ = abortLog__fnc; /* avoid VC++ inlining */
#define webhttrack_lock(A) do{}while(0)
/* Static definitions */
-static int linputsoc(T_SOC soc, char* s, int max) {
+static int linputsoc(T_SOC soc, char *s, int max) {
int c;
- int j=0;
+ int j = 0;
+
do {
unsigned char ch;
+
if (recv(soc, &ch, 1, 0) == 1) {
c = ch;
} else {
c = EOF;
}
- if (c!=EOF) {
- switch(c) {
- case 13: break; // sauter CR
- case 10: c=-1; break;
- case 9: case 12: break; // sauter ces caractères
- default: s[j++]=(char) c; break;
+ if (c != EOF) {
+ switch (c) {
+ case 13:
+ break; // sauter CR
+ case 10:
+ c = -1;
+ break;
+ case 9:
+ case 12:
+ break; // sauter ces caractères
+ default:
+ s[j++] = (char) c;
+ break;
}
}
- } while((c!=-1) && (c!=EOF) && (j<(max-1)));
- s[j]='\0';
+ } while((c != -1) && (c != EOF) && (j < (max - 1)));
+ s[j] = '\0';
return j;
}
static int check_readinput_t(T_SOC soc, int timeout) {
if (soc != INVALID_SOCKET) {
- fd_set fds; // poll structures
+ fd_set fds; // poll structures
struct timeval tv; // structure for select
+
FD_ZERO(&fds);
- FD_SET(soc,&fds);
- tv.tv_sec=timeout;
- tv.tv_usec=0;
- select((int)(soc + 1),&fds,NULL,NULL,&tv);
- if (FD_ISSET(soc,&fds))
+ FD_SET(soc, &fds);
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+ select((int) (soc + 1), &fds, NULL, NULL, &tv);
+ if (FD_ISSET(soc, &fds))
return 1;
else
return 0;
@@ -212,102 +222,107 @@ static int check_readinput_t(T_SOC soc, int timeout) {
return 0;
}
-static int linputsoc_t(T_SOC soc, char* s, int max, int timeout) {
+static int linputsoc_t(T_SOC soc, char *s, int max, int timeout) {
if (check_readinput_t(soc, timeout)) {
return linputsoc(soc, s, max);
}
return -1;
}
-static int gethost(const char* hostname, SOCaddr *server, size_t server_size) {
+static int gethost(const char *hostname, SOCaddr * server, size_t server_size) {
if (hostname != NULL && *hostname != '\0') {
#if HTS_INET6==0
- /*
- ipV4 resolver
- */
- t_hostent* hp=gethostbyname(hostname);
- if (hp!=NULL) {
- if (hp->h_length) {
- SOCaddr_copyaddr(*server, server_size, hp->h_addr_list[0], hp->h_length);
- return 1;
- }
- }
+ /*
+ ipV4 resolver
+ */
+ t_hostent *hp = gethostbyname(hostname);
+
+ if (hp != NULL) {
+ if (hp->h_length) {
+ SOCaddr_copyaddr(*server, server_size, hp->h_addr_list[0],
+ hp->h_length);
+ return 1;
+ }
+ }
#else
- /*
- ipV6 resolver
- */
- struct addrinfo* res = NULL;
- struct addrinfo hints;
- memset(&hints, 0, sizeof(hints));
+ /*
+ ipV6 resolver
+ */
+ struct addrinfo *res = NULL;
+ struct addrinfo hints;
+
+ memset(&hints, 0, sizeof(hints));
#if 0
- if (IPV6_resolver == 1) // V4 only (for bogus V6 entries)
- hints.ai_family = PF_INET;
- else if (IPV6_resolver == 2) // V6 only (for testing V6 only)
- hints.ai_family = PF_INET6;
- else
+ if (IPV6_resolver == 1) // V4 only (for bogus V6 entries)
+ hints.ai_family = PF_INET;
+ else if (IPV6_resolver == 2) // V6 only (for testing V6 only)
+ hints.ai_family = PF_INET6;
+ else
#endif
- hints.ai_family = PF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
- if (getaddrinfo(hostname, NULL, &hints, &res) == 0) {
- if (res) {
- if ( (res->ai_addr) && (res->ai_addrlen) ) {
- SOCaddr_copyaddr(*server, server_size, res->ai_addr, res->ai_addrlen);
- freeaddrinfo(res);
- return 1;
- }
- }
- }
- if (res) {
- freeaddrinfo(res);
- }
-
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ if (getaddrinfo(hostname, NULL, &hints, &res) == 0) {
+ if (res) {
+ if ((res->ai_addr) && (res->ai_addrlen)) {
+ SOCaddr_copyaddr(*server, server_size, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+ return 1;
+ }
+ }
+ }
+ if (res) {
+ freeaddrinfo(res);
+ }
#endif
- }
- return 0;
+ }
+ return 0;
}
-static String getip(SOCaddr *server, int serverLen) {
- String s = STRING_EMPTY;
+static String getip(SOCaddr * server, int serverLen) {
+ String s = STRING_EMPTY;
+
#if HTS_INET6==0
- unsigned int sizeMax = sizeof("999.999.999.999:65535");
+ unsigned int sizeMax = sizeof("999.999.999.999:65535");
#else
- unsigned int sizeMax = sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:65535");
+ unsigned int sizeMax = sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:65535");
#endif
- char * dotted = malloc(sizeMax + 1);
- unsigned short port = ntohs(SOCaddr_sinport(*server));
- if (dotted == NULL) {
- proxytrack_print_log(CRITICAL, "memory exhausted");
- return s;
- }
- SOCaddr_inetntoa(dotted, sizeMax, *server, serverLen);
- sprintf(dotted + strlen(dotted), ":%d", port);
- StringAttach(&s, &dotted);
- return s;
+ char *dotted = malloc(sizeMax + 1);
+ unsigned short port = ntohs(SOCaddr_sinport(*server));
+
+ if (dotted == NULL) {
+ proxytrack_print_log(CRITICAL, "memory exhausted");
+ return s;
+ }
+ SOCaddr_inetntoa(dotted, sizeMax, *server, serverLen);
+ sprintf(dotted + strlen(dotted), ":%d", port);
+ StringAttach(&s, &dotted);
+ return s;
}
+static T_SOC smallserver_init(const char *adr, int port, int family) {
+ SOCaddr server;
+ size_t server_size = sizeof(server);
-static T_SOC smallserver_init(const char* adr, int port, int family) {
- SOCaddr server;
- size_t server_size = sizeof(server);
+ memset(&server, 0, sizeof(server));
+ SOCaddr_initany(server, server_size);
+ if (gethost(adr, &server, server_size)) { // host name
+ T_SOC soc = INVALID_SOCKET;
- memset(&server, 0, sizeof(server));
- SOCaddr_initany(server, server_size);
- if (gethost(adr, &server, server_size)) { // host name
- T_SOC soc = INVALID_SOCKET;
- if ( (soc = (T_SOC) socket(SOCaddr_sinfamily(server), family, 0)) != INVALID_SOCKET) {
+ if ((soc =
+ (T_SOC) socket(SOCaddr_sinfamily(server), family,
+ 0)) != INVALID_SOCKET) {
SOCaddr_initport(server, port);
- if ( bind(soc,(struct sockaddr*) &server, (int)server_size) == 0 ) {
- if (family != SOCK_STREAM
- || listen(soc, 10) >=0 ) {
- return soc;
+ if (bind(soc, (struct sockaddr *) &server, (int) server_size) == 0) {
+ if (family != SOCK_STREAM || listen(soc, 10) >= 0) {
+ return soc;
} else {
#ifdef _WIN32
closesocket(soc);
#else
close(soc);
#endif
- soc=INVALID_SOCKET;
+ soc = INVALID_SOCKET;
}
} else {
#ifdef _WIN32
@@ -315,7 +330,7 @@ static T_SOC smallserver_init(const char* adr, int port, int family) {
#else
close(soc);
#endif
- soc=INVALID_SOCKET;
+ soc = INVALID_SOCKET;
}
}
}
@@ -323,26 +338,26 @@ static T_SOC smallserver_init(const char* adr, int port, int family) {
}
static int proxytrack_start(PT_Indexes indexes, T_SOC soc, T_SOC socICP);
-int proxytrack_main(char* proxyAddr, int proxyPort,
- char* icpAddr, int icpPort,
- PT_Indexes index) {
+int proxytrack_main(char *proxyAddr, int proxyPort, char *icpAddr, int icpPort,
+ PT_Indexes index) {
int returncode = 0;
T_SOC soc = smallserver_init(proxyAddr, proxyPort, SOCK_STREAM);
T_SOC socICP = smallserver_init(proxyAddr, icpPort, SOCK_DGRAM);
- if (soc != INVALID_SOCKET
- && socICP != INVALID_SOCKET)
- {
- char url[HTS_URLMAXSIZE*2];
+
+ if (soc != INVALID_SOCKET && socICP != INVALID_SOCKET) {
+ char url[HTS_URLMAXSIZE * 2];
char method[32];
char data[32768];
- url[0]=method[0]=data[0]='\0';
+
+ url[0] = method[0] = data[0] = '\0';
//
printf("HTTP Proxy installed on %s:%d/\n", proxyAddr, proxyPort);
printf("ICP Proxy installed on %s:%d/\n", icpAddr, icpPort);
#ifndef _WIN32
{
pid_t pid = getpid();
- printf("PID=%d\n", (int)pid);
+
+ printf("PID=%d\n", (int) pid);
}
#endif
fflush(stdout);
@@ -350,7 +365,9 @@ int proxytrack_main(char* proxyAddr, int proxyPort,
//
if (!proxytrack_start(index, soc, socICP)) {
int last_errno = errno;
- fprintf(stderr, "Unable to create the server: %s\n", strerror(last_errno));
+
+ fprintf(stderr, "Unable to create the server: %s\n",
+ strerror(last_errno));
#ifdef _WIN32
closesocket(soc);
#else
@@ -363,7 +380,9 @@ int proxytrack_main(char* proxyAddr, int proxyPort,
}
} else {
int last_errno = errno;
- fprintf(stderr, "Unable to initialize a temporary server : %s\n", strerror(last_errno));
+
+ fprintf(stderr, "Unable to initialize a temporary server : %s\n",
+ strerror(last_errno));
returncode = 1;
}
printf("EXITED\n");
@@ -372,1020 +391,1104 @@ int proxytrack_main(char* proxyAddr, int proxyPort,
return returncode;
}
-static const char* GetHttpMessage(int statuscode) {
+static const char *GetHttpMessage(int statuscode) {
// Erreurs HTTP, selon RFC
- switch( statuscode) {
- case 100: return "Continue"; break;
- case 101: return "Switching Protocols"; break;
- case 200: return "OK"; break;
- case 201: return "Created"; break;
- case 202: return "Accepted"; break;
- case 203: return "Non-Authoritative Information"; break;
- case 204: return "No Content"; break;
- case 205: return "Reset Content"; break;
- case 206: return "Partial Content"; break;
- case 207: return "Multi-Status"; break;
- case 300: return "Multiple Choices"; break;
- case 301: return "Moved Permanently"; break;
- case 302: return "Moved Temporarily"; break;
- case 303: return "See Other"; break;
- case 304: return "Not Modified"; break;
- case 305: return "Use Proxy"; break;
- case 306: return "Undefined 306 error"; break;
- case 307: return "Temporary Redirect"; break;
- case 400: return "Bad Request"; break;
- case 401: return "Unauthorized"; break;
- case 402: return "Payment Required"; break;
- case 403: return "Forbidden"; break;
- case 404: return "Not Found"; break;
- case 405: return "Method Not Allowed"; break;
- case 406: return "Not Acceptable"; break;
- case 407: return "Proxy Authentication Required"; break;
- case 408: return "Request Time-out"; break;
- case 409: return "Conflict"; break;
- case 410: return "Gone"; break;
- case 411: return "Length Required"; break;
- case 412: return "Precondition Failed"; break;
- case 413: return "Request Entity Too Large"; break;
- case 414: return "Request-URI Too Large"; break;
- case 415: return "Unsupported Media Type"; break;
- case 416: return "Requested Range Not Satisfiable"; break;
- case 417: return "Expectation Failed"; break;
- case 500: return "Internal Server Error"; break;
- case 501: return "Not Implemented"; break;
- case 502: return "Bad Gateway"; break;
- case 503: return "Service Unavailable"; break;
- case 504: return "Gateway Time-out"; break;
- case 505: return "HTTP Version Not Supported"; break;
- default: return "Unknown HTTP Error"; break;
- }
+ switch (statuscode) {
+ case 100:
+ return "Continue";
+ break;
+ case 101:
+ return "Switching Protocols";
+ break;
+ case 200:
+ return "OK";
+ break;
+ case 201:
+ return "Created";
+ break;
+ case 202:
+ return "Accepted";
+ break;
+ case 203:
+ return "Non-Authoritative Information";
+ break;
+ case 204:
+ return "No Content";
+ break;
+ case 205:
+ return "Reset Content";
+ break;
+ case 206:
+ return "Partial Content";
+ break;
+ case 207:
+ return "Multi-Status";
+ break;
+ case 300:
+ return "Multiple Choices";
+ break;
+ case 301:
+ return "Moved Permanently";
+ break;
+ case 302:
+ return "Moved Temporarily";
+ break;
+ case 303:
+ return "See Other";
+ break;
+ case 304:
+ return "Not Modified";
+ break;
+ case 305:
+ return "Use Proxy";
+ break;
+ case 306:
+ return "Undefined 306 error";
+ break;
+ case 307:
+ return "Temporary Redirect";
+ break;
+ case 400:
+ return "Bad Request";
+ break;
+ case 401:
+ return "Unauthorized";
+ break;
+ case 402:
+ return "Payment Required";
+ break;
+ case 403:
+ return "Forbidden";
+ break;
+ case 404:
+ return "Not Found";
+ break;
+ case 405:
+ return "Method Not Allowed";
+ break;
+ case 406:
+ return "Not Acceptable";
+ break;
+ case 407:
+ return "Proxy Authentication Required";
+ break;
+ case 408:
+ return "Request Time-out";
+ break;
+ case 409:
+ return "Conflict";
+ break;
+ case 410:
+ return "Gone";
+ break;
+ case 411:
+ return "Length Required";
+ break;
+ case 412:
+ return "Precondition Failed";
+ break;
+ case 413:
+ return "Request Entity Too Large";
+ break;
+ case 414:
+ return "Request-URI Too Large";
+ break;
+ case 415:
+ return "Unsupported Media Type";
+ break;
+ case 416:
+ return "Requested Range Not Satisfiable";
+ break;
+ case 417:
+ return "Expectation Failed";
+ break;
+ case 500:
+ return "Internal Server Error";
+ break;
+ case 501:
+ return "Not Implemented";
+ break;
+ case 502:
+ return "Bad Gateway";
+ break;
+ case 503:
+ return "Service Unavailable";
+ break;
+ case 504:
+ return "Gateway Time-out";
+ break;
+ case 505:
+ return "HTTP Version Not Supported";
+ break;
+ default:
+ return "Unknown HTTP Error";
+ break;
+ }
}
#ifndef NO_WEBDAV
-static void proxytrack_add_DAV_Item(String *item, String *buff,
- const char* filename,
- size_t size,
- time_t timestamp,
- const char* mime,
- int isDir,
- int isRoot,
- int isDefault)
-{
- struct tm * timetm;
- if (timestamp == (time_t) 0 || timestamp == (time_t) -1) {
- timestamp = time(NULL);
- }
- if ((timetm = gmtime(&timestamp)) != NULL) {
- char tms[256 + 1];
- const char * name;
- strftime(tms, 256, "%a, %d %b %Y %H:%M:%S GMT", timetm); /* Sun, 18 Sep 2005 11:45:45 GMT */
-
- if (mime == NULL || *mime == 0)
- mime = "application/octet-stream";
-
- StringLength(*buff) = 0;
- escapexml(filename, buff);
-
- name = strrchr(StringBuff(*buff), '/');
- if (name != NULL)
- name++;
- if (name == NULL || *name == 0) {
- if (strcmp(mime, "text/html") == 0)
- name = "Default Document for the Folder.html";
- else
- name = "Default Document for the Folder";
- }
-
- StringRoom(*item, 1024);
- sprintf(StringBuffRW(*item),
- "<response xmlns=\"DAV:\">\r\n"
- "<href>/webdav%s%s</href>\r\n"
- "<propstat>\r\n"
- "<prop>\r\n"
- "<displayname>%s</displayname>\r\n"
- "<iscollection>%d</iscollection>\r\n"
- "<haschildren>%d</haschildren>\r\n"
- "<isfolder>%d</isfolder>\r\n"
- "<resourcetype>%s</resourcetype>\r\n"
- "<creationdate>%d-%02d-%02dT%02d:%02d:%02dZ</creationdate>\r\n"
- "<getlastmodified>%s</getlastmodified>\r\n"
- "<supportedlock></supportedlock>\r\n"
- "<lockdiscovery/>\r\n"
- "<getcontenttype>%s</getcontenttype>\r\n"
- "<getcontentlength>%d</getcontentlength>\r\n"
- "<isroot>%d</isroot>\r\n"
- "</prop>\r\n"
- "<status>HTTP/1.1 200 OK</status>\r\n"
- "</propstat>\r\n"
- "</response>\r\n",
- /* */
- ( StringBuff(*buff)[0] == '/' ) ? "" : "/", StringBuff(*buff),
- name,
- isDir ? 1 : 0,
- isDir ? 1 : 0,
- isDir ? 1 : 0,
- isDir ? "<collection/>" : "",
- timetm->tm_year + 1900, timetm->tm_mon + 1, timetm->tm_mday, timetm->tm_hour, timetm->tm_min, timetm->tm_sec,
- tms,
- isDir ? "httpd/unix-directory" : mime,
- (int)size,
- isRoot ? 1 : 0
- );
- StringLength(*item) = (int) strlen(StringBuff(*item));
- }
+static void proxytrack_add_DAV_Item(String * item, String * buff,
+ const char *filename, size_t size,
+ time_t timestamp, const char *mime,
+ int isDir, int isRoot, int isDefault) {
+ struct tm *timetm;
+
+ if (timestamp == (time_t) 0 || timestamp == (time_t) - 1) {
+ timestamp = time(NULL);
+ }
+ if ((timetm = gmtime(&timestamp)) != NULL) {
+ char tms[256 + 1];
+ const char *name;
+
+ strftime(tms, 256, "%a, %d %b %Y %H:%M:%S GMT", timetm); /* Sun, 18 Sep 2005 11:45:45 GMT */
+
+ if (mime == NULL || *mime == 0)
+ mime = "application/octet-stream";
+
+ StringLength(*buff) = 0;
+ escapexml(filename, buff);
+
+ name = strrchr(StringBuff(*buff), '/');
+ if (name != NULL)
+ name++;
+ if (name == NULL || *name == 0) {
+ if (strcmp(mime, "text/html") == 0)
+ name = "Default Document for the Folder.html";
+ else
+ name = "Default Document for the Folder";
+ }
+
+ StringRoom(*item, 1024);
+ sprintf(StringBuffRW(*item),
+ "<response xmlns=\"DAV:\">\r\n" "<href>/webdav%s%s</href>\r\n"
+ "<propstat>\r\n" "<prop>\r\n" "<displayname>%s</displayname>\r\n"
+ "<iscollection>%d</iscollection>\r\n"
+ "<haschildren>%d</haschildren>\r\n" "<isfolder>%d</isfolder>\r\n"
+ "<resourcetype>%s</resourcetype>\r\n"
+ "<creationdate>%d-%02d-%02dT%02d:%02d:%02dZ</creationdate>\r\n"
+ "<getlastmodified>%s</getlastmodified>\r\n"
+ "<supportedlock></supportedlock>\r\n" "<lockdiscovery/>\r\n"
+ "<getcontenttype>%s</getcontenttype>\r\n"
+ "<getcontentlength>%d</getcontentlength>\r\n"
+ "<isroot>%d</isroot>\r\n" "</prop>\r\n"
+ "<status>HTTP/1.1 200 OK</status>\r\n" "</propstat>\r\n"
+ "</response>\r\n",
+ /* */
+ (StringBuff(*buff)[0] == '/') ? "" : "/", StringBuff(*buff), name,
+ isDir ? 1 : 0, isDir ? 1 : 0, isDir ? 1 : 0,
+ isDir ? "<collection/>" : "", timetm->tm_year + 1900,
+ timetm->tm_mon + 1, timetm->tm_mday, timetm->tm_hour,
+ timetm->tm_min, timetm->tm_sec, tms,
+ isDir ? "httpd/unix-directory" : mime, (int) size, isRoot ? 1 : 0);
+ StringLength(*item) = (int) strlen(StringBuff(*item));
+ }
}
/* Convert a RFC822 time to time_t */
-static time_t get_time_rfc822(const char* s) {
+static time_t get_time_rfc822(const char *s) {
struct tm result;
+
/* */
- char months[]="jan feb mar apr may jun jul aug sep oct nov dec";
+ char months[] = "jan feb mar apr may jun jul aug sep oct nov dec";
char str[256];
- char* a;
- int i;
+ char *a;
+ int i;
+
/* */
- int result_mm=-1;
- int result_dd=-1;
- int result_n1=-1;
- int result_n2=-1;
- int result_n3=-1;
- int result_n4=-1;
+ int result_mm = -1;
+ int result_dd = -1;
+ int result_n1 = -1;
+ int result_n2 = -1;
+ int result_n3 = -1;
+ int result_n4 = -1;
+
/* */
if ((int) strlen(s) > 200)
- return (time_t)0;
- for(i = 0 ; s[i] != 0 ; i++) {
- if (s[i] >= 'A' && s[i] <= 'Z')
- str[i] = s[i] + ('a' - 'A');
- else
- str[i] = s[i];
- }
- str[i] = 0;
+ return (time_t) 0;
+ for(i = 0; s[i] != 0; i++) {
+ if (s[i] >= 'A' && s[i] <= 'Z')
+ str[i] = s[i] + ('a' - 'A');
+ else
+ str[i] = s[i];
+ }
+ str[i] = 0;
/* éliminer :,- */
- while( (a=strchr(str,'-')) ) *a=' ';
- while( (a=strchr(str,':')) ) *a=' ';
- while( (a=strchr(str,',')) ) *a=' ';
+ while((a = strchr(str, '-')))
+ *a = ' ';
+ while((a = strchr(str, ':')))
+ *a = ' ';
+ while((a = strchr(str, ',')))
+ *a = ' ';
/* tokeniser */
- a=str;
+ a = str;
while(*a) {
- char *first,*last;
+ char *first, *last;
char tok[256];
+
/* découper mot */
- while(*a==' ') a++; /* sauter espaces */
- first=a;
- while((*a) && (*a!=' ')) a++;
- last=a;
- tok[0]='\0';
- if (first!=last) {
- char* pos;
- strncat(tok,first,(int) (last - first));
+ while(*a == ' ')
+ a++; /* sauter espaces */
+ first = a;
+ while((*a) && (*a != ' '))
+ a++;
+ last = a;
+ tok[0] = '\0';
+ if (first != last) {
+ char *pos;
+
+ strncat(tok, first, (int) (last - first));
/* analyser */
- if ( (pos=strstr(months,tok)) ) { /* month always in letters */
- result_mm=((int) (pos - months))/4;
+ if ((pos = strstr(months, tok))) { /* month always in letters */
+ result_mm = ((int) (pos - months)) / 4;
} else {
int number;
- if (sscanf(tok,"%d",&number) == 1) { /* number token */
- if (result_dd<0) /* day always first number */
- result_dd=number;
- else if (result_n1<0)
- result_n1=number;
- else if (result_n2<0)
- result_n2=number;
- else if (result_n3<0)
- result_n3=number;
- else if (result_n4<0)
- result_n4=number;
- } /* sinon, bruit de fond(+1GMT for exampel) */
+
+ if (sscanf(tok, "%d", &number) == 1) { /* number token */
+ if (result_dd < 0) /* day always first number */
+ result_dd = number;
+ else if (result_n1 < 0)
+ result_n1 = number;
+ else if (result_n2 < 0)
+ result_n2 = number;
+ else if (result_n3 < 0)
+ result_n3 = number;
+ else if (result_n4 < 0)
+ result_n4 = number;
+ } /* sinon, bruit de fond(+1GMT for exampel) */
}
}
}
- if ((result_n1>=0) && (result_mm>=0) && (result_dd>=0) && (result_n2>=0) && (result_n3>=0) && (result_n4>=0)) {
- if (result_n4>=1000) { /* Sun Nov 6 08:49:37 1994 */
- result.tm_year=result_n4-1900;
- result.tm_hour=result_n1;
- result.tm_min=result_n2;
- result.tm_sec=max(result_n3,0);
- } else { /* Sun, 06 Nov 1994 08:49:37 GMT or Sunday, 06-Nov-94 08:49:37 GMT */
- result.tm_hour=result_n2;
- result.tm_min=result_n3;
- result.tm_sec=max(result_n4,0);
- if (result_n1<=50) /* 00 means 2000 */
- result.tm_year=result_n1+100;
- else if (result_n1<1000) /* 99 means 1999 */
- result.tm_year=result_n1;
- else /* 2000 */
- result.tm_year=result_n1-1900;
+ if ((result_n1 >= 0) && (result_mm >= 0) && (result_dd >= 0)
+ && (result_n2 >= 0) && (result_n3 >= 0) && (result_n4 >= 0)) {
+ if (result_n4 >= 1000) { /* Sun Nov 6 08:49:37 1994 */
+ result.tm_year = result_n4 - 1900;
+ result.tm_hour = result_n1;
+ result.tm_min = result_n2;
+ result.tm_sec = max(result_n3, 0);
+ } else { /* Sun, 06 Nov 1994 08:49:37 GMT or Sunday, 06-Nov-94 08:49:37 GMT */
+ result.tm_hour = result_n2;
+ result.tm_min = result_n3;
+ result.tm_sec = max(result_n4, 0);
+ if (result_n1 <= 50) /* 00 means 2000 */
+ result.tm_year = result_n1 + 100;
+ else if (result_n1 < 1000) /* 99 means 1999 */
+ result.tm_year = result_n1;
+ else /* 2000 */
+ result.tm_year = result_n1 - 1900;
}
- result.tm_isdst=0; /* assume GMT */
- result.tm_yday=-1; /* don't know */
- result.tm_wday=-1; /* don't know */
- result.tm_mon=result_mm;
- result.tm_mday=result_dd;
+ result.tm_isdst = 0; /* assume GMT */
+ result.tm_yday = -1; /* don't know */
+ result.tm_wday = -1; /* don't know */
+ result.tm_mon = result_mm;
+ result.tm_mday = result_dd;
return mktime(&result);
}
return (time_t) 0;
}
-static PT_Element proxytrack_process_DAV_Request(PT_Indexes indexes, const char * urlFull, int depth) {
- const char * file = jump_protocol_and_auth(urlFull);
- if ( (file = strchr(file, '/')) == NULL)
- return NULL;
-
- if (strncmp(file, "/webdav", 7) != 0) {
- PT_Element elt = PT_ElementNew();
- elt->statuscode = 405;
- strcpy(elt->msg, "Method Not Allowed");
- return elt;
- }
-
- /* Skip /webdav */
- file += 7;
-
- /* */
- {
- PT_Element elt = PT_ElementNew();
- int i, isDir;
- String url = STRING_EMPTY;
- String response = STRING_EMPTY;
- String item = STRING_EMPTY;
- String itemUrl = STRING_EMPTY;
- String buff = STRING_EMPTY;
- StringClear(response);
- StringClear(item);
- StringClear(itemUrl);
- StringClear(buff);
-
- /* Canonize URL */
- StringCopy(url, file + ((file[0] == '/') ? 1 : 0));
- if (StringLength(url) > 0) {
- if (StringBuff(url)[StringLength(url) - 1] == '/') {
- StringBuffRW(url)[StringLength(url) - 1] = '\0';
- StringLength(url)--;
- }
- }
-
- /* Form response */
- StringRoom(response, 1024);
- sprintf(StringBuffRW(response),
- "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
- "<multistatus xmlns=\"DAV:\">\r\n");
- StringLength(response) = (int) strlen(StringBuff(response));
- /* */
-
- /* Root */
- StringLength(item) = 0;
- proxytrack_add_DAV_Item(&item, &buff,
- StringBuff(url), /*size*/0, /*timestamp*/(time_t) 0, /*mime*/NULL, /*isDir*/1, /*isRoot*/1, /*isDefault*/0);
- StringMemcat(response, StringBuff(item), StringLength(item));
-
- /* Childrens (Depth > 0) */
- if (depth > 0) {
- time_t timestampRep = (time_t) -1;
- const char * prefix = StringBuff(url);
- unsigned int prefixLen = (unsigned int) strlen(prefix);
- char ** list = PT_Enumerate(indexes, prefix, 0);
- if (list != NULL) {
- for(isDir = 1 ; isDir >= 0 ; isDir--) {
- for(i = 0 ; list[i] != NULL ; i++) {
- const char * thisUrl = list[i];
- const char * mimeType = "application/octet-stream";
- unsigned int thisUrlLen = (unsigned int) strlen(thisUrl);
- int thisIsDir = (thisUrl[thisUrlLen - 1] == '/') ? 1 : 0;
-
- /* Item URL */
- StringRoom(itemUrl, thisUrlLen + prefixLen + sizeof("/webdav/") + 1);
- StringClear(itemUrl);
- sprintf(StringBuffRW(itemUrl), "/%s/%s", prefix, thisUrl);
- if (!thisIsDir)
- StringLength(itemUrl) = (int) strlen(StringBuff(itemUrl));
- else
- StringLength(itemUrl) = (int) strlen(StringBuff(itemUrl)) - 1;
- StringBuffRW(itemUrl)[StringLength(itemUrl)] = '\0';
-
- if (thisIsDir == isDir) {
- size_t size = 0;
- time_t timestamp = (time_t) 0;
- PT_Element file = NULL;
-
- /* Item stats */
- if (!isDir) {
- file = PT_ReadIndex(indexes, StringBuff(itemUrl) + 1, FETCH_HEADERS);
- if (file != NULL && file->statuscode == HTTP_OK ) {
- size = file->size;
- if (file->lastmodified) {
- timestamp = get_time_rfc822(file->lastmodified);
- }
- if (timestamp == (time_t) 0) {
- if (timestampRep == (time_t) -1) {
- timestampRep = 0;
- if (file->indexId != -1) {
- timestampRep = PT_Index_Timestamp(PT_GetIndex(indexes, file->indexId));
- }
- }
- timestamp = timestampRep;
- }
- if (file->contenttype) {
- mimeType = file->contenttype;
- }
- }
- }
-
- /* Add item */
- StringLength(item) = 0;
- proxytrack_add_DAV_Item(&item, &buff,
- StringBuff(itemUrl), size, timestamp, mimeType, isDir, /*isRoot*/0, /*isDefault*/(thisUrlLen == 0));
- StringMemcat(response, StringBuff(item), StringLength(item));
-
- /* Wipe element */
- if (file != NULL)
- PT_Element_Delete(&file);
- }
- }
- }
- PT_Enumerate_Delete(&list);
- } /* items != NULL */
- } /* Depth > 0 */
-
- /* End of responses */
- StringCat(response,
- "</multistatus>\r\n"
- );
-
- StringFree(item);
- StringFree(itemUrl);
- StringFree(url);
- StringFree(buff);
-
- elt->size = StringLength(response);
- elt->adr = StringAcquire(&response);
- elt->statuscode = 207; /* Multi-Status */
- strcpy(elt->charset, "utf-8");
- strcpy(elt->contenttype, "text/xml");
- strcpy(elt->msg, "Multi-Status");
- StringFree(response);
-
- fprintf(stderr, "RESPONSE:\n%s\n", elt->adr);
-
- return elt;
- }
- return NULL;
+static PT_Element proxytrack_process_DAV_Request(PT_Indexes indexes,
+ const char *urlFull,
+ int depth) {
+ const char *file = jump_protocol_and_auth(urlFull);
+
+ if ((file = strchr(file, '/')) == NULL)
+ return NULL;
+
+ if (strncmp(file, "/webdav", 7) != 0) {
+ PT_Element elt = PT_ElementNew();
+
+ elt->statuscode = 405;
+ strcpy(elt->msg, "Method Not Allowed");
+ return elt;
+ }
+
+ /* Skip /webdav */
+ file += 7;
+
+ /* */
+ {
+ PT_Element elt = PT_ElementNew();
+ int i, isDir;
+ String url = STRING_EMPTY;
+ String response = STRING_EMPTY;
+ String item = STRING_EMPTY;
+ String itemUrl = STRING_EMPTY;
+ String buff = STRING_EMPTY;
+
+ StringClear(response);
+ StringClear(item);
+ StringClear(itemUrl);
+ StringClear(buff);
+
+ /* Canonize URL */
+ StringCopy(url, file + ((file[0] == '/') ? 1 : 0));
+ if (StringLength(url) > 0) {
+ if (StringBuff(url)[StringLength(url) - 1] == '/') {
+ StringBuffRW(url)[StringLength(url) - 1] = '\0';
+ StringLength(url)--;
+ }
+ }
+
+ /* Form response */
+ StringRoom(response, 1024);
+ sprintf(StringBuffRW(response),
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
+ "<multistatus xmlns=\"DAV:\">\r\n");
+ StringLength(response) = (int) strlen(StringBuff(response));
+ /* */
+
+ /* Root */
+ StringLength(item) = 0;
+ proxytrack_add_DAV_Item(&item, &buff, StringBuff(url), /*size */ 0,
+ /*timestamp */ (time_t) 0, /*mime */ NULL, /*isDir */ 1, /*isRoot */ 1,
+/*isDefault */ 0);
+ StringMemcat(response, StringBuff(item), StringLength(item));
+
+ /* Childrens (Depth > 0) */
+ if (depth > 0) {
+ time_t timestampRep = (time_t) - 1;
+ const char *prefix = StringBuff(url);
+ unsigned int prefixLen = (unsigned int) strlen(prefix);
+ char **list = PT_Enumerate(indexes, prefix, 0);
+
+ if (list != NULL) {
+ for(isDir = 1; isDir >= 0; isDir--) {
+ for(i = 0; list[i] != NULL; i++) {
+ const char *thisUrl = list[i];
+ const char *mimeType = "application/octet-stream";
+ unsigned int thisUrlLen = (unsigned int) strlen(thisUrl);
+ int thisIsDir = (thisUrl[thisUrlLen - 1] == '/') ? 1 : 0;
+
+ /* Item URL */
+ StringRoom(itemUrl,
+ thisUrlLen + prefixLen + sizeof("/webdav/") + 1);
+ StringClear(itemUrl);
+ sprintf(StringBuffRW(itemUrl), "/%s/%s", prefix, thisUrl);
+ if (!thisIsDir)
+ StringLength(itemUrl) = (int) strlen(StringBuff(itemUrl));
+ else
+ StringLength(itemUrl) = (int) strlen(StringBuff(itemUrl)) - 1;
+ StringBuffRW(itemUrl)[StringLength(itemUrl)] = '\0';
+
+ if (thisIsDir == isDir) {
+ size_t size = 0;
+ time_t timestamp = (time_t) 0;
+ PT_Element file = NULL;
+
+ /* Item stats */
+ if (!isDir) {
+ file =
+ PT_ReadIndex(indexes, StringBuff(itemUrl) + 1, FETCH_HEADERS);
+ if (file != NULL && file->statuscode == HTTP_OK) {
+ size = file->size;
+ if (file->lastmodified) {
+ timestamp = get_time_rfc822(file->lastmodified);
+ }
+ if (timestamp == (time_t) 0) {
+ if (timestampRep == (time_t) - 1) {
+ timestampRep = 0;
+ if (file->indexId != -1) {
+ timestampRep =
+ PT_Index_Timestamp(PT_GetIndex
+ (indexes, file->indexId));
+ }
+ }
+ timestamp = timestampRep;
+ }
+ if (file->contenttype) {
+ mimeType = file->contenttype;
+ }
+ }
+ }
+
+ /* Add item */
+ StringLength(item) = 0;
+ proxytrack_add_DAV_Item(&item, &buff, StringBuff(itemUrl), size,
+ timestamp, mimeType, isDir, /*isRoot */ 0,
+ /*isDefault */ (thisUrlLen == 0));
+ StringMemcat(response, StringBuff(item), StringLength(item));
+
+ /* Wipe element */
+ if (file != NULL)
+ PT_Element_Delete(&file);
+ }
+ }
+ }
+ PT_Enumerate_Delete(&list);
+ } /* items != NULL */
+ }
+
+ /* Depth > 0 */
+ /* End of responses */
+ StringCat(response, "</multistatus>\r\n");
+
+ StringFree(item);
+ StringFree(itemUrl);
+ StringFree(url);
+ StringFree(buff);
+
+ elt->size = StringLength(response);
+ elt->adr = StringAcquire(&response);
+ elt->statuscode = 207; /* Multi-Status */
+ strcpy(elt->charset, "utf-8");
+ strcpy(elt->contenttype, "text/xml");
+ strcpy(elt->msg, "Multi-Status");
+ StringFree(response);
+
+ fprintf(stderr, "RESPONSE:\n%s\n", elt->adr);
+
+ return elt;
+ }
+ return NULL;
}
#endif
-static PT_Element proxytrack_process_HTTP_List(PT_Indexes indexes, const char * url) {
- char ** list = PT_Enumerate(indexes, url, 0);
- if (list != NULL) {
- PT_Element elt = PT_ElementNew();
- int i, isDir;
- String html = STRING_EMPTY;
- StringClear(html);
- StringCat(html,
- "<html>"
- PROXYTRACK_COMMENT_HEADER
- DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES
- "<head>\r\n"
- "<title>ProxyTrack " PROXYTRACK_VERSION " Catalog</title>"
- "</head>\r\n"
- "<body>\r\n"
- "<h3>Directory index:</h3><br />"
- "<br />"
- "<hr>"
- "<tt>[DIR] <a href=\"..\">..</a></tt><br />"
- );
- for(isDir = 1 ; isDir >= 0 ; isDir--) {
- for(i = 0 ; list[i] != NULL ; i++) {
- char * thisUrl = list[i];
- unsigned int thisUrlLen = (unsigned int) strlen(thisUrl);
- int thisIsDir = (thisUrl[thisUrlLen - 1] == '/') ? 1 : 0;
- if (thisIsDir == isDir) {
- if (isDir)
- StringCat(html, "<tt>[DIR] ");
- else
- StringCat(html, "<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
- StringCat(html, "<a href=\"");
- if (isDir) {
- StringCat(html, "http://proxytrack/");
- }
- StringCat(html, url);
- StringCat(html, list[i]);
- StringCat(html, "\">");
- StringCat(html, list[i]);
- StringCat(html, "</a></tt><br />");
- }
- }
- }
- StringCat(html,
- "</body>"
- "</html>");
- PT_Enumerate_Delete(&list);
- elt->size = StringLength(html);
- elt->adr = StringAcquire(&html);
- elt->statuscode = HTTP_OK;
- strcpy(elt->charset, "iso-8859-1");
- strcpy(elt->contenttype, "text/html");
- strcpy(elt->msg, "OK");
- StringFree(html);
- return elt;
- }
- return NULL;
+static PT_Element proxytrack_process_HTTP_List(PT_Indexes indexes,
+ const char *url) {
+ char **list = PT_Enumerate(indexes, url, 0);
+
+ if (list != NULL) {
+ PT_Element elt = PT_ElementNew();
+ int i, isDir;
+ String html = STRING_EMPTY;
+
+ StringClear(html);
+ StringCat(html,
+ "<html>" PROXYTRACK_COMMENT_HEADER
+ DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES "<head>\r\n"
+ "<title>ProxyTrack " PROXYTRACK_VERSION " Catalog</title>"
+ "</head>\r\n" "<body>\r\n" "<h3>Directory index:</h3><br />"
+ "<br />" "<hr>" "<tt>[DIR] <a href=\"..\">..</a></tt><br />");
+ for(isDir = 1; isDir >= 0; isDir--) {
+ for(i = 0; list[i] != NULL; i++) {
+ char *thisUrl = list[i];
+ unsigned int thisUrlLen = (unsigned int) strlen(thisUrl);
+ int thisIsDir = (thisUrl[thisUrlLen - 1] == '/') ? 1 : 0;
+
+ if (thisIsDir == isDir) {
+ if (isDir)
+ StringCat(html, "<tt>[DIR] ");
+ else
+ StringCat(html, "<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
+ StringCat(html, "<a href=\"");
+ if (isDir) {
+ StringCat(html, "http://proxytrack/");
+ }
+ StringCat(html, url);
+ StringCat(html, list[i]);
+ StringCat(html, "\">");
+ StringCat(html, list[i]);
+ StringCat(html, "</a></tt><br />");
+ }
+ }
+ }
+ StringCat(html, "</body>" "</html>");
+ PT_Enumerate_Delete(&list);
+ elt->size = StringLength(html);
+ elt->adr = StringAcquire(&html);
+ elt->statuscode = HTTP_OK;
+ strcpy(elt->charset, "iso-8859-1");
+ strcpy(elt->contenttype, "text/html");
+ strcpy(elt->msg, "OK");
+ StringFree(html);
+ return elt;
+ }
+ return NULL;
}
static void proxytrack_process_HTTP(PT_Indexes indexes, T_SOC soc_c) {
- int timeout=30;
- int buffer_size = 32768;
- char * buffer = (char*)malloc(buffer_size);
- int line1Size = 1024;
- char * line1 = (char*)malloc(line1Size);
- int lineSize = 8192;
- char * line = (char*)malloc(lineSize);
- int length = 0;
- int keepAlive = 1;
-
- String url = STRING_EMPTY;
- String urlRedirect = STRING_EMPTY;
- String headers = STRING_EMPTY;
- String output = STRING_EMPTY;
- String host = STRING_EMPTY;
- String localhost = STRING_EMPTY;
+ int timeout = 30;
+ int buffer_size = 32768;
+ char *buffer = (char *) malloc(buffer_size);
+ int line1Size = 1024;
+ char *line1 = (char *) malloc(line1Size);
+ int lineSize = 8192;
+ char *line = (char *) malloc(lineSize);
+ int length = 0;
+ int keepAlive = 1;
+
+ String url = STRING_EMPTY;
+ String urlRedirect = STRING_EMPTY;
+ String headers = STRING_EMPTY;
+ String output = STRING_EMPTY;
+ String host = STRING_EMPTY;
+ String localhost = STRING_EMPTY;
+
#ifndef NO_WEBDAV
- String davHeaders = STRING_EMPTY;
- String davRequest = STRING_EMPTY;
+ String davHeaders = STRING_EMPTY;
+ String davRequest = STRING_EMPTY;
#endif
- StringRoom(localhost, 256);
- if (gethostname(StringBuffRW(localhost), (int) StringCapacity(localhost) - 1) == 0) {
- StringLength(localhost) = (int) strlen(StringBuff(localhost));
- } else {
- StringCopy(localhost, "localhost");
- }
+ StringRoom(localhost, 256);
+ if (gethostname(StringBuffRW(localhost), (int) StringCapacity(localhost) - 1)
+ == 0) {
+ StringLength(localhost) = (int) strlen(StringBuff(localhost));
+ } else {
+ StringCopy(localhost, "localhost");
+ }
#ifdef _DEBUG
- Sleep(1000);
+ Sleep(1000);
#endif
- if (buffer == NULL || line == NULL || line1 == NULL) {
- proxytrack_print_log(CRITICAL, "proxytrack_process_HTTP:memory exhausted");
+ if (buffer == NULL || line == NULL || line1 == NULL) {
+ proxytrack_print_log(CRITICAL, "proxytrack_process_HTTP:memory exhausted");
#ifdef _WIN32
- closesocket(soc_c);
+ closesocket(soc_c);
#else
- close(soc_c);
+ close(soc_c);
#endif
- return ;
- }
-
- do {
- const char* msgError = NULL;
- int msgCode = 0;
- PT_Element element = NULL;
- char* command;
- char* proto;
- char* surl;
- int directHit = 0;
- int headRequest = 0;
- int listRequest = 0;
+ return;
+ }
+
+ do {
+ const char *msgError = NULL;
+ int msgCode = 0;
+ PT_Element element = NULL;
+ char *command;
+ char *proto;
+ char *surl;
+ int directHit = 0;
+ int headRequest = 0;
+ int listRequest = 0;
+
#ifndef NO_WEBDAV
- int davDepth = 0;
+ int davDepth = 0;
#endif
- /* Clear context */
- line[0] = line1[0] = '\0';
- buffer[0] = '\0';
- command = line1;
- StringClear(url);
- StringClear(urlRedirect);
- StringClear(headers);
- StringClear(output);
- StringClear(host);
+ /* Clear context */
+ line[0] = line1[0] = '\0';
+ buffer[0] = '\0';
+ command = line1;
+ StringClear(url);
+ StringClear(urlRedirect);
+ StringClear(headers);
+ StringClear(output);
+ StringClear(host);
#ifndef NO_WEBDAV
- StringClear(davHeaders);
- StringClear(davRequest);
+ StringClear(davHeaders);
+ StringClear(davRequest);
#endif
- /* line1: "GET http://www.example.com/ HTTP/1.0" */
- if (linputsoc_t(soc_c, line1, line1Size - 2, timeout) > 0
- && ( surl = strchr(line1, ' ') )
- && !(*surl = '\0')
- && ++surl
- && (proto = strchr(surl, ' ')) && !(*proto = '\0') && ++proto)
- {
- /* Flush headers */
- while(linputsoc_t(soc_c, line, lineSize - 2, timeout) > 0
- && line[0] != 0)
- {
- int p;
- if ((p = strfield(line, "Content-length:"))!=0) {
- if (sscanf(line+p, "%d", &length) != 1) {
- msgCode = 500;
- msgError = "Bad HTTP Content-Length Field";
- keepAlive = 0;
- length = 0;
- }
- } else if (strcasecmp(line, "Connection: close") == 0) {
- keepAlive = 0;
- } else if (strcasecmp(line, "Connection: keep-alive") == 0) {
- keepAlive = 1;
- } else if ((p = strfield(line, "Host:"))) {
- char* chost = line + p;
- if (*chost == ' ')
- chost++;
- StringCopy(host, chost);
- }
+ /* line1: "GET http://www.example.com/ HTTP/1.0" */
+ if (linputsoc_t(soc_c, line1, line1Size - 2, timeout) > 0
+ && (surl = strchr(line1, ' '))
+ && !(*surl = '\0')
+ && ++surl && (proto = strchr(surl, ' ')) && !(*proto = '\0') && ++proto) {
+ /* Flush headers */
+ while(linputsoc_t(soc_c, line, lineSize - 2, timeout) > 0 && line[0] != 0) {
+ int p;
+
+ if ((p = strfield(line, "Content-length:")) != 0) {
+ if (sscanf(line + p, "%d", &length) != 1) {
+ msgCode = 500;
+ msgError = "Bad HTTP Content-Length Field";
+ keepAlive = 0;
+ length = 0;
+ }
+ } else if (strcasecmp(line, "Connection: close") == 0) {
+ keepAlive = 0;
+ } else if (strcasecmp(line, "Connection: keep-alive") == 0) {
+ keepAlive = 1;
+ } else if ((p = strfield(line, "Host:"))) {
+ char *chost = line + p;
+
+ if (*chost == ' ')
+ chost++;
+ StringCopy(host, chost);
+ }
#ifndef NO_WEBDAV
- else if ((p = strfield(line, "Depth: "))) {
- char* depth = line + p;
- if (sscanf(depth, "%d", &davDepth) != 1) {
- davDepth = 0;
- }
- }
+ else if ((p = strfield(line, "Depth: "))) {
+ char *depth = line + p;
+
+ if (sscanf(depth, "%d", &davDepth) != 1) {
+ davDepth = 0;
+ }
+ }
#endif
- }
+ }
- /* Flush body */
+ /* Flush body */
#ifndef NO_WEBDAV
- if (length > 0) {
- if (length < 32768) {
- StringRoom(davRequest, length + 1);
- if (recv(soc_c, StringBuffRW(davRequest), length, 0) == length) {
- StringBuffRW(davRequest)[length] = 0;
- } else {
- msgCode = 500;
- msgError = "Posted Data Read Error";
- keepAlive = 0;
- }
- } else {
- msgCode = 500;
- msgError = "Posted Data Too Large";
- keepAlive = 0;
- }
- }
+ if (length > 0) {
+ if (length < 32768) {
+ StringRoom(davRequest, length + 1);
+ if (recv(soc_c, StringBuffRW(davRequest), length, 0) == length) {
+ StringBuffRW(davRequest)[length] = 0;
+ } else {
+ msgCode = 500;
+ msgError = "Posted Data Read Error";
+ keepAlive = 0;
+ }
+ } else {
+ msgCode = 500;
+ msgError = "Posted Data Too Large";
+ keepAlive = 0;
+ }
+ }
#endif
- /* Switch protocol ID */
- if (strcasecmp(command, "post") == 0) {
+ /* Switch protocol ID */
+ if (strcasecmp(command, "post") == 0) {
#ifndef NO_WEBDAV
- msgCode = 404;
+ msgCode = 404;
#else
- msgCode = 501;
- keepAlive = 0;
+ msgCode = 501;
+ keepAlive = 0;
#endif
- msgError = "Proxy Error (POST Request Forbidden)";
- }
- else if (strcasecmp(command, "get") == 0) {
- headRequest = 0;
- }
- else if (strcasecmp(command, "head") == 0) {
- headRequest = 1;
- }
+ msgError = "Proxy Error (POST Request Forbidden)";
+ } else if (strcasecmp(command, "get") == 0) {
+ headRequest = 0;
+ } else if (strcasecmp(command, "head") == 0) {
+ headRequest = 1;
+ }
#ifndef NO_WEBDAV
- else if (strcasecmp(command, "options") == 0) {
- const char * options = "GET, HEAD, OPTIONS, POST, PROPFIND, TRACE"
- ", MKCOL, DELETE, PUT"; /* Not supported */
- msgCode = HTTP_OK;
- StringRoom(headers, 8192);
- sprintf(StringBuffRW(headers),
- "HTTP/1.1 %d %s\r\n"
- "DAV: 1, 2\r\n"
- "MS-Author-Via: DAV\r\n"
- "Cache-Control: private\r\n"
- "Allow: %s\r\n",
- msgCode, GetHttpMessage(msgCode), options);
- StringLength(headers) = (int) strlen(StringBuff(headers));
- }
- else if (strcasecmp(command, "propfind") == 0) {
- if (davDepth > 1) {
- msgCode = 403;
- msgError = "DAV Depth Limit Forbidden";
- } else {
- fprintf(stderr, "DEBUG: DAV-DATA=<%s>\n", StringBuff(davRequest));
- listRequest = 2; /* propfind */
- }
- }
- else if (strcasecmp(command, "mkcol") == 0
- || strcasecmp(command, "delete") == 0
- || strcasecmp(command, "put") == 0
- || strcasecmp(command, "proppatch") == 0
- || strcasecmp(command, "lock") == 0
- || strcasecmp(command, "unlock") == 0
- || strcasecmp(command, "copy") == 0
- || strcasecmp(command, "trace") == 0)
- {
- msgCode = 403;
- msgError = "Method Forbidden";
- }
+ else if (strcasecmp(command, "options") == 0) {
+ const char *options = "GET, HEAD, OPTIONS, POST, PROPFIND, TRACE" ", MKCOL, DELETE, PUT"; /* Not supported */
+
+ msgCode = HTTP_OK;
+ StringRoom(headers, 8192);
+ sprintf(StringBuffRW(headers),
+ "HTTP/1.1 %d %s\r\n" "DAV: 1, 2\r\n" "MS-Author-Via: DAV\r\n"
+ "Cache-Control: private\r\n" "Allow: %s\r\n", msgCode,
+ GetHttpMessage(msgCode), options);
+ StringLength(headers) = (int) strlen(StringBuff(headers));
+ } else if (strcasecmp(command, "propfind") == 0) {
+ if (davDepth > 1) {
+ msgCode = 403;
+ msgError = "DAV Depth Limit Forbidden";
+ } else {
+ fprintf(stderr, "DEBUG: DAV-DATA=<%s>\n", StringBuff(davRequest));
+ listRequest = 2; /* propfind */
+ }
+ } else if (strcasecmp(command, "mkcol") == 0
+ || strcasecmp(command, "delete") == 0
+ || strcasecmp(command, "put") == 0
+ || strcasecmp(command, "proppatch") == 0
+ || strcasecmp(command, "lock") == 0
+ || strcasecmp(command, "unlock") == 0
+ || strcasecmp(command, "copy") == 0
+ || strcasecmp(command, "trace") == 0) {
+ msgCode = 403;
+ msgError = "Method Forbidden";
+ }
#endif
- else {
- msgCode = 501;
- msgError = "Proxy Error (Unsupported or Unknown HTTP Command Request)";
- keepAlive = 0;
- }
- if (strcasecmp(proto, "http/1.1") == 0) {
- keepAlive = 1;
- } else if (strcasecmp(proto, "http/1.0") == 0) {
- keepAlive = 0;
- } else {
- msgCode = 505;
- msgError = "Proxy Error (Unknown HTTP Version)";
- keepAlive = 0;
- }
-
- /* Post-process request */
- if (link_has_authority(surl)) {
- if (strncasecmp(surl, "http://proxytrack/", sizeof("http://proxytrack/") - 1) == 0) {
- directHit = 1; /* Another direct hit hack */
- }
- StringCopy(url, surl);
- } else {
- if (StringLength(host) > 0) {
- /* Direct hit */
- if (
+ else {
+ msgCode = 501;
+ msgError = "Proxy Error (Unsupported or Unknown HTTP Command Request)";
+ keepAlive = 0;
+ }
+ if (strcasecmp(proto, "http/1.1") == 0) {
+ keepAlive = 1;
+ } else if (strcasecmp(proto, "http/1.0") == 0) {
+ keepAlive = 0;
+ } else {
+ msgCode = 505;
+ msgError = "Proxy Error (Unknown HTTP Version)";
+ keepAlive = 0;
+ }
+
+ /* Post-process request */
+ if (link_has_authority(surl)) {
+ if (strncasecmp
+ (surl, "http://proxytrack/",
+ sizeof("http://proxytrack/") - 1) == 0) {
+ directHit = 1; /* Another direct hit hack */
+ }
+ StringCopy(url, surl);
+ } else {
+ if (StringLength(host) > 0) {
+ /* Direct hit */
+ if (
#ifndef NO_WEBDAV
- listRequest != 2
- &&
+ listRequest != 2 &&
#endif
- strncasecmp(StringBuff(host), StringBuff(localhost), StringLength(localhost)) == 0
- &&
- (StringBuff(host)[StringLength(localhost)] == '\0'
- || StringBuff(host)[StringLength(localhost)] == ':')
- && surl[0] == '/'
- )
- {
- const char * toHit = surl + 1;
- if (strncmp(toHit, "webdav/", 7) == 0) {
- toHit += 7;
- }
- /* Direct hit */
- directHit = 1;
- StringCopy(url, "");
- if (!link_has_authority(toHit))
- StringCat(url, "http://");
- StringCat(url, toHit);
- } else if (strncasecmp(surl, "/proxytrack/", sizeof("/proxytrack/") - 1) == 0) {
- const char * toHit = surl + sizeof("/proxytrack/") - 1;
- /* Direct hit */
- directHit = 1;
- StringCopy(url, "");
- if (!link_has_authority(toHit))
- StringCat(url, "http://");
- StringCat(url, toHit);
- } else {
- /* Transparent proxy */
- StringCopy(url, "http://");
- StringCat(url, StringBuff(host));
- StringCat(url, surl);
- }
- } else {
- msgCode = 500;
- msgError = "Transparent Proxy Error ('Host' HTTP Request Header Field Missing)";
- keepAlive = 0;
- }
- }
-
- /* Response */
- if (msgCode == 0) {
- if (listRequest == 1) {
- element = proxytrack_process_HTTP_List(indexes, StringBuff(url));
- }
+ strncasecmp(StringBuff(host), StringBuff(localhost),
+ StringLength(localhost)) == 0
+ && (StringBuff(host)[StringLength(localhost)] == '\0'
+ || StringBuff(host)[StringLength(localhost)] == ':')
+ && surl[0] == '/') {
+ const char *toHit = surl + 1;
+
+ if (strncmp(toHit, "webdav/", 7) == 0) {
+ toHit += 7;
+ }
+ /* Direct hit */
+ directHit = 1;
+ StringCopy(url, "");
+ if (!link_has_authority(toHit))
+ StringCat(url, "http://");
+ StringCat(url, toHit);
+ } else
+ if (strncasecmp(surl, "/proxytrack/", sizeof("/proxytrack/") - 1) ==
+ 0) {
+ const char *toHit = surl + sizeof("/proxytrack/") - 1;
+
+ /* Direct hit */
+ directHit = 1;
+ StringCopy(url, "");
+ if (!link_has_authority(toHit))
+ StringCat(url, "http://");
+ StringCat(url, toHit);
+ } else {
+ /* Transparent proxy */
+ StringCopy(url, "http://");
+ StringCat(url, StringBuff(host));
+ StringCat(url, surl);
+ }
+ } else {
+ msgCode = 500;
+ msgError =
+ "Transparent Proxy Error ('Host' HTTP Request Header Field Missing)";
+ keepAlive = 0;
+ }
+ }
+
+ /* Response */
+ if (msgCode == 0) {
+ if (listRequest == 1) {
+ element = proxytrack_process_HTTP_List(indexes, StringBuff(url));
+ }
#ifndef NO_WEBDAV
- else if (listRequest == 2) {
- if ((element = proxytrack_process_DAV_Request(indexes, StringBuff(url), davDepth)) != NULL) {
- msgCode = element->statuscode;
- StringRoom(davHeaders, 1024);
- sprintf(StringBuffRW(davHeaders),
- "DAV: 1, 2\r\n"
- "MS-Author-Via: DAV\r\n"
- "Cache-Control: private\r\n");
- StringLength(davHeaders) = (int) strlen(StringBuff(davHeaders));
- }
- }
+ else if (listRequest == 2) {
+ if ((element =
+ proxytrack_process_DAV_Request(indexes, StringBuff(url),
+ davDepth)) != NULL) {
+ msgCode = element->statuscode;
+ StringRoom(davHeaders, 1024);
+ sprintf(StringBuffRW(davHeaders),
+ "DAV: 1, 2\r\n" "MS-Author-Via: DAV\r\n"
+ "Cache-Control: private\r\n");
+ StringLength(davHeaders) = (int) strlen(StringBuff(davHeaders));
+ }
+ }
#endif
- else {
- element = PT_ReadIndex(indexes, StringBuff(url), FETCH_BODY);
- }
- if (element == NULL
+ else {
+ element = PT_ReadIndex(indexes, StringBuff(url), FETCH_BODY);
+ }
+ if (element == NULL
#ifndef NO_WEBDAV
- && listRequest == 2
+ && listRequest == 2
#endif
- && StringLength(url) > 0
- && StringBuff(url)[StringLength(url) - 1] == '/'
- )
- {
- element = PT_Index_HTML_BuildRootInfo(indexes);
- if (element != NULL) {
- element->statuscode = 404; /* HTML page, but in error */
- }
- }
- if (element != NULL) {
- msgCode = element->statuscode;
- StringRoom(headers, 8192);
- sprintf(StringBuffRW(headers),
- "HTTP/1.1 %d %s\r\n"
+ && StringLength(url) > 0
+ && StringBuff(url)[StringLength(url) - 1] == '/') {
+ element = PT_Index_HTML_BuildRootInfo(indexes);
+ if (element != NULL) {
+ element->statuscode = 404; /* HTML page, but in error */
+ }
+ }
+ if (element != NULL) {
+ msgCode = element->statuscode;
+ StringRoom(headers, 8192);
+ sprintf(StringBuffRW(headers), "HTTP/1.1 %d %s\r\n"
#ifndef NO_WEBDAV
- "%s"
+ "%s"
#endif
- "Content-Type: %s%s%s%s\r\n"
- "%s%s%s"
- "%s%s%s"
- "%s%s%s",
- /* */
- msgCode,
- element->msg,
+ "Content-Type: %s%s%s%s\r\n" "%s%s%s" "%s%s%s" "%s%s%s",
+ /* */
+ msgCode, element->msg,
#ifndef NO_WEBDAV
- /* DAV */
- StringBuff(davHeaders),
+ /* DAV */
+ StringBuff(davHeaders),
#endif
- /* Content-type: foo; [ charset=bar ] */
- element->contenttype,
- ( ( element->charset[0]) ? "; charset=\"" : ""),
- element->charset,
- ( ( element->charset[0]) ? "\"" : ""),
- /* location */
- ( ( element->location != NULL && element->location[0]) ? "Location: " : ""),
- ( ( element->location != NULL && element->location[0]) ? element->location : ""),
- ( ( element->location != NULL && element->location[0]) ? "\r\n" : ""),
- /* last-modified */
- ( ( element->lastmodified[0]) ? "Last-Modified: " : ""),
- ( ( element->lastmodified[0]) ? element->lastmodified : ""),
- ( ( element->lastmodified[0]) ? "\r\n" : ""),
- /* etag */
- ( ( element->etag[0]) ? "ETag: " : ""),
- ( ( element->etag[0]) ? element->etag : ""),
- ( ( element->etag[0]) ? "\r\n" : "")
- );
- StringLength(headers) = (int) strlen(StringBuff(headers));
- } else {
- /* No query string, no ending / : check the the <url>/ page */
- if (StringLength(url) > 0 && StringBuff(url)[StringLength(url) - 1] != '/' && strchr(StringBuff(url), '?') == NULL) {
- StringCopy(urlRedirect, StringBuff(url));
- StringCat(urlRedirect, "/");
- if (PT_LookupIndex(indexes, StringBuff(urlRedirect))) {
- msgCode = 301; /* Moved Permanently */
- StringRoom(headers, 8192);
- sprintf(StringBuffRW(headers),
- "HTTP/1.1 %d %s\r\n"
- "Content-Type: text/html\r\n"
- "Location: %s\r\n",
- /* */
- msgCode,
- GetHttpMessage(msgCode),
- StringBuff(urlRedirect)
- );
- StringLength(headers) = (int) strlen(StringBuff(headers));
- /* */
- StringRoom(output, 1024 + sizeof(PROXYTRACK_COMMENT_HEADER) + sizeof(DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES));
- sprintf(StringBuffRW(output),
- "<html>"
- PROXYTRACK_COMMENT_HEADER
- DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES
- "<head>"
- "<title>ProxyTrack - Page has moved</title>"
- "</head>\r\n"
- "<body>"
- "<h3>The correct location is:</h3><br />"
- "<b><a href=\"%s\">%s</a></b><br />"
- "<br />"
- "<br />\r\n"
- "<i>Generated by ProxyTrack " PROXYTRACK_VERSION ", (C) Xavier Roche and other contributors</i>"
- "\r\n"
- "</body>"
- "</header>",
- StringBuff(urlRedirect),
- StringBuff(urlRedirect));
- StringLength(output) = (int) strlen(StringBuff(output));
- }
- }
- if (msgCode == 0) {
- msgCode = 404;
- msgError = "Not Found in this cache";
- }
- }
- }
- } else {
- msgCode = 500;
- msgError = "Server Error";
- keepAlive = 0;
- }
- if (StringLength(headers) == 0) {
- if (msgCode == 0) {
- msgCode = 500;
- msgError = "Internal Proxy Error";
- } else if (msgError == NULL) {
- msgError = GetHttpMessage(msgCode);
- }
- StringRoom(headers, 256);
- sprintf(StringBuffRW(headers),
- "HTTP/1.1 %d %s\r\n"
- "Content-type: text/html\r\n",
- msgCode,
- msgError);
- StringLength(headers) = (int) strlen(StringBuff(headers));
- StringRoom(output, 1024 + sizeof(PROXYTRACK_COMMENT_HEADER) + sizeof(DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES));
- sprintf(StringBuffRW(output),
- "<html>"
- PROXYTRACK_COMMENT_HEADER
- DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES
- "<head>"
- "<title>ProxyTrack - HTTP Proxy Error %d</title>"
- "</head>\r\n"
- "<body>"
- "<h3>A proxy error has occured while processing the request.</h3><br />"
- "<b>Error HTTP %d: <i>%s</i></b><br />"
- "<br />"
- "<br />\r\n"
- "<i>Generated by ProxyTrack " PROXYTRACK_VERSION ", (C) Xavier Roche and other contributors</i>"
- "\r\n"
- "</body>"
- "</html>",
- msgCode,
- msgCode,
- msgError);
- StringLength(output) = (int) strlen(StringBuff(output));
- }
- {
- char tmp[20 + 1]; /* 2^64 = 18446744073709551616 */
- size_t dataSize = 0;
- if (!headRequest) {
- dataSize = StringLength(output);
- if (dataSize == 0 && element != NULL) {
- dataSize = element->size;
- }
- }
- sprintf(tmp, "%d", (int) dataSize);
- StringCat(headers, "Content-length: ");
- StringCat(headers, tmp);
- StringCat(headers, "\r\n");
- }
- if (keepAlive) {
- StringCat(headers,
- "Connection: Keep-Alive\r\n"
- "Proxy-Connection: Keep-Alive\r\n");
- } else {
- StringCat(headers,
- "Connection: Close\r\n"
- "Proxy-Connection: Close\r\n");
- }
- if (msgCode != 500)
- StringCat(headers, "X-Cache: HIT from ");
- else
- StringCat(headers, "X-Cache: MISS from ");
- StringCat(headers, StringBuff(localhost));
- StringCat(headers, "\r\n");
-
- /* Logging */
- {
- const char * contentType = "text/html";
- size_t size = StringLength(output) ? StringLength(output) : ( element ? element->size : 0 );
- /* */
- String ip = STRING_EMPTY;
- SOCaddr serverClient;
- SOClen lenServerClient = (int) sizeof(serverClient);
- memset(&serverClient, 0, sizeof(serverClient));
- if (getsockname(soc_c, (struct sockaddr*) &serverClient, &lenServerClient) == 0) {
- ip = getip(&serverClient, lenServerClient);
- } else {
- StringCopy(ip, "unknown");
- }
- if (element != NULL && element->contenttype[0] != '\0') {
- contentType = element->contenttype;
- }
- proxytrack_print_log(LOG, "HTTP %s %d %d %s %s %s", StringBuff(ip), msgCode, (int)size, command, StringBuff(url), contentType);
- StringFree(ip);
- }
-
- /* Send reply */
- StringCat(headers, "Server: ProxyTrack " PROXYTRACK_VERSION " (HTTrack " HTTRACK_VERSIONID ")\r\n");
- StringCat(headers, "\r\n"); /* Headers separator */
- if (send(soc_c, StringBuff(headers), (int)StringLength(headers), 0) != StringLength(headers)
- || ( !headRequest && StringLength(output) > 0 && send(soc_c, StringBuff(output), (int)StringLength(output), 0) != StringLength(output))
- || ( !headRequest && StringLength(output) == 0 && element != NULL && element->adr != NULL && send(soc_c, element->adr, (int)element->size, 0) != element->size)
- )
- {
- keepAlive = 0; /* Error, abort connection */
- }
- PT_Element_Delete(&element);
-
- /* Shutdown (FIN) and wait until confirmed */
- if (!keepAlive) {
- char c;
+ /* Content-type: foo; [ charset=bar ] */
+ element->contenttype,
+ ((element->charset[0]) ? "; charset=\"" : ""),
+ element->charset, ((element->charset[0]) ? "\"" : ""),
+ /* location */
+ ((element->location != NULL
+ && element->location[0]) ? "Location: " : ""),
+ ((element->location != NULL
+ && element->location[0]) ? element->location : ""),
+ ((element->location != NULL
+ && element->location[0]) ? "\r\n" : ""),
+ /* last-modified */
+ ((element->lastmodified[0]) ? "Last-Modified: " : ""),
+ ((element->lastmodified[0]) ? element->lastmodified : ""),
+ ((element->lastmodified[0]) ? "\r\n" : ""),
+ /* etag */
+ ((element->etag[0]) ? "ETag: " : ""),
+ ((element->etag[0]) ? element->etag : ""),
+ ((element->etag[0]) ? "\r\n" : "")
+ );
+ StringLength(headers) = (int) strlen(StringBuff(headers));
+ } else {
+ /* No query string, no ending / : check the the <url>/ page */
+ if (StringLength(url) > 0
+ && StringBuff(url)[StringLength(url) - 1] != '/'
+ && strchr(StringBuff(url), '?') == NULL) {
+ StringCopy(urlRedirect, StringBuff(url));
+ StringCat(urlRedirect, "/");
+ if (PT_LookupIndex(indexes, StringBuff(urlRedirect))) {
+ msgCode = 301; /* Moved Permanently */
+ StringRoom(headers, 8192);
+ sprintf(StringBuffRW(headers),
+ "HTTP/1.1 %d %s\r\n" "Content-Type: text/html\r\n"
+ "Location: %s\r\n",
+ /* */
+ msgCode, GetHttpMessage(msgCode), StringBuff(urlRedirect)
+ );
+ StringLength(headers) = (int) strlen(StringBuff(headers));
+ /* */
+ StringRoom(output,
+ 1024 + sizeof(PROXYTRACK_COMMENT_HEADER) +
+ sizeof(DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES));
+ sprintf(StringBuffRW(output),
+ "<html>" PROXYTRACK_COMMENT_HEADER
+ DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES "<head>"
+ "<title>ProxyTrack - Page has moved</title>" "</head>\r\n"
+ "<body>" "<h3>The correct location is:</h3><br />"
+ "<b><a href=\"%s\">%s</a></b><br />" "<br />" "<br />\r\n"
+ "<i>Generated by ProxyTrack " PROXYTRACK_VERSION
+ ", (C) Xavier Roche and other contributors</i>" "\r\n"
+ "</body>" "</header>", StringBuff(urlRedirect),
+ StringBuff(urlRedirect));
+ StringLength(output) = (int) strlen(StringBuff(output));
+ }
+ }
+ if (msgCode == 0) {
+ msgCode = 404;
+ msgError = "Not Found in this cache";
+ }
+ }
+ }
+ } else {
+ msgCode = 500;
+ msgError = "Server Error";
+ keepAlive = 0;
+ }
+ if (StringLength(headers) == 0) {
+ if (msgCode == 0) {
+ msgCode = 500;
+ msgError = "Internal Proxy Error";
+ } else if (msgError == NULL) {
+ msgError = GetHttpMessage(msgCode);
+ }
+ StringRoom(headers, 256);
+ sprintf(StringBuffRW(headers),
+ "HTTP/1.1 %d %s\r\n" "Content-type: text/html\r\n", msgCode,
+ msgError);
+ StringLength(headers) = (int) strlen(StringBuff(headers));
+ StringRoom(output,
+ 1024 + sizeof(PROXYTRACK_COMMENT_HEADER) +
+ sizeof(DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES));
+ sprintf(StringBuffRW(output),
+ "<html>" PROXYTRACK_COMMENT_HEADER
+ DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES "<head>"
+ "<title>ProxyTrack - HTTP Proxy Error %d</title>" "</head>\r\n"
+ "<body>"
+ "<h3>A proxy error has occured while processing the request.</h3><br />"
+ "<b>Error HTTP %d: <i>%s</i></b><br />" "<br />" "<br />\r\n"
+ "<i>Generated by ProxyTrack " PROXYTRACK_VERSION
+ ", (C) Xavier Roche and other contributors</i>" "\r\n" "</body>"
+ "</html>", msgCode, msgCode, msgError);
+ StringLength(output) = (int) strlen(StringBuff(output));
+ }
+ {
+ char tmp[20 + 1]; /* 2^64 = 18446744073709551616 */
+ size_t dataSize = 0;
+
+ if (!headRequest) {
+ dataSize = StringLength(output);
+ if (dataSize == 0 && element != NULL) {
+ dataSize = element->size;
+ }
+ }
+ sprintf(tmp, "%d", (int) dataSize);
+ StringCat(headers, "Content-length: ");
+ StringCat(headers, tmp);
+ StringCat(headers, "\r\n");
+ }
+ if (keepAlive) {
+ StringCat(headers,
+ "Connection: Keep-Alive\r\n"
+ "Proxy-Connection: Keep-Alive\r\n");
+ } else {
+ StringCat(headers, "Connection: Close\r\n" "Proxy-Connection: Close\r\n");
+ }
+ if (msgCode != 500)
+ StringCat(headers, "X-Cache: HIT from ");
+ else
+ StringCat(headers, "X-Cache: MISS from ");
+ StringCat(headers, StringBuff(localhost));
+ StringCat(headers, "\r\n");
+
+ /* Logging */
+ {
+ const char *contentType = "text/html";
+ size_t size =
+ StringLength(output) ? StringLength(output) : (element ? element->
+ size : 0);
+ /* */
+ String ip = STRING_EMPTY;
+ SOCaddr serverClient;
+ SOClen lenServerClient = (int) sizeof(serverClient);
+
+ memset(&serverClient, 0, sizeof(serverClient));
+ if (getsockname
+ (soc_c, (struct sockaddr *) &serverClient, &lenServerClient) == 0) {
+ ip = getip(&serverClient, lenServerClient);
+ } else {
+ StringCopy(ip, "unknown");
+ }
+ if (element != NULL && element->contenttype[0] != '\0') {
+ contentType = element->contenttype;
+ }
+ proxytrack_print_log(LOG, "HTTP %s %d %d %s %s %s", StringBuff(ip),
+ msgCode, (int) size, command, StringBuff(url),
+ contentType);
+ StringFree(ip);
+ }
+
+ /* Send reply */
+ StringCat(headers,
+ "Server: ProxyTrack " PROXYTRACK_VERSION " (HTTrack "
+ HTTRACK_VERSIONID ")\r\n");
+ StringCat(headers, "\r\n"); /* Headers separator */
+ if (send(soc_c, StringBuff(headers), (int) StringLength(headers), 0) !=
+ StringLength(headers)
+ || (!headRequest && StringLength(output) > 0
+ && send(soc_c, StringBuff(output), (int) StringLength(output),
+ 0) != StringLength(output))
+ || (!headRequest && StringLength(output) == 0 && element != NULL
+ && element->adr != NULL
+ && send(soc_c, element->adr, (int) element->size,
+ 0) != element->size)
+ ) {
+ keepAlive = 0; /* Error, abort connection */
+ }
+ PT_Element_Delete(&element);
+
+ /* Shutdown (FIN) and wait until confirmed */
+ if (!keepAlive) {
+ char c;
+
#ifdef _WIN32
- shutdown(soc_c, SD_SEND);
+ shutdown(soc_c, SD_SEND);
#else
- shutdown(soc_c, 1);
+ shutdown(soc_c, 1);
#endif
- while(recv(soc_c, ((char*)&c), 1, 0) > 0);
- }
- } while(keepAlive);
+ while(recv(soc_c, ((char *) &c), 1, 0) > 0) ;
+ }
+ } while(keepAlive);
#ifdef _WIN32
- closesocket(soc_c);
+ closesocket(soc_c);
#else
- close(soc_c);
+ close(soc_c);
#endif
- StringFree(url);
- StringFree(urlRedirect);
- StringFree(headers);
- StringFree(output);
- StringFree(host);
- StringFree(localhost);
+ StringFree(url);
+ StringFree(urlRedirect);
+ StringFree(headers);
+ StringFree(output);
+ StringFree(host);
+ StringFree(localhost);
#ifndef NO_WEBDAV
- StringFree(davHeaders);
- StringFree(davRequest);
+ StringFree(davHeaders);
+ StringFree(davRequest);
#endif
- if (buffer)
- free(buffer);
- if (line)
- free(line);
- if (line1)
- free(line1);
+ if (buffer)
+ free(buffer);
+ if (line)
+ free(line);
+ if (line1)
+ free(line1);
}
/* Generic threaded function start */
-static int startThread(void (*funct)(void*), void* param)
-{
- if (param != NULL) {
+static int startThread(void (*funct) (void *), void *param) {
+ if (param != NULL) {
#ifdef _WIN32
- if (_beginthread(funct, 0, param) == -1) {
- free(param);
- return 0;
- }
- return 1;
+ if (_beginthread(funct, 0, param) == -1) {
+ free(param);
+ return 0;
+ }
+ return 1;
#else
- pthread_t handle = 0;
- int retcode;
- retcode = pthread_create(&handle, NULL, funct, param);
- if (retcode != 0) { /* error */
- free(param);
- return 0;
- } else {
- /* detach the thread from the main process so that is can be independent */
- pthread_detach(handle);
- return 1;
- }
+ pthread_t handle = 0;
+ int retcode;
+
+ retcode = pthread_create(&handle, NULL, funct, param);
+ if (retcode != 0) { /* error */
+ free(param);
+ return 0;
+ } else {
+ /* detach the thread from the main process so that is can be independent */
+ pthread_detach(handle);
+ return 1;
+ }
#endif
- } else {
- return 0;
- }
+ } else {
+ return 0;
+ }
}
/* Generic socket/index structure */
typedef struct proxytrack_process_th_p {
- T_SOC soc_c;
- PT_Indexes indexes;
- void (*process)(PT_Indexes indexes, T_SOC soc_c);
+ T_SOC soc_c;
+ PT_Indexes indexes;
+ void (*process) (PT_Indexes indexes, T_SOC soc_c);
} proxytrack_process_th_p;
/* Generic socket/index function stub */
-static void proxytrack_process_th(void* param_) {
- proxytrack_process_th_p *param = (proxytrack_process_th_p *) param_;
- T_SOC soc_c = param->soc_c;
- PT_Indexes indexes = param->indexes;
- void (*process)(PT_Indexes indexes, T_SOC soc_c) = param->process;
- free(param);
- process(indexes, soc_c);
- return ;
+static void proxytrack_process_th(void *param_) {
+ proxytrack_process_th_p *param = (proxytrack_process_th_p *) param_;
+ T_SOC soc_c = param->soc_c;
+ PT_Indexes indexes = param->indexes;
+ void (*process) (PT_Indexes indexes, T_SOC soc_c) = param->process;
+
+ free(param);
+ process(indexes, soc_c);
+ return;
}
/* Process generic socket/index operation */
-static int proxytrack_process_generic(void (*process)(PT_Indexes indexes, T_SOC soc_c),
- PT_Indexes indexes, T_SOC soc_c)
-{
- proxytrack_process_th_p *param = calloc(sizeof(proxytrack_process_th_p), 1);
- if (param != NULL) {
- param->soc_c = soc_c;
- param->indexes = indexes;
- param->process = process;
- return startThread(proxytrack_process_th, param);
- } else {
- proxytrack_print_log(CRITICAL, "proxytrack_process_generic:Memory exhausted");
- return 0;
- }
- return 0;
+static int
+proxytrack_process_generic(void (*process) (PT_Indexes indexes, T_SOC soc_c),
+ PT_Indexes indexes, T_SOC soc_c) {
+ proxytrack_process_th_p *param = calloc(sizeof(proxytrack_process_th_p), 1);
+
+ if (param != NULL) {
+ param->soc_c = soc_c;
+ param->indexes = indexes;
+ param->process = process;
+ return startThread(proxytrack_process_th, param);
+ } else {
+ proxytrack_print_log(CRITICAL,
+ "proxytrack_process_generic:Memory exhausted");
+ return 0;
+ }
+ return 0;
}
/* Process HTTP proxy requests */
static int proxytrack_process_HTTP_threaded(PT_Indexes indexes, T_SOC soc) {
- return proxytrack_process_generic(proxytrack_process_HTTP, indexes, soc);
+ return proxytrack_process_generic(proxytrack_process_HTTP, indexes, soc);
}
/* HTTP Server */
static int proxytrack_start_HTTP(PT_Indexes indexes, T_SOC soc) {
- while(soc != INVALID_SOCKET) {
+ while(soc != INVALID_SOCKET) {
T_SOC soc_c;
- if ( (soc_c = (T_SOC) accept(soc, NULL, NULL)) != INVALID_SOCKET) {
- if (!proxytrack_process_HTTP_threaded(indexes, soc_c)) {
- proxytrack_print_log(CRITICAL, "proxytrack_start_HTTP::Can not fork a thread");
- }
- }
- }
- if (soc != INVALID_SOCKET) {
+
+ if ((soc_c = (T_SOC) accept(soc, NULL, NULL)) != INVALID_SOCKET) {
+ if (!proxytrack_process_HTTP_threaded(indexes, soc_c)) {
+ proxytrack_print_log(CRITICAL,
+ "proxytrack_start_HTTP::Can not fork a thread");
+ }
+ }
+ }
+ if (soc != INVALID_SOCKET) {
#ifdef _WIN32
- closesocket(soc);
+ closesocket(soc);
#else
- close(soc);
+ close(soc);
#endif
- }
- return 1;
+ }
+ return 1;
}
/* Network order is big endian */
@@ -1403,191 +1506,208 @@ static int proxytrack_start_HTTP(PT_Indexes indexes, T_SOC soc) {
WRITE_NET16(((unsigned char*)buffer) + 2, ( ((unsigned int)(value)) ) & 0xffff); \
} while(0)
-static int ICP_reply(struct sockaddr * clientAddr,
- int clientAddrLen,
- T_SOC soc,
- /* */
- unsigned char Opcode,
- unsigned char Version,
- unsigned short Message_Length,
- unsigned int Request_Number,
- unsigned int Options,
- unsigned int Option_Data,
- unsigned int Sender_Host_Address,
- unsigned char *Message
- )
-{
- int ret = 0;
- unsigned long int BufferSize;
- unsigned char * buffer;
- if (Message_Length == 0 && Message != NULL) /* We have to get the message size */
- Message_Length = (unsigned int) strlen(Message) + 1; /* NULL terminated */
- BufferSize = 20 + Message_Length;
- buffer = malloc(BufferSize);
- if (buffer != NULL) {
- WRITE_NET8(&buffer[0], Opcode);
- WRITE_NET8(&buffer[1], Version);
- WRITE_NET16(&buffer[2], Message_Length);
- WRITE_NET32(&buffer[4], Request_Number);
- WRITE_NET32(&buffer[8], Options);
- WRITE_NET32(&buffer[12], Option_Data);
- WRITE_NET32(&buffer[16], Sender_Host_Address);
- if (Message != NULL && Message_Length > 0) {
- memcpy(buffer + 20, Message, Message_Length);
- }
- if (sendto(soc, buffer, BufferSize, 0, clientAddr, clientAddrLen) == BufferSize) {
- ret = 1;
- }
- free(buffer);
- }
- return ret;
+static int ICP_reply(struct sockaddr *clientAddr, int clientAddrLen, T_SOC soc,
+ /* */
+ unsigned char Opcode, unsigned char Version,
+ unsigned short Message_Length, unsigned int Request_Number,
+ unsigned int Options, unsigned int Option_Data,
+ unsigned int Sender_Host_Address, unsigned char *Message) {
+ int ret = 0;
+ unsigned long int BufferSize;
+ unsigned char *buffer;
+
+ if (Message_Length == 0 && Message != NULL) /* We have to get the message size */
+ Message_Length = (unsigned int) strlen(Message) + 1; /* NULL terminated */
+ BufferSize = 20 + Message_Length;
+ buffer = malloc(BufferSize);
+ if (buffer != NULL) {
+ WRITE_NET8(&buffer[0], Opcode);
+ WRITE_NET8(&buffer[1], Version);
+ WRITE_NET16(&buffer[2], Message_Length);
+ WRITE_NET32(&buffer[4], Request_Number);
+ WRITE_NET32(&buffer[8], Options);
+ WRITE_NET32(&buffer[12], Option_Data);
+ WRITE_NET32(&buffer[16], Sender_Host_Address);
+ if (Message != NULL && Message_Length > 0) {
+ memcpy(buffer + 20, Message, Message_Length);
+ }
+ if (sendto(soc, buffer, BufferSize, 0, clientAddr, clientAddrLen) ==
+ BufferSize) {
+ ret = 1;
+ }
+ free(buffer);
+ }
+ return ret;
}
/* ICP Server */
static int proxytrack_start_ICP(PT_Indexes indexes, T_SOC soc) {
- /* "ICP messages MUST not exceed 16,384 octets in length." (RFC2186) */
- int bufferSize = 16384;
- unsigned char * buffer = (unsigned char*) malloc(bufferSize + 1);
- if (buffer == NULL) {
- proxytrack_print_log(CRITICAL, "proxytrack_start_ICP:memory exhausted");
+ /* "ICP messages MUST not exceed 16,384 octets in length." (RFC2186) */
+ int bufferSize = 16384;
+ unsigned char *buffer = (unsigned char *) malloc(bufferSize + 1);
+
+ if (buffer == NULL) {
+ proxytrack_print_log(CRITICAL, "proxytrack_start_ICP:memory exhausted");
#ifdef _WIN32
- closesocket(soc);
+ closesocket(soc);
#else
- close(soc);
+ close(soc);
#endif
- return -1;
- }
- while(soc != INVALID_SOCKET) {
- struct sockaddr clientAddr;
- SOClen clientAddrLen = sizeof(struct sockaddr);
- int n;
- memset(&clientAddr, 0, sizeof(clientAddr));
- n = recvfrom(soc, (char*)buffer, bufferSize, 0, &clientAddr, &clientAddrLen);
- if (n != -1) {
- const char * LogRequest = "ERROR";
- const char * LogReply = "ERROR";
- unsigned char * UrlRequest = NULL;
- if (n >= 20) {
- enum {
- ICP_OP_MIN = 0,
- ICP_OP_INVALID = 0,
- ICP_OP_QUERY = 1,
- ICP_OP_HIT = 2,
- ICP_OP_MISS = 3,
- ICP_OP_ERR = 4,
- ICP_OP_SECHO = 10,
- ICP_OP_DECHO = 11,
- ICP_OP_MISS_NOFETCH = 21,
- ICP_OP_DENIED = 22,
- ICP_OP_HIT_OBJ = 23,
- ICP_OP_MAX = ICP_OP_HIT_OBJ
- };
- unsigned char Opcode = buffer[0];
- unsigned char Version = buffer[1];
- unsigned short Message_Length = READ_NET16(&buffer[2]);
- unsigned int Request_Number = READ_NET32(&buffer[4]); /* Session ID */
- unsigned int Options = READ_NET32(&buffer[8]);
- unsigned int Option_Data = READ_NET32(&buffer[12]); /* ICP_FLAG_SRC_RTT */
- unsigned int Sender_Host_Address = READ_NET32(&buffer[16]); /* ignored */
- unsigned char* Payload = &buffer[20];
- buffer[bufferSize] = '\0'; /* Ensure payload is NULL terminated */
- if (Message_Length <= bufferSize - 20) {
- if (Opcode >= ICP_OP_MIN && Opcode <= ICP_OP_MAX) {
- if (Version == 2) {
- switch(Opcode) {
- case ICP_OP_QUERY:
- {
- unsigned int UrlRequestSize;
- UrlRequest = &Payload[4];
- UrlRequestSize = (unsigned int)strlen((char*)UrlRequest);
- LogRequest = "ICP_OP_QUERY";
- if (indexes == NULL) {
- ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_DENIED, Version, 0, Request_Number, 0, 0, 0, UrlRequest);
- LogReply = "ICP_OP_DENIED";
- } else if (PT_LookupIndex(indexes, UrlRequest)) {
- ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_HIT, Version, 0, Request_Number, 0, 0, 0, UrlRequest);
- LogReply = "ICP_OP_HIT";
- } else {
- if (UrlRequestSize > 0 && UrlRequest[UrlRequestSize - 1] != '/' && strchr(UrlRequest, '?') == NULL) {
- char * UrlRedirect = malloc(UrlRequestSize + 1 + 1);
- if (UrlRedirect != NULL) {
- sprintf(UrlRedirect, "%s/", UrlRequest);
- if (PT_LookupIndex(indexes, UrlRedirect)) { /* We'll generate a redirect */
- ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_HIT, Version, 0, Request_Number, 0, 0, 0, UrlRequest);
- LogReply = "ICP_OP_HIT";
- free(UrlRedirect);
- break;
- }
- free(UrlRedirect);
- }
- }
- /* We won't retrive the cache MISS online, no way! */
- ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_MISS_NOFETCH, Version, 0, Request_Number, 0, 0, 0, UrlRequest);
- LogReply = "ICP_OP_MISS_NOFETCH";
- }
- }
- break;
- case ICP_OP_SECHO:
- {
- UrlRequest = &Payload[4];
- LogRequest = "ICP_OP_QUERY";
- LogReply = "ICP_OP_QUERY";
- ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_SECHO, Version, 0, Request_Number, 0, 0, 0, UrlRequest);
- }
- break;
- default:
- LogRequest = "NOTIMPLEMENTED";
- LogReply = "ICP_OP_ERR";
- ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_ERR, Version, 0, Request_Number, 0, 0, 0, NULL);
- break;
- }
- } else {
- ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_ERR, 2, 0, Request_Number, 0, 0, 0, NULL);
- }
- } /* Ignored (RFC2186) */
- } else {
- ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_ERR, Version, 0, Request_Number, 0, 0, 0, NULL);
- }
- }
-
- /* Logging */
- {
- String ip = STRING_EMPTY;
- SOCaddr serverClient;
- int lenServerClient = (int) sizeof(serverClient);
- SOCaddr_copyaddr(serverClient, lenServerClient, &clientAddr, clientAddrLen);
- if (lenServerClient > 0) {
- ip = getip(&serverClient, lenServerClient);
- } else {
- StringCopy(ip, "unknown");
- }
- proxytrack_print_log(LOG, "ICP %s %s/%s %s", StringBuff(ip), LogRequest, LogReply, (UrlRequest ? UrlRequest : "-") );
- StringFree(ip);
- }
-
- }
- }
- if (soc != INVALID_SOCKET) {
+ return -1;
+ }
+ while(soc != INVALID_SOCKET) {
+ struct sockaddr clientAddr;
+ SOClen clientAddrLen = sizeof(struct sockaddr);
+ int n;
+
+ memset(&clientAddr, 0, sizeof(clientAddr));
+ n =
+ recvfrom(soc, (char *) buffer, bufferSize, 0, &clientAddr,
+ &clientAddrLen);
+ if (n != -1) {
+ const char *LogRequest = "ERROR";
+ const char *LogReply = "ERROR";
+ unsigned char *UrlRequest = NULL;
+
+ if (n >= 20) {
+ enum {
+ ICP_OP_MIN = 0,
+ ICP_OP_INVALID = 0,
+ ICP_OP_QUERY = 1,
+ ICP_OP_HIT = 2,
+ ICP_OP_MISS = 3,
+ ICP_OP_ERR = 4,
+ ICP_OP_SECHO = 10,
+ ICP_OP_DECHO = 11,
+ ICP_OP_MISS_NOFETCH = 21,
+ ICP_OP_DENIED = 22,
+ ICP_OP_HIT_OBJ = 23,
+ ICP_OP_MAX = ICP_OP_HIT_OBJ
+ };
+ unsigned char Opcode = buffer[0];
+ unsigned char Version = buffer[1];
+ unsigned short Message_Length = READ_NET16(&buffer[2]);
+ unsigned int Request_Number = READ_NET32(&buffer[4]); /* Session ID */
+ unsigned int Options = READ_NET32(&buffer[8]);
+ unsigned int Option_Data = READ_NET32(&buffer[12]); /* ICP_FLAG_SRC_RTT */
+ unsigned int Sender_Host_Address = READ_NET32(&buffer[16]); /* ignored */
+ unsigned char *Payload = &buffer[20];
+
+ buffer[bufferSize] = '\0'; /* Ensure payload is NULL terminated */
+ if (Message_Length <= bufferSize - 20) {
+ if (Opcode >= ICP_OP_MIN && Opcode <= ICP_OP_MAX) {
+ if (Version == 2) {
+ switch (Opcode) {
+ case ICP_OP_QUERY:
+ {
+ unsigned int UrlRequestSize;
+
+ UrlRequest = &Payload[4];
+ UrlRequestSize = (unsigned int) strlen((char *) UrlRequest);
+ LogRequest = "ICP_OP_QUERY";
+ if (indexes == NULL) {
+ ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_DENIED,
+ Version, 0, Request_Number, 0, 0, 0, UrlRequest);
+ LogReply = "ICP_OP_DENIED";
+ } else if (PT_LookupIndex(indexes, UrlRequest)) {
+ ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_HIT,
+ Version, 0, Request_Number, 0, 0, 0, UrlRequest);
+ LogReply = "ICP_OP_HIT";
+ } else {
+ if (UrlRequestSize > 0
+ && UrlRequest[UrlRequestSize - 1] != '/'
+ && strchr(UrlRequest, '?') == NULL) {
+ char *UrlRedirect = malloc(UrlRequestSize + 1 + 1);
+
+ if (UrlRedirect != NULL) {
+ sprintf(UrlRedirect, "%s/", UrlRequest);
+ if (PT_LookupIndex(indexes, UrlRedirect)) { /* We'll generate a redirect */
+ ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_HIT,
+ Version, 0, Request_Number, 0, 0, 0,
+ UrlRequest);
+ LogReply = "ICP_OP_HIT";
+ free(UrlRedirect);
+ break;
+ }
+ free(UrlRedirect);
+ }
+ }
+ /* We won't retrive the cache MISS online, no way! */
+ ICP_reply(&clientAddr, clientAddrLen, soc,
+ ICP_OP_MISS_NOFETCH, Version, 0, Request_Number,
+ 0, 0, 0, UrlRequest);
+ LogReply = "ICP_OP_MISS_NOFETCH";
+ }
+ }
+ break;
+ case ICP_OP_SECHO:
+ {
+ UrlRequest = &Payload[4];
+ LogRequest = "ICP_OP_QUERY";
+ LogReply = "ICP_OP_QUERY";
+ ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_SECHO,
+ Version, 0, Request_Number, 0, 0, 0, UrlRequest);
+ }
+ break;
+ default:
+ LogRequest = "NOTIMPLEMENTED";
+ LogReply = "ICP_OP_ERR";
+ ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_ERR, Version,
+ 0, Request_Number, 0, 0, 0, NULL);
+ break;
+ }
+ } else {
+ ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_ERR, 2, 0,
+ Request_Number, 0, 0, 0, NULL);
+ }
+ } /* Ignored (RFC2186) */
+ } else {
+ ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_ERR, Version, 0,
+ Request_Number, 0, 0, 0, NULL);
+ }
+ }
+
+ /* Logging */
+ {
+ String ip = STRING_EMPTY;
+ SOCaddr serverClient;
+ int lenServerClient = (int) sizeof(serverClient);
+
+ SOCaddr_copyaddr(serverClient, lenServerClient, &clientAddr,
+ clientAddrLen);
+ if (lenServerClient > 0) {
+ ip = getip(&serverClient, lenServerClient);
+ } else {
+ StringCopy(ip, "unknown");
+ }
+ proxytrack_print_log(LOG, "ICP %s %s/%s %s", StringBuff(ip), LogRequest,
+ LogReply, (UrlRequest ? UrlRequest : "-"));
+ StringFree(ip);
+ }
+
+ }
+ }
+ if (soc != INVALID_SOCKET) {
#ifdef _WIN32
- closesocket(soc);
+ closesocket(soc);
#else
- close(soc);
+ close(soc);
#endif
- }
- free(buffer);
- return 1;
+ }
+ free(buffer);
+ return 1;
}
static int proxytrack_start(PT_Indexes indexes, T_SOC soc, T_SOC socICP) {
- int ret = 1;
- if (proxytrack_process_generic(proxytrack_start_ICP, indexes, socICP)) {
- //if (!proxytrack_process_generic(proxytrack_start_HTTP, indexes, soc))
- if (!proxytrack_start_HTTP(indexes, soc)) {
- ret = 0;
- }
- } else {
- ret = 0;
- }
- return ret;
-}
+ int ret = 1;
+ if (proxytrack_process_generic(proxytrack_start_ICP, indexes, socICP)) {
+ //if (!proxytrack_process_generic(proxytrack_start_HTTP, indexes, soc))
+ if (!proxytrack_start_HTTP(indexes, soc)) {
+ ret = 0;
+ }
+ } else {
+ ret = 0;
+ }
+ return ret;
+}