wwwoffles.c
上传用户:seven77cht
上传日期:2007-01-04
资源大小:486k
文件大小:48k
- /***************************************
- $Header: /home/amb/wwwoffle/RCS/wwwoffles.c 2.141 1999/12/04 11:38:21 amb Exp $
- WWWOFFLE - World Wide Web Offline Explorer - Version 2.5c.
- A server to fetch the required pages.
- ******************/ /******************
- Written by Andrew M. Bishop
- This file Copyright 1996,97,98,99 Andrew M. Bishop
- It may be distributed under the GNU Public License, version 2, or
- any higher version. See section COPYING of the GNU Public license
- for conditions under which this file may be redistributed.
- ***************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <time.h>
- #include <signal.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include "wwwoffle.h"
- #include "document.h"
- #include "misc.h"
- #include "proto.h"
- #include "config.h"
- #include "sockets.h"
- #include "errors.h"
- static int ssl_tunnel(int client,URL *Url,Header *request_head);
- static void uninstall_sighandlers(void);
- /*+ The mode of operation of the server. +*/
- typedef enum _Mode
- {
- None, /*+ Undecided. +*/
- Real, /*+ From server host to cache and client. +*/
- RealNoCache, /*+ From server host to client. +*/
- RealRefresh, /*+ Refresh the page, forced from index. +*/
- RealNoPassword, /*+ From server host to cache, not using supplied password. +*/
- SpoolOrReal, /*+ Spool if already cached else Real. +*/
- Fetch, /*+ From server host to cache. +*/
- FetchNoPassword, /*+ From server host to cache, not using supplied password. +*/
- Spool, /*+ From cache to client. +*/
- SpoolGet, /*+ Not in cache so record request in outgoing. +*/
- SpoolWillGet, /*+ Not in cache but is in outgoing. +*/
- SpoolRefresh, /*+ Refresh the page, forced from refresh page. +*/
- SpoolPragma, /*+ Refresh the page, forced from browser by 'Pragma: no-cache'. +*/
- SpoolInternal /*+ The page is one that has been internally generated by WWWOFFLE. +*/
- }
- Mode;
- /*++++++++++++++++++++++++++++++++++++++
- The main server program.
- int wwwoffles Returns the exit status.
- int online Whether the demon is online or not.
- int browser Set to true if there is a browser.
- int client The file descriptor of the client.
- ++++++++++++++++++++++++++++++++++++++*/
- int wwwoffles(int online,int browser,int client)
- {
- int outgoing=-1,spool=-1,tmpclient=-1;
- int fetch_again=0;
- char *proxy_auth,*proxy_user;
- char *aliasProto=NULL,*aliasHost=NULL,*aliasPath=NULL;
- Header *request_head=NULL,*reply_head=NULL;
- Body *request_body=NULL,*reply_body=NULL;
- int reply_status=-1,head_only=0;
- char *url;
- URL *Url=NULL,*Urlpw=NULL;
- Mode mode=None;
- int outgoing_exists=0,lasttime_exists=0;
- time_t spool_exists=0,spool_exists_pw=0;
- int offline_request=1;
- char *is_client_wwwoffle=NULL,*is_client_htdig=NULL;
- /* Initialise things. */
- uninstall_sighandlers();
- InitErrorHandler("wwwoffles",-1,-1); /* change name nothing else */
- if(online==1 && browser)
- mode=Real;
- else if(online==1 && !browser)
- mode=Fetch;
- else if(online==-1 && browser)
- mode=SpoolOrReal;
- else if(!online && browser)
- mode=Spool;
- else
- PrintMessage(Fatal,"Started in a mode that is not allowed (online=%d, browser=%d).",online,browser);
- /* mode = Spool, Real, SpoolOrReal or Fetch */
- /* Set up the client file. */
- if(client==-1 && mode!=Fetch)
- PrintMessage(Fatal,"Cannot use client file descriptor %d.",client);
- if(mode!=Fetch)
- {
- tmpclient=CreateTempSpoolFile();
- if(tmpclient==-1)
- {
- PrintMessage(Warning,"Cannot open temporary spool file [%!s].");
- HTMLMessage(client,500,"WWWOFFLE Server Error",NULL,"ServerError",
- "error","Cannot open temporary file.",
- NULL);
- exit(1);
- }
- }
- /* Set up the outgoing file. */
- if(mode==Fetch)
- {
- outgoing=OpenOutgoingSpoolFile(1);
- init_buffer(outgoing);
- if(outgoing==-1)
- {PrintMessage(Inform,"No more outgoing requests.");exit(3);}
- }
- /* Get the URL from the request. */
- if(mode==Real || mode==Spool || mode==SpoolOrReal)
- url=ParseRequest(client,&request_head,&request_body);
- else /* mode==Fetch */
- url=ParseRequest(outgoing,&request_head,&request_body);
- if(DebugLevel==ExtraDebug)
- {
- if(request_head)
- PrintMessage(ExtraDebug,"Incoming Request Head (from browser)n%s",HeaderString(request_head));
- else
- PrintMessage(ExtraDebug,"Incoming Request Head (from browser) is empty");
- if(request_body)
- if(strcmp(request_head->method,"POST")) /* only POST is guaranteed to be ASCII. */
- PrintMessage(ExtraDebug,"Incoming Request Body (from browser) is %d bytes of binary datan",request_body->length);
- else
- PrintMessage(ExtraDebug,"Incoming Request Body (from browser)n%s",request_body->content);
- }
- if(!url)
- {
- PrintMessage(Warning,"Could not parse HTTP request (%s).",request_head?"Parse error":"Empty request");
- if(mode!=Fetch)
- HTMLMessage(client,500,"WWWOFFLE Server Error",NULL,"ServerError",
- "error",request_head?"Cannot parse the HTTP request":"The HTTP request was empty",
- NULL);
- exit(1);
- }
- Url=SplitURL(url);
- /* Authenticate the user with the proxy */
- proxy_auth=GetHeader(request_head,"Proxy-Authorization",NULL);
- proxy_user=IsAllowedConnectUser(proxy_auth);
- if(!proxy_user)
- {
- PrintMessage(Inform,"HTTP Proxy connection rejected from unauthenticated user."); /* Used in audit-usage.pl */
- HTMLMessageHead(tmpclient,407,"WWWOFFLE Proxy Authentication Required",
- "Proxy-Authenticate","Basic realm="wwwoffle-proxy"",
- NULL);
- HTMLMessageBody(tmpclient,"ProxyAuthFail",
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- else if(proxy_auth)
- PrintMessage(Inform,"HTTP Proxy connection from user '%s'.",proxy_user); /* Used in audit-usage.pl */
- /* Check the HTTP method that is requested */
- if(!strcasecmp(request_head->method,"CONNECT"))
- {
- PrintMessage(Inform,"SSL='%s'.",Url->host); /* Used in audit-usage.pl */
- if(mode==Real || mode==SpoolOrReal || (mode==Spool && IsLocalNetHost(Url->host)))
- {
- if(IsSSLAllowedPort(Url->host))
- {
- int ret=ssl_tunnel(client,Url,request_head);
- exit(ret);
- }
- else
- {
- PrintMessage(Warning,"A SSL proxy connection for %s was received but is not allowed.",Url->host);
- HTMLMessage(tmpclient,500,"WWWOFFLE Server Error",NULL,"ServerError",
- "error","SSL proxy connection to specified port is not allowed.",
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- }
- else /* mode==Fetch || mode==Spool */
- {
- PrintMessage(Warning,"A SSL proxy connection for %s was received but wwwoffles is in wrong mode.",Url->host);
- if(mode==Fetch)
- {
- if(client!=-1)
- write_formatted(client,"Cannot fetch %s [HTTP method 'CONNECT' not supported in this mode]n",Url->name);
- exit(1);
- }
- else
- {
- HTMLMessage(tmpclient,500,"WWWOFFLE Server Error",NULL,"ServerError",
- "error","SSL proxy connection while offline is not allowed.",
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- }
- }
- else if(strcmp(request_head->method,"GET") &&
- strcmp(request_head->method,"HEAD") &&
- strcmp(request_head->method,"POST") &&
- strcmp(request_head->method,"PUT"))
- {
- PrintMessage(Warning,"The requested method '%s' is not supported.",request_head->method);
- if(mode==Fetch)
- {
- if(client!=-1)
- write_formatted(client,"Cannot fetch %s [The %s method is not supported]n",Url->name,request_head->method);
- exit(1);
- }
- else
- {
- HTMLMessage(tmpclient,501,"WWWOFFLE Method Unsupported",NULL,"MethodUnsupported",
- "method",request_head->method,
- "protocol","all",
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- }
- else if(!strcmp(request_head->method,"HEAD"))
- {
- strcpy(request_head->method,"GET");
- request_head->size-=1;
- head_only=1;
- }
- PrintMessage(Inform,"URL='%s'%s.",Url->name,Url->user?" (With username/password)":""); /* Used in audit-usage.pl */
- PrintMessage(Debug,"proto='%s'; host='%s'; path='%s'; args='%s'; user:pass='%s:%s'.",
- Url->proto,Url->host,Url->path,Url->args,Url->user,Url->pass);
- /* Check for an alias. */
- if(IsAliased(Url->proto,Url->host,Url->path,&aliasProto,&aliasHost,&aliasPath))
- {
- URL *newUrl;
- char *newurl=(char*)malloc(strlen(aliasProto)+strlen(aliasHost)+strlen(aliasPath)-
- strlen(Url->path)+strlen(Url->pathp)+8);
- sprintf(newurl,"%s://%s%s%s",aliasProto,aliasHost,aliasPath,Url->pathp+strlen(Url->path));
- newUrl=SplitURL(newurl);
- if(Url->user)
- AddURLPassword(newUrl,Url->user,Url->pass);
- url=newurl;
- FreeURL(Url);
- Url=newUrl;
- PrintMessage(Inform,"Aliased URL='%s'%s.",newUrl->name,newUrl->user?" (With username/password)":"");
- PrintMessage(Debug,"Aliased proto='%s'; host='%s'; path='%s'; args='%s'; user:pass='%s:%s'.",
- newUrl->proto,newUrl->host,newUrl->path,newUrl->args,newUrl->user,newUrl->pass);
- }
- /* Initial sanity checks. */
- if(IsNotGot(Url->proto,Url->host,Url->path,Url->args))
- {
- char *replace = NotGotReplacement(Url->proto,Url->host,Url->path,Url->args);
- if(!replace)
- {
- PrintMessage(Inform,"The server '%s://%s' and/or path '%s' is on the list not to get.",Url->proto,Url->host,Url->path);
- if(mode==Fetch)
- exit(0);
- else
- {
- HTMLMessage(tmpclient,404,"WWWOFFLE Host Not Got",NULL,"HostNotGot",
- "url",Url->name,
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- }
- else
- {
- char *newurl=(char*)malloc(strlen(replace)+1);
- URL *newUrl=SplitURL(replace);
- strcpy(newurl,replace);
- url=newurl;
- FreeURL(Url);
- Url=newUrl;
- PrintMessage(Inform,"Replaced URL='%s'%s.",newUrl->name,newUrl->user?" (With username/password)":"");
- PrintMessage(Debug,"Replaced proto='%s'; host='%s'; path='%s'; args='%s'; user:pass='%s:%s'.",
- newUrl->proto,newUrl->host,newUrl->path,newUrl->args,newUrl->user,newUrl->pass);
- }
- }
- if(!Url->Protocol)
- {
- PrintMessage(Inform,"The protocol '%s' is not available.",Url->proto);
- if(mode==Fetch)
- {
- if(client!=-1)
- write_formatted(client,"Cannot fetch %s [Protocol not available]n",Url->name);
- exit(1);
- }
- else
- {
- HTMLMessage(tmpclient,404,"WWWOFFLE Illegal Protocol",NULL,"IllegalProtocol",
- "url",Url->name,
- "protocol",Url->proto,
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- }
- if((!strcmp(request_head->method,"POST") && !Url->Protocol->postable) ||
- (!strcmp(request_head->method,"PUT") && !Url->Protocol->putable))
- {
- PrintMessage(Warning,"The requested method '%s' is not supported for the %s protocol.",request_head->method,Url->Protocol->name);
- if(mode==Fetch)
- {
- if(client!=-1)
- write_formatted(client,"Cannot fetch %s [The %s method is not supported for %s]n",Url->name,request_head->method,Url->Protocol->name);
- exit(1);
- }
- else
- {
- HTMLMessage(tmpclient,501,"WWWOFFLE Method Unsupported",NULL,"MethodUnsupported",
- "method",request_head->method,
- "protocol",Url->Protocol->name,
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- }
- /* Change the mode based on the URL as required. */
- /* mode = Spool, Real, SpoolOrReal or Fetch */
- /* A local URL. */
- if(Url->local)
- {
- if(!strncmp("/refresh",Url->path,8))
- {
- int recurse=0;
- char *newurl=RefreshPage(tmpclient,Url,request_body,&recurse);
- if(!newurl)
- {mode=SpoolInternal; goto spoolinternal;}
- else
- {
- URL *newUrl=SplitURL(newurl);
- if(Url->user)
- AddURLPassword(newUrl,Url->user,Url->pass);
- if(newUrl->args && *newUrl->args=='!')
- {
- PrintMessage(Inform,"It is not possible to refresh a URL that used the POST/PUT method.");
- if(mode==Fetch)
- {
- if(client!=-1)
- write_formatted(client,"Cannot fetch %s [Reply from a POST/PUT method]n",Url->name);
- exit(1);
- }
- else
- {
- HTMLMessage(tmpclient,404,"WWWOFFLE Cant Refresh POST/PUT",NULL,"CantRefreshPosted",
- "url",newUrl->name,
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- }
- else if(recurse)
- {
- fetch_again=1;
- if(mode!=Fetch)
- {
- mode=SpoolGet;
- if(!Url->args || *Url->args!='!')
- {
- free(newurl);
- FreeURL(newUrl);
- newurl=(char*)malloc(strlen(url)+1);
- strcpy(newurl,url);
- newUrl=SplitURL(newurl);
- if(Url->user)
- AddURLPassword(newUrl,Url->user,Url->pass);
- }
- FreeHeader(request_head);
- request_head=RequestURL(newUrl,NULL);
- if(request_body)
- FreeBody(request_body);
- request_body=NULL;
- }
- }
- else
- {
- if(mode==Spool)
- mode=SpoolRefresh;
- else
- {
- DeleteWebpageSpoolFile(newUrl,0);
- mode=RealRefresh;
- }
- }
- url=newurl;
- FreeURL(Url);
- Url=newUrl;
- PrintMessage(Inform,"Refresh URL='%s'%s.",newUrl->name,newUrl->user?" (With username/password)":"");
- PrintMessage(Debug,"Refresh proto='%s'; host='%s'; path='%s'; args='%s'; user:pass='%s:%s'.",
- newUrl->proto,newUrl->host,newUrl->path,newUrl->args,newUrl->user,newUrl->pass);
- }
- }
- else if(mode==Fetch)
- {
- PrintMessage(Inform,"The request to fetch a page from the local host is ignored.");
- if(client!=-1)
- write_formatted(client,"Cannot fetch %s [On local host]n",Url->name);
- exit(1);
- }
- else if(!strncmp("/index/",Url->path,7))
- {
- IndexPage(tmpclient,Url);
- mode=SpoolInternal; goto spoolinternal;
- }
- else if(!strncmp("/control/",Url->path,9))
- {
- ControlPage(tmpclient,Url,request_head,request_body);
- mode=SpoolInternal; goto spoolinternal;
- }
- else if(!strncmp("/monitor",Url->path,8))
- {
- MonitorPage(tmpclient,Url,request_body);
- mode=SpoolInternal; goto spoolinternal;
- }
- else if((!strchr(Url->path+1,'/') || !strncmp("/local/",Url->path,7)) && !Url->args)
- {
- LocalPage(tmpclient,Url->path,request_head);
- mode=SpoolInternal; goto spoolinternal;
- }
- else if(!strncmp("/htdig/",Url->path,7))
- {
- HTDigPage(tmpclient,Url,request_head);
- mode=SpoolInternal; goto spoolinternal;
- }
- else
- {
- int i;
- for(i=0;i<NProtocols;i++)
- if(!strncmp(Protocols[i].name,Url->pathp+1,strlen(Protocols[i].name)) &&
- Url->pathp[strlen(Protocols[i].name)+1]=='/')
- {
- url=(char*)malloc(strlen(Url->pathp)+4);
- Url->pathp[strlen(Protocols[i].name)+1]=0;
- sprintf(url,"%s://%s",Url->pathp+1,&Url->pathp[strlen(Protocols[i].name)+2]);
- Url->pathp[strlen(Protocols[i].name)+1]='/';
- break;
- }
- if(i==NProtocols)
- {
- PrintMessage(Inform,"The requested URL '%s' does not exist on the local server.",Url->pathp);
- HTMLMessage(tmpclient,404,"WWWOFFLE Page Not Found",NULL,"PageNotFound",
- "url",Url->name,
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- else
- {
- FreeURL(Url);
- Url=SplitURL(url);
- }
- }
- /* Repeat initial sanity checks. */
- if(IsNotGot(Url->proto,Url->host,Url->path,Url->args))
- {
- char *replace = NotGotReplacement(Url->proto,Url->host,Url->path,Url->args);
- if(!replace)
- {
- PrintMessage(Inform,"The server '%s://%s' and/or path '%s' is on the list not to get.",Url->proto,Url->host,Url->path);
- if(mode==Fetch)
- exit(0);
- else
- {
- HTMLMessage(tmpclient,404,"WWWOFFLE Host Not Got",NULL,"HostNotGot",
- "url",Url->name,
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- }
- else
- {
- char *newurl=(char*)malloc(strlen(replace)+1);
- URL *newUrl=SplitURL(replace);
- strcpy(newurl,replace);
- url=newurl;
- FreeURL(Url);
- Url=newUrl;
- PrintMessage(Inform,"Replaced URL='%s'%s.",newUrl->name,newUrl->user?" (With username/password)":"");
- PrintMessage(Debug,"Replaced proto='%s'; host='%s'; path='%s'; args='%s'; user:pass='%s:%s'.",
- newUrl->proto,newUrl->host,newUrl->path,newUrl->args,newUrl->user,newUrl->pass);
- }
- }
- if(!Url->Protocol)
- {
- PrintMessage(Inform,"The protocol '%s' is not available.",Url->proto);
- if(mode==Fetch)
- {
- if(client!=-1)
- write_formatted(client,"Cannot fetch %s [Protocol not available]n",Url->name);
- exit(1);
- }
- else
- {
- HTMLMessage(tmpclient,404,"WWWOFFLE Illegal Protocol",NULL,"IllegalProtocol",
- "url",Url->name,
- "protocol",Url->proto,
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- }
- if((!strcmp(request_head->method,"POST") && !Url->Protocol->postable) ||
- (!strcmp(request_head->method,"PUT") && !Url->Protocol->putable))
- {
- PrintMessage(Warning,"The requested method '%s' is not supported for the %s protocol.",request_head->method,Url->Protocol->name);
- if(mode==Fetch)
- {
- if(client!=-1)
- write_formatted(client,"Cannot fetch %s [The %s method is not supported for %s]n",Url->name,request_head->method,Url->Protocol->name);
- exit(1);
- }
- else
- {
- HTMLMessage(tmpclient,501,"WWWOFFLE Method Unsupported",NULL,"MethodUnsupported",
- "method",request_head->method,
- "protocol",Url->Protocol->name,
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- }
- }
- else if(mode==Fetch)
- ParseRecurseOptions(NULL);
- /* mode = Spool, SpoolGet, SpoolRefresh, Real, RealRefresh, SpoolOrReal or Fetch */
- /* Check for a username / password */
- if(Url->user)
- {
- URL *new=SplitURL(Url->name);
- Urlpw=Url;
- Url=new;
- if(!Urlpw->pass)
- {
- if(mode==Fetch)
- {
- FreeURL(Urlpw);
- Urlpw=NULL;
- }
- else
- {
- HTMLMessage(tmpclient,403,"WWWOFFLE Username Needs Password",NULL,"UserNeedsPass",
- "url",Urlpw->name,
- "user",Urlpw->user,
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- }
- }
- /* Check for an existing cached version */
- outgoing_exists=ExistsOutgoingSpoolFile(Url);
- spool_exists=ExistsWebpageSpoolFile(Url);
- if(Urlpw)
- {
- spool_exists_pw=ExistsWebpageSpoolFile(Urlpw);
- if((mode==Spool || mode==SpoolGet || mode==SpoolOrReal) && spool_exists)
- {
- if(SpooledPageStatus(Url)==401)
- {FreeURL(Url);Url=Urlpw;Urlpw=NULL;
- spool_exists=spool_exists_pw;spool_exists_pw=0;}
- else
- {FreeURL(Urlpw);Urlpw=NULL;
- spool_exists_pw=0;}
- }
- else if(mode==Spool || mode==SpoolGet || mode==SpoolOrReal) /* && ! spool_exists */
- {
- if(spool_exists_pw)
- {
- int new_outgoing=OpenOutgoingSpoolFile(0);
- if(new_outgoing==-1)
- PrintMessage(Warning,"Cannot open the new outgoing request to write.");
- else
- {
- char *head=HeaderString(request_head);
- write_string(new_outgoing,head);
- if(request_body)
- write_data(new_outgoing,request_body->content,request_body->length);
- CloseOutgoingSpoolFile(new_outgoing,Url);
- free(head);
- }
- }
- FreeURL(Url);Url=Urlpw;Urlpw=NULL;
- spool_exists=spool_exists_pw;spool_exists_pw=0;
- }
- else if((mode==Fetch || mode==Real) && spool_exists)
- {
- if(SpooledPageStatus(Url)==401)
- {FreeURL(Url);Url=Urlpw;Urlpw=NULL;
- spool_exists=spool_exists_pw;spool_exists_pw=0;}
- else
- {FreeURL(Urlpw);Urlpw=NULL;
- spool_exists_pw=0;}
- }
- }
- /* If mode is Real or Fetch and a password is set then get page with
- no password then come here and try again with a password. */
- passwordagain:
- /* Check if it needs to be cached. */
- if(IsLocalNetHost(Url->host))
- {
- if(mode==Real || mode==Spool || mode==SpoolOrReal)
- mode=RealNoCache;
- else if(mode==Fetch)
- {
- PrintMessage(Inform,"The request to fetch a page from the local network host '%s' is ignored.",Url->host);
- if(client!=-1)
- write_formatted(client,"Cannot fetch %s [On local network]n",Url->name);
- exit(1);
- }
- }
- else if((mode==Real || mode==SpoolOrReal) && IsNotCached(Url->proto,Url->host,Url->path,Url->args))
- {
- mode=RealNoCache;
- }
- if(mode==RealNoCache && Urlpw)
- {FreeURL(Url);Url=Urlpw;Urlpw=NULL;
- spool_exists=spool_exists_pw;spool_exists_pw=0;}
- /* mode = Spool, SpoolGet, SpoolRefresh, Real, RealRefresh, RealNoCache, SpoolOrReal or Fetch */
- /* Check if it was a POST/PUT method. */
- if(!strcmp(request_head->method,"POST") ||
- !strcmp(request_head->method,"PUT"))
- {
- if(mode==Spool)
- mode=SpoolGet;
- }
- else if(Url->args && *Url->args=='!')
- {
- if(mode==Fetch)
- {
- PrintMessage(Inform,"It is not possible to fetch a URL that used the POST/PUT method.");
- if(client!=-1)
- write_formatted(client,"Cannot fetch %s [Reply from a POST/PUT method]n",Url->name);
- exit(1);
- }
- else if(!spool_exists && !outgoing_exists)
- {
- PrintMessage(Inform,"It is not possible to request a URL that used the POST/PUT method.");
- HTMLMessage(tmpclient,404,"WWWOFFLE Cant Refresh POST/PUT",NULL,"CantRefreshPosted",
- "url",Url->name,
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- else
- mode=Spool;
- }
- /* Check if it is a conditional request. */
- if(mode!=RealNoCache && GetHeader(request_head,"If-Modified-Since",NULL))
- {
- char *val=GetHeader(request_head,"If-Modified-Since",NULL);
- if(mode==Spool || mode==SpoolOrReal)
- {
- spool=OpenWebpageSpoolFile(1,Url);
- if(spool!=-1)
- {
- Header *spooled_head=NULL;
- char *modified;
- time_t modtime;
- time_t since=DateToTimeT(val);
- init_buffer(spool);
- ParseReply(spool,NULL,&spooled_head);
- if(spooled_head && (modified=GetHeader(spooled_head,"Last-Modified",NULL)))
- modtime=DateToTimeT(modified);
- else
- {
- struct stat buf;
- if(fstat(spool,&buf))
- modtime=time(NULL)+1;
- else
- modtime=buf.st_mtime;
- }
- close(spool);
- spool=-1;
- if(spooled_head)
- FreeHeader(spooled_head);
- if(since>=modtime)
- {
- HTMLMessageHead(tmpclient,304,"WWWOFFLE Not Modified",
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- }
- }
- RemoveFromHeader(request_head,"If-Modified-Since",NULL);
- }
- /* Check if a refresh is needed based on pragma, request changes, autodial. */
- if(mode==Real && ExistsLockWebpageSpoolFile(Url))
- {
- mode=Spool;
- }
- else if(mode==Fetch && ExistsLockWebpageSpoolFile(Url))
- {
- PrintMessage(Debug,"Already fetching URL.");
- if(client!=-1)
- write_formatted(client,"Cannot fetch %s [Already fetching]n",Url->name);
- exit(fetch_again?4:0);
- }
- else if(RefreshForced() || (PragmaNoCache && GetHeader(request_head,"Pragma","no-cache")))
- {
- if(mode==Spool || mode==SpoolGet)
- {
- if(spool_exists)
- mode=SpoolPragma;
- else
- if(outgoing_exists)
- mode=SpoolWillGet;
- else
- mode=SpoolGet;
- }
- else if(mode==SpoolOrReal)
- mode=Real;
- /* (mode==Fetch || mode==Real) are left unchanged, not modified as below. */
- }
- else if(mode==Spool && !spool_exists)
- {
- if(outgoing_exists)
- mode=SpoolWillGet;
- else
- mode=SpoolGet;
- }
- else if(mode==Fetch && spool_exists)
- {
- spool=OpenWebpageSpoolFile(1,Url);
- init_buffer(spool);
- if((RequestChanged>=0 || RequestChangedOnce) && RequestChanges(spool,request_head)==1)
- TouchWebpageSpoolFile(Url,0);
- else if(fetch_again)
- {
- lseek(spool,0,SEEK_SET);
- init_buffer(spool);
- if(ParseDocument(spool,Url))
- RecurseFetch(Url,0);
- exit(4);
- }
- else
- exit(0);
- close(spool);
- }
- else if(mode==Real && spool_exists)
- {
- spool=OpenWebpageSpoolFile(1,Url);
- init_buffer(spool);
- if((RequestChanged>=0 || RequestChangedOnce) && RequestChanges(spool,request_head)==1)
- TouchWebpageSpoolFile(Url,0);
- else
- mode=Spool;
- close(spool);
- }
- else if(mode==SpoolOrReal)
- {
- if(spool_exists)
- mode=Spool;
- else
- mode=Real;
- }
- /* Don't let htdig request any URLs. */
- is_client_htdig=GetHeader(request_head,"User-Agent","htdig/");
- if((mode==SpoolGet || mode==Real) && is_client_htdig)
- {
- PrintMessage(Inform,"URL unavailable to be searched.");
- HTMLMessageHead(tmpclient,404,"WWWOFFLE Not Searched",
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- /* mode = Spool, SpoolGet, SpoolWillGet, SpoolPragma, SpoolRefresh, Real, RealRefresh, RealNoCache or Fetch */
- /* Set up the file descriptor for the spool file. */
- if(mode==Real || mode==Fetch)
- {
- if(spool_exists)
- CreateBackupWebpageSpoolFile(Url);
- spool=OpenWebpageSpoolFile(0,Url);
- CreateLockWebpageSpoolFile(Url);
- if(spool==-1)
- {
- DeleteLockWebpageSpoolFile(Url);
- PrintMessage(Warning,"Cannot open the spooled web page to write.");
- if(mode==Real)
- {
- HTMLMessage(tmpclient,500,"WWWOFFLE Server Error",NULL,"ServerError",
- "error","Cannot open the spooled web page to write.",
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- else /* mode==Fetch */
- {
- if(client!=-1)
- write_formatted(client,"Internal Error %s [Cannot open spool file]n",Url->name);
- exit(1);
- }
- }
- lasttime_exists=CreateLastTimeSpoolFile(Url);
- }
- else if(mode==Spool || mode==SpoolPragma)
- {
- spool=OpenWebpageSpoolFile(1,Url);
- init_buffer(spool);
- if(spool==-1)
- {
- PrintMessage(Warning,"Cannot open the spooled web page to read.");
- HTMLMessage(tmpclient,500,"WWWOFFLE Server Error",NULL,"ServerError",
- "error","Cannot open the spooled web page to read.",
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- }
- /* Set up the outgoing file. */
- offline_request=!IsNotRequestedOffline(Url->proto,Url->host,Url->path,Url->args);
- is_client_wwwoffle=GetHeader(request_head,"Pragma","wwwoffle");
- if((offline_request || online) &&
- ((mode==SpoolGet && (!ConfirmRequests || is_client_wwwoffle || Url->local || (Url->args && *Url->args=='!'))) ||
- mode==SpoolRefresh ||
- mode==SpoolPragma))
- {
- outgoing=OpenOutgoingSpoolFile(0);
- if(outgoing==-1)
- {
- PrintMessage(Warning,"Cannot open the outgoing request to write.");
- HTMLMessage(tmpclient,500,"WWWOFFLE Server Error",NULL,"ServerError",
- "error","Cannot open the outgoing request to write.",
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- }
- /* Open the connection to the server host. */
- if(mode==Real || mode==RealNoCache || mode==Fetch)
- {
- char *err=(Url->Protocol->open)(Url);
- if(err && ConnectRetry)
- {
- PrintMessage(Inform,"Waiting to try connection again.");
- sleep(10);
- err=(Url->Protocol->open)(Url);
- }
- if(err)
- {
- if(mode==Fetch || mode==Real)
- {
- lseek(spool,0,SEEK_SET);
- ftruncate(spool,0);
- HTMLMessage(spool,503,"WWWOFFLE Remote Host Error",NULL,"RemoteHostError",
- "url",Url->name,
- "reason",err,
- "cache","yes",
- "backup",spool_exists?"yes":NULL,
- NULL);
- DeleteLockWebpageSpoolFile(Url);
- close(spool);
- }
- if(mode==Fetch)
- {
- if(client!=-1)
- write_formatted(client,"Fetch Failure %s [Server Connection Failed]n",Url->name);
- exit(1);
- }
- else
- {
- HTMLMessage(tmpclient,503,"WWWOFFLE Remote Host Error",NULL,"RemoteHostError",
- "url",Url->name,
- "reason",err,
- "cache","",
- "backup",spool_exists?"yes":NULL,
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- }
- }
- /* Modify the request header (Censor / Cannonicalise URL / POST/PUT / HTTP-1.1 etc). */
- if(mode==Real || mode==RealNoCache || mode==Fetch || mode==SpoolGet || mode==SpoolRefresh || mode==SpoolPragma)
- ModifyRequest(Url,request_head);
- /* Write request to remote server or outgoing file. */
- if(mode==Fetch && client!=-1)
- write_formatted(client,"Fetching %s ...n",Url->name);
- if(mode==Real || mode==RealNoCache || mode==Fetch)
- {
- char *err=(Url->Protocol->request)(Url,request_head,request_body);
- if(err)
- {
- if(mode==Real || mode==Fetch)
- {
- lseek(spool,0,SEEK_SET);
- ftruncate(spool,0);
- HTMLMessage(spool,503,"WWWOFFLE Remote Host Error",NULL,"RemoteHostError",
- "url",Url->name,
- "reason",err,
- "cache","yes",
- "backup",spool_exists?"yes":NULL,
- NULL);
- DeleteLockWebpageSpoolFile(Url);
- }
- if(mode==Real || mode==RealNoCache)
- {
- HTMLMessage(tmpclient,503,"WWWOFFLE Remote Host Error",NULL,"RemoteHostError",
- "url",Url->name,
- "reason",err,
- "cache",NULL,
- "backup",spool_exists?"yes":NULL,
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- else /* mode==Fetch */
- {
- if(client!=-1)
- write_formatted(client,"Fetch Failure %s [Server Connection Error]n",Url->name);
- exit(1);
- }
- }
- }
- else if((offline_request || online) &&
- ((mode==SpoolGet && (!ConfirmRequests || Url->local || (Url->args && *Url->args=='!'))) ||
- mode==SpoolRefresh ||
- mode==SpoolPragma))
- {
- char *head=HeaderString(request_head);
- int err=write_string(outgoing,head);
- if(err==-1)
- {
- PrintMessage(Warning,"Cannot write the outgoing request.");
- HTMLMessage(tmpclient,500,"WWWOFFLE Server Error",NULL,"ServerError",
- "error","Cannot write the outgoing request.",
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- if(request_body)
- write_data(outgoing,request_body->content,request_body->length);
- free(head);
- }
- /* Parse the reply */
- if(mode==Real || mode==RealNoCache || mode==Fetch)
- {
- reply_status=ParseReply(-1,Url,&reply_head);
- if(!reply_head)
- {
- PrintMessage(Warning,"Timed out reading the reply.");
- if(mode==Real || mode==Fetch)
- {
- lseek(spool,0,SEEK_SET);
- ftruncate(spool,0);
- HTMLMessage(spool,503,"WWWOFFLE Remote Host Error",NULL,"RemoteHostError",
- "url",Url->name,
- "reason","TimeoutReply",
- "cache","yes",
- "backup",spool_exists?"yes":NULL,
- NULL);
- DeleteLockWebpageSpoolFile(Url);
- }
- if(mode==Real || mode==RealNoCache)
- HTMLMessage(client,503,"WWWOFFLE Remote Host Error",NULL,"RemoteHostError",
- "url",Url->name,
- "reason","TimeoutReply",
- "cache",NULL,
- "backup",spool_exists?"yes":NULL,
- NULL);
- else if(mode==Fetch && client!=-1)
- write_formatted(client,"Fetch Failure %s [Server Reply Error]n",Url->name);
- exit(1);
- }
- if(DebugLevel==ExtraDebug)
- PrintMessage(ExtraDebug,"Incoming Reply Head (from server/proxy)n%s",HeaderString(reply_head));
- if(mode==Fetch && (reply_status==301 || reply_status==302))
- {
- char *new_url=MovedLocation(Url,reply_head);
- if(client!=-1)
- write_formatted(client,"Fetching More %s [Page Moved]n",Url->name);
- if(!new_url)
- PrintMessage(Warning,"Cannot parse the reply for the new location.");
- else
- fetch_again+=RecurseFetchRelocation(Url,new_url);
- }
- else if(reply_status==304)
- {
- PrintMessage(Inform,"Server page is not newer than the one in cache.");
- if(mode==Fetch || mode==Real)
- {
- close(spool);
- DeleteLockWebpageSpoolFile(Url);
- RestoreBackupWebpageSpoolFile(Url);
- if(!lasttime_exists)
- DeleteLastTimeSpoolFile(Url);
- }
- if(mode==Fetch)
- {
- if(client!=-1)
- write_formatted(client,"Not fetching %s [Page Unchanged]n",Url->name);
- if(fetch_again)
- {
- spool=OpenWebpageSpoolFile(1,Url);
- init_buffer(spool);
- if(ParseDocument(spool,Url))
- RecurseFetch(Url,1);
- close(spool);
- }
- exit(fetch_again?4:0);
- }
- else if(mode==Real)
- {
- spool=OpenWebpageSpoolFile(1,Url);
- init_buffer(spool);
- mode=Spool;
- }
- }
- else if(mode==Fetch && reply_status==401 && Urlpw)
- {
- mode=FetchNoPassword;
- if(client!=-1)
- write_formatted(client,"Fetching More %s [URL with password]n",Url->name);
- }
- else if(mode==Real && reply_status==401 && Urlpw)
- {
- mode=RealNoPassword;
- }
- }
- else
- reply_head=NULL;
- if(mode==Spool || mode==SpoolPragma)
- {
- reply_status=ParseReply(spool,Url,&reply_head);
- if(!reply_head)
- PrintMessage(Warning,"Spooled Reply Head (from cache) is empty.");
- else
- {
- char *head=HeaderString(reply_head);
- if(DebugLevel==ExtraDebug)
- PrintMessage(ExtraDebug,"Spooled Reply Head (from cache)n%s",head);
- free(head);
- }
- }
- reply_body=CreateBody(READ_BUFFER_SIZE);
- /* mode = Spool, SpoolGet, SpoolWillGet, SpoolPragma, SpoolRefresh, Real, RealRefresh, RealNoCache, RealNoPassword, Fetch or FetchNoPassword */
- /* Close the outgoing file if any. */
- if(outgoing>=0)
- {
- if(mode==Fetch)
- close(outgoing);
- if(mode==SpoolGet || mode==SpoolRefresh || mode==SpoolPragma)
- CloseOutgoingSpoolFile(outgoing,Url);
- }
- /* The main body of the handling of the data. */
- if(mode==Real || mode==RealNoCache || mode==RealNoPassword)
- {
- char *head;
- int n=0,err=0,bytes=0;
- ModifyReply(reply_head);
- head=HeaderString(reply_head);
- if(DebugLevel==ExtraDebug)
- PrintMessage(ExtraDebug,"Outgoing Reply Head (to browser)n%s",head);
- if(mode!=RealNoCache)
- write_string(spool,head);
- if(mode!=RealNoPassword)
- err=write_string(client,head);
- free(head);
- while(err!=-1 && (n=(Url->Protocol->readbody)(reply_body->content,READ_BUFFER_SIZE))>0)
- {
- bytes+=n;
- if(mode!=RealNoCache)
- write_data(spool,reply_body->content,n);
- if(mode!=RealNoPassword && !head_only)
- err=write_data(client,reply_body->content,n);
- if(err==-1)
- {
- char *length=GetHeader(reply_head,"Content-Length",NULL);
- if(length)
- {
- int size=atoi(length);
- if(size<(IntrDownloadSize<<10) || (100*(double)bytes/(double)size)>IntrDownloadPercent)
- err=0;
- head_only=1; /* cheat to stop writing to client */
- }
- }
- }
- if(mode!=RealNoCache)
- {
- if(err==-1 && !IntrDownloadKeep)
- {
- PrintMessage(Warning,"Error writing to client [%!s]; client disconnected?");
- lseek(spool,0,SEEK_SET);
- ftruncate(spool,0);
- HTMLMessage(spool,503,"WWWOFFLE Remote Host Error",NULL,"RemoteHostError",
- "url",Url->name,
- "reason","ClientClose",
- "cache","yes",
- "backup",spool_exists?"yes":NULL,
- NULL);
- }
- else if(n<0 && !TimeoutDownloadKeep)
- {
- PrintMessage(Warning,"Timed out while reading from remote host.");
- lseek(spool,0,SEEK_SET);
- ftruncate(spool,0);
- HTMLMessage(spool,503,"WWWOFFLE Remote Host Error",NULL,"RemoteHostError",
- "url",Url->name,
- "reason","TimeoutTransfer",
- "cache","yes",
- "backup",spool_exists?"yes":NULL,
- NULL);
- }
- else
- {
- if(n<0 || err==-1)
- {
- reply_head->status=503;
- head=HeaderString(reply_head);
- lseek(spool,0,SEEK_SET);
- write_string(spool,head);
- free(head);
- }
- if(spool_exists)
- DeleteBackupWebpageSpoolFile(Url);
- }
- DeleteLockWebpageSpoolFile(Url);
- }
- }
- else if(mode==Fetch || mode==FetchNoPassword)
- {
- char *head=HeaderString(reply_head);
- int n;
- write_string(spool,head);
- free(head);
- while((n=(Url->Protocol->readbody)(reply_body->content,READ_BUFFER_SIZE))>0)
- write_data(spool,reply_body->content,n);
- if(n<0 && !TimeoutDownloadKeep)
- {
- PrintMessage(Warning,"Timed out while reading from remote host.");
- lseek(spool,0,SEEK_SET);
- ftruncate(spool,0);
- HTMLMessage(spool,503,"WWWOFFLE Remote Host Error",NULL,"RemoteHostError",
- "url",Url->name,
- "reason","TimeoutTransfer",
- "cache","yes",
- "backup",spool_exists?"yes":NULL,
- NULL);
- if(client!=-1)
- write_formatted(client,"Fetch Failure %s [Timeout]n",Url->name);
- }
- else
- {
- if(spool_exists)
- DeleteBackupWebpageSpoolFile(Url);
- if(client!=-1)
- write_formatted(client,"Fetch Success %sn",Url->name);
- }
- DeleteLockWebpageSpoolFile(Url);
- if(n>=0 && reply_status>=200 && reply_status<400)
- {
- lseek(spool,0,SEEK_SET);
- init_buffer(spool);
- if(ParseDocument(spool,Url))
- {
- int links=RecurseFetch(Url,1);
- if(client!=-1 && links)
- write_formatted(client,"Fetching More %s [%d Extra URLs]n",Url->name,links);
- fetch_again+=links;
- }
- }
- }
- else if(mode==Spool || mode==SpoolPragma)
- {
- struct stat buf;
- char *remote_error_note="WWWOFFLE Remote Host Error";
- if(ExistsLockWebpageSpoolFile(Url))
- {
- int t=0;
- if(online)
- {
- t=SocketTimeout/6;
- PrintMessage(Inform,"Waiting for the page to be unlocked.");
- while(--t>0 && ExistsLockWebpageSpoolFile(Url))
- sleep(1);
- if(t<=0)
- PrintMessage(Inform,"Timed out waiting for the page to be unlocked.");
- }
- if(t<=0)
- {
- HTMLMessage(tmpclient,503,"WWWOFFLE File Locked",NULL,"FileLocked",
- "url",Url->name,
- NULL);
- mode=SpoolInternal; goto spoolinternal;
- }
- }
- if((reply_head && !strcmp(reply_head->note,remote_error_note)) || (!fstat(spool,&buf) && buf.st_size==0))
- {
- DeleteWebpageSpoolFile(Url,0);
- RestoreBackupWebpageSpoolFile(Url);
- }
- if(reply_head)
- {
- char *head=HeaderString(reply_head);
- write_string(tmpclient,head);
- free(head);
- }
- if(EnableHTMLModifications &&
- reply_status>=200 && reply_status<400 &&
- GetHeader(reply_head,"Content-Type","text/html") &&
- !is_client_wwwoffle &&
- !is_client_htdig)
- OutputHTMLWithModifications(tmpclient,spool,Url);
- else if(DisableAnimatedGIF &&
- reply_status>=200 && reply_status<400 &&
- GetHeader(reply_head,"Content-Type","image/gif") &&
- !is_client_wwwoffle &&
- !is_client_htdig)
- OutputGIFWithModifications(tmpclient,spool,Url);
- else
- {
- int n;
- while((n=read_data(spool,reply_body->content,READ_BUFFER_SIZE))>0)
- write_data(tmpclient,reply_body->content,n);
- }
- mode=SpoolInternal;
- }
- else if(mode==SpoolGet)
- {
- if((offline_request || online))
- {
- if(ConfirmRequests && !Url->local && (!Url->args || *Url->args!='!'))
- HTMLMessage(tmpclient,404,"WWWOFFLE Confirm Request",NULL,"ConfirmRequest",
- "url",Url->name,
- NULL);
- else if(fetch_again)
- HTMLMessage(tmpclient,404,"WWWOFFLE Refresh Will Get",NULL,"RefreshWillGet",
- "url",Url->name,
- "password",HashOutgoingSpoolFile(Url),
- NULL);
- else
- HTMLMessage(tmpclient,404,"WWWOFFLE Will Get",NULL,"WillGet",
- "already",NULL,
- "url",Url->name,
- "password",HashOutgoingSpoolFile(Url),
- NULL);
- }
- else
- HTMLMessage(tmpclient,404,"WWWOFFLE Refused Request",NULL,"RefusedRequest",
- "url",Url->name,
- NULL);
- mode=SpoolInternal;
- }
- else if(mode==SpoolWillGet)
- {
- HTMLMessage(tmpclient,404,"WWWOFFLE Will Get",NULL,"WillGet",
- "already","yes",
- "url",Url->name,
- "password",HashOutgoingSpoolFile(Url),
- NULL);
- mode=SpoolInternal;
- }
- else if(mode==RealRefresh || mode==SpoolRefresh)
- {
- HTMLMessage(tmpclient,301,"WWWOFFLE Refresh Redirect",Url->link,"RefreshRedirect",
- "url",Url->name,
- "link",Url->link,
- NULL);
- mode=SpoolInternal;
- }
- spoolinternal: /* Jump here if mode is SpoolInternal. */
- if(mode==SpoolInternal)
- {
- int n;
- unsigned long size;
- if(!reply_body)
- reply_body=CreateBody(READ_BUFFER_SIZE);
- size=lseek(tmpclient,0,SEEK_CUR);
- lseek(tmpclient,0,SEEK_SET);
- init_buffer(tmpclient);
- reply_status=ParseReply(tmpclient,Url,&reply_head);
- if(!reply_head)
- PrintMessage(Warning,"Outgoing Reply Head (to browser) is empty.");
- else
- {
- char *head,length[10];
- size-=reply_head->size;
- RemoveFromHeader(reply_head,"Content-Length",NULL);
- sprintf(length,"%ld",size);
- AddToHeader(reply_head,"Content-Length",length);
- ModifyReply(reply_head);
- head=HeaderString(reply_head);
- if(DebugLevel==ExtraDebug)
- PrintMessage(ExtraDebug,"Outgoing Reply Head (to browser)n%s",head);
- write_string(client,head);
- free(head);
- }
- if(!head_only)
- while((n=read_data(tmpclient,reply_body->content,READ_BUFFER_SIZE))>0)
- write_data(client,reply_body->content,n);
- }
- /* Close down and exit. */
- if((mode==Real || mode==RealNoPassword) && outgoing_exists)
- DeleteOutgoingSpoolFile(Url);
- if(mode==Real || mode==RealNoCache || mode==RealNoPassword ||
- mode==Fetch || mode==FetchNoPassword)
- (Url->Protocol->close)();
- if(tmpclient>=0)
- CloseTempSpoolFile(tmpclient);
- if(spool>=0)
- close(spool);
- if(mode==SpoolInternal && request_head && spool_exists && is_client_htdig)
- TouchWebpageSpoolFile(Url,spool_exists);
- if(reply_head)
- FreeHeader(reply_head);
- if(reply_body)
- FreeBody(reply_body);
- if(mode==RealNoPassword || mode==FetchNoPassword)
- {
- FreeURL(Url);Url=Urlpw;Urlpw=NULL;
- spool_exists=spool_exists_pw;spool_exists_pw=0;
- reply_head=NULL;
- reply_body=NULL;
- if(mode==RealNoPassword)
- mode=Real;
- else
- mode=Fetch;
- goto passwordagain;
- }
- if(request_head)
- FreeHeader(request_head);
- if(request_body)
- FreeBody(request_body);
- if(client>=0)
- CloseSocket(client);
- if(fetch_again)
- return(4);
- else
- return(0);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Make an SSL proxy connection.
- int ssl_tunnel Return 1 in case of failure.
- int client The client socket.
- URL *Url The URL to get (used for host only).
- Header *request_head The head of the request.
- ++++++++++++++++++++++++++++++++++++++*/
- static int ssl_tunnel(int client,URL *Url,Header *request_head)
- {
- char *err=SSL_Open(Url);
- if(err && ConnectRetry)
- {
- PrintMessage(Inform,"Waiting to try connection again.");
- sleep(10);
- err=SSL_Open(Url);
- }
- if(err)
- {
- HTMLMessage(client,503,"WWWOFFLE Remote Host Error",NULL,"RemoteHostError",
- "url",Url->host,
- "reason",err,
- "cache",NULL,
- "backup",NULL,
- NULL);
- return(1);
- }
- ModifyRequest(Url,request_head);
- err=SSL_Request(client,Url,request_head);
- if(err)
- {
- HTMLMessage(client,503,"WWWOFFLE Remote Host Error",NULL,"RemoteHostError",
- "url",Url->host,
- "reason",err,
- "cache",NULL,
- "backup",NULL,
- NULL);
- return(1);
- }
- else if(!SSLProxy)
- HTMLMessageHead(client,200,"WWWOFFLE SSL OK",
- "Content-Type",NULL,
- NULL);
- SSL_Transfer(client);
- SSL_Close();
- return(0);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Uninstall the signal handlers.
- ++++++++++++++++++++++++++++++++++++++*/
- static void uninstall_sighandlers(void)
- {
- struct sigaction action;
- /* SIGCHLD */
- action.sa_handler = SIG_DFL;
- sigemptyset (&action.sa_mask);
- action.sa_flags = 0;
- if(sigaction(SIGCHLD, &action, NULL) != 0)
- PrintMessage(Warning, "Cannot uninstall SIGCHLD handler.");
- /* SIGINT, SIGQUIT, SIGTERM */
- action.sa_handler = SIG_DFL;
- sigemptyset(&action.sa_mask);
- action.sa_flags = 0;
- if(sigaction(SIGINT, &action, NULL) != 0)
- PrintMessage(Warning, "Cannot uninstall SIGINT handler.");
- if(sigaction(SIGQUIT, &action, NULL) != 0)
- PrintMessage(Warning, "Cannot uninstall SIGQUIT handler.");
- if(sigaction(SIGTERM, &action, NULL) != 0)
- PrintMessage(Warning, "Cannot uninstall SIGTERM handler.");
- /* SIGHUP */
- action.sa_handler = SIG_DFL;
- sigemptyset(&action.sa_mask);
- action.sa_flags = 0;
- if(sigaction(SIGHUP, &action, NULL) != 0)
- PrintMessage(Warning, "Cannot uninstall SIGHUP handler.");
- /* SIGPIPE */
- action.sa_handler = SIG_IGN;
- sigemptyset (&action.sa_mask);
- action.sa_flags = 0;
- if(sigaction(SIGPIPE, &action, NULL) != 0)
- PrintMessage(Warning, "Cannot ignore SIGPIPE.");
- }