refresh.c
上传用户:seven77cht
上传日期:2007-01-04
资源大小:486k
文件大小:15k
- /***************************************
- $Header: /home/amb/wwwoffle/RCS/refresh.c 2.50 1999/09/11 14:00:04 amb Exp $
- WWWOFFLE - World Wide Web Offline Explorer - Version 2.5.
- The HTML interactive page to refresh a URL.
- ******************/ /******************
- Written by Andrew M. Bishop
- This file Copyright 1997,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 <unistd.h>
- #include "wwwoffle.h"
- #include "document.h"
- #include "misc.h"
- #include "config.h"
- #include "sockets.h"
- #include "errors.h"
- /*+ The options for recursive or normal fetching. +*/
- static int recursive=0;
- static int recursive_depth=0,recursive_mode=0,force=0;
- static int stylesheets=0,images=0,frames=0,scripts=0,objects=0;
- static char *RefreshFormParse(int fd,Body *request_body);
- static int request_url(URL *Url,char *refresh,URL *refUrl);
- /*++++++++++++++++++++++++++++++++++++++
- Send to the client a page to allow refreshes using HTML.
- char *RefreshPage Returns a modified URLs for a simple refresh.
- int fd The file descriptor of the client.
- URL *Url The URL that was used to request this page.
- Body *request_body The HTTP request body sent by the browser.
- int *recurse Return value set to true if a recursive fetch was asked for.
- ++++++++++++++++++++++++++++++++++++++*/
- char *RefreshPage(int fd,URL *Url,Body *request_body,int *recurse)
- {
- char *newurl=NULL;
- if(!strcmp("/refresh-options/",Url->path))
- HTMLMessage(fd,200,"WWWOFFLE Refresh Form",NULL,"RefreshPage",
- "url",Url->args,
- "stylesheets",FetchStyleSheets?"yes":NULL,
- "images",FetchImages?"yes":NULL,
- "frames",FetchFrames?"yes":NULL,
- "scripts",FetchScripts?"yes":NULL,
- "objects",FetchObjects?"yes":NULL,
- NULL);
- else if(!strcmp("/refresh-request/",Url->path))
- {
- if((newurl=RefreshFormParse(fd,request_body)))
- *recurse=1;
- }
- else if(!strcmp("/refresh/",Url->path))
- {
- newurl=(char*)malloc(strlen(Url->args)+1);
- strcpy(newurl,Url->args);
- }
- else
- {
- newurl=(char*)malloc(strlen(Url->args)+1);
- strcpy(newurl,Url->args);
- *recurse=1;
- }
- if(*recurse)
- ParseRecurseOptions(Url->path+8);
- return(newurl);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Parse the reply from the form.
- char *RefreshFormParse Returns the first URL to get.
- int fd The file descriptor of the client.
- Body *request_body The body of the HTTP request sent by the browser.
- ++++++++++++++++++++++++++++++++++++++*/
- static char *RefreshFormParse(int fd,Body *request_body)
- {
- int i;
- char *copy,*url=NULL,*method=NULL,*force="";
- char *stylesheets="",*images="",*frames="",*scripts="",*objects="";
- URL *Url;
- char *new_url;
- if(!request_body)
- {
- HTMLMessage(fd,404,"WWWOFFLE Refresh Form Error",NULL,"RefreshFormError",
- "body",NULL,
- NULL);
- return(NULL);
- }
- copy=(char*)malloc(request_body->length+1);
- strcpy(copy,request_body->content);
- for(i=0;copy[i];i++)
- {
- if(i!=0 && copy[i-1]=='&')
- copy[i-1]=0;
- if(i==0 || copy[i-1]==0)
- {
- if(!strncmp("method=",©[i],7))
- method=©[i+7];
- if(!strncmp("force=",©[i],6))
- force=©[i+6];
- if(!strncmp("stylesheets=",©[i],12))
- stylesheets=©[i+12];
- if(!strncmp("images=",©[i],7))
- images=©[i+7];
- if(!strncmp("frames=",©[i],7))
- frames=©[i+7];
- if(!strncmp("scripts=",©[i],8))
- scripts=©[i+8];
- if(!strncmp("objects=",©[i],8))
- objects=©[i+8];
- if(!strncmp("url=",©[i],4))
- url=©[i+4];
- }
- }
- if(url==NULL || *url==0 || method==NULL || *method==0)
- {
- HTMLMessage(fd,404,"WWWOFFLE Refresh Form Error",NULL,"RefreshFormError",
- "body",request_body->content,
- NULL);
- free(copy);
- return(NULL);
- }
- url=URLDecode(url,1);
- Url=SplitURL(url);
- new_url=(char*)malloc(request_body->length+64);
- strcpy(new_url,"/refresh");
- strcat(new_url,method);
- strcat(new_url,force);
- strcat(new_url,stylesheets);
- strcat(new_url,images);
- strcat(new_url,frames);
- strcat(new_url,scripts);
- strcat(new_url,objects);
- strcat(new_url,"/?");
- strcat(new_url,Url->file);
- FreeURL(Url);
- free(copy);
- return(new_url);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Parse the url method to decide what needs fetching recursively.
- char *method The method to use, encoding the depth and other options.
- ++++++++++++++++++++++++++++++++++++++*/
- void ParseRecurseOptions(char *method)
- {
- if(method)
- {
- char *copy=(char*)malloc(strlen(method)+1),*dash,*slash;
- strcpy(copy,method);
- if((slash=strchr(copy,'/')))
- *slash=0;
- PrintMessage(Debug,"Refresh method='%s'.",copy);
- if(*copy=='-')
- copy++;
- do
- {
- if((dash=strchr(copy,'-')))
- *dash=0;
- if(!strcmp(copy,"refresh"))
- ;
- else if(!strcmp(copy,"none"))
- ;
- else if(!strcmp(copy,"dir"))
- recursive_mode=1;
- else if(!strcmp(copy,"host"))
- recursive_mode=2;
- else if(!strcmp(copy,"any"))
- recursive_mode=3;
- else if(!strcmp(copy,"force"))
- force=1;
- else if(!strcmp(copy,"stylesheets"))
- stylesheets=1;
- else if(!strcmp(copy,"images"))
- images=1;
- else if(!strcmp(copy,"frames"))
- frames=1;
- else if(!strcmp(copy,"scripts"))
- scripts=1;
- else if(!strcmp(copy,"objects"))
- objects=1;
- else if(atoi(copy))
- recursive_depth=atoi(copy);
- copy=dash+1;
- }
- while(dash);
- recursive=1;
- }
- else
- {
- stylesheets=FetchStyleSheets;
- images=FetchImages;
- frames=FetchFrames;
- scripts=FetchScripts;
- objects=FetchObjects;
- }
- }
- /*++++++++++++++++++++++++++++++++++++++
- Replies with whether the page is to be forced to refresh.
- int RefreshForced Returns the force flag.
- ++++++++++++++++++++++++++++++++++++++*/
- int RefreshForced(void)
- {
- return(force);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Fetch the images, etc from the just parsed page.
- int RecurseFetch Returns 1 if there are more to be fetched.
- URL *Url The URL that was fetched.
- int new Set to true if the page is new to the cache, else we may be in infinite recursion.
- ++++++++++++++++++++++++++++++++++++++*/
- int RecurseFetch(URL *Url,int new)
- {
- char **list,*metarefresh;
- int more=0;
- int j;
- /* A Meta-Refesh header. */
- if(new && (metarefresh=MetaRefresh()))
- {
- URL *metarefreshUrl=SplitURL(metarefresh);
- if(!metarefreshUrl->local && metarefreshUrl->Protocol)
- {
- char *refresh=NULL;
- if(recursive)
- refresh=CreateRefreshPath(recursive_depth,recursive_mode,force,
- stylesheets,images,frames,scripts,objects);
- PrintMessage(Debug,"Meta-Refresh=%s",metarefreshUrl->name);
- more+=request_url(metarefreshUrl,refresh,Url);
- }
- FreeURL(metarefreshUrl);
- }
- /* Any style sheets. */
- if(stylesheets && (list=GetReferences(RefStyleSheet)))
- for(j=0;list[j];j++)
- {
- URL *stylesheetUrl=SplitURL(list[j]);
- if(!stylesheetUrl->local && stylesheetUrl->Protocol)
- {
- PrintMessage(Debug,"Style-Sheet=%s",stylesheetUrl->name);
- more+=request_url(stylesheetUrl,NULL,Url);
- }
- FreeURL(stylesheetUrl);
- }
- /* Any images. */
- if(images && (list=GetReferences(RefImage)))
- for(j=0;list[j];j++)
- {
- URL *imageUrl=SplitURL(list[j]);
- if(!imageUrl->local && imageUrl->Protocol)
- {
- PrintMessage(Debug,"Image=%s",imageUrl->name);
- more+=request_url(imageUrl,NULL,Url);
- }
- FreeURL(imageUrl);
- }
- /* Any frames */
- if(new && frames && (list=GetReferences(RefFrame)))
- for(j=0;list[j];j++)
- {
- URL *frameUrl=SplitURL(list[j]);
- if(!frameUrl->local && frameUrl->Protocol)
- {
- char *refresh=NULL;
- if(recursive)
- refresh=CreateRefreshPath(recursive_depth,recursive_mode,force,
- stylesheets,images,frames,scripts,objects);
- PrintMessage(Debug,"Frame=%s",frameUrl->name);
- more+=request_url(frameUrl,refresh,Url);
- }
- FreeURL(frameUrl);
- }
- /* Any scripts. */
- if(scripts && (list=GetReferences(RefScript)))
- for(j=0;list[j];j++)
- {
- URL *scriptUrl=SplitURL(list[j]);
- if(!scriptUrl->local && scriptUrl->Protocol)
- {
- PrintMessage(Debug,"Script=%s",scriptUrl->name);
- more+=request_url(scriptUrl,NULL,Url);
- }
- FreeURL(scriptUrl);
- }
- /* Any Objects. */
- if(objects && (list=GetReferences(RefObject)))
- for(j=0;list[j];j++)
- {
- URL *objectUrl=SplitURL(list[j]);
- if(!objectUrl->local && objectUrl->Protocol)
- {
- PrintMessage(Debug,"Object=%s",objectUrl->name);
- more+=request_url(objectUrl,NULL,Url);
- }
- FreeURL(objectUrl);
- }
- if(new && objects && (list=GetReferences(RefInlineObject)))
- for(j=0;list[j];j++)
- {
- URL *objectUrl=SplitURL(list[j]);
- if(!objectUrl->local && objectUrl->Protocol)
- {
- char *refresh=CreateRefreshPath(recursive_depth,recursive_mode,
- force,stylesheets,images,frames,scripts,objects);
- PrintMessage(Debug,"InlineObject=%s",objectUrl->name);
- more+=request_url(objectUrl,refresh,Url);
- }
- FreeURL(objectUrl);
- }
- /* Any links */
- if(recursive_depth && (list=GetReferences(RefLink)))
- for(j=0;list[j];j++)
- {
- URL *linkUrl=SplitURL(list[j]);
- if(!linkUrl->local && linkUrl->Protocol)
- {
- int get=1;
- if(recursive_mode!=3)
- {
- if(strcmp(Url->host,linkUrl->host))
- get=0;
- else
- if(recursive_mode!=2)
- {
- char *end=Url->path+strlen(Url->path);
- while(end>Url->path)
- if(*end=='/')
- break;
- else
- end--;
- if(*end)
- *++end=0;
- if(end!=Url->path && strncmp(Url->path,linkUrl->path,end-Url->path))
- get=0;
- }
- }
- if(get)
- {
- char *refresh=CreateRefreshPath(recursive_depth-1,recursive_mode,force,
- stylesheets,images,frames,scripts,objects);
- PrintMessage(Debug,"Link=%s",linkUrl->name);
- more+=request_url(linkUrl,refresh,Url);
- }
- }
- FreeURL(linkUrl);
- }
- return(more);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Fetch the relocated page.
- int RecurseFetchRelocation Returns 1 if there are more to be fetched.
- URL *Url The URL that was fetched.
- char *location The new location of the URL.
- ++++++++++++++++++++++++++++++++++++++*/
- int RecurseFetchRelocation(URL *Url,char *location)
- {
- int more=0;
- URL *locationUrl=SplitURL(location);
- if(!locationUrl->local && locationUrl->Protocol)
- {
- char *refresh=NULL;
- int get=1;
- if(recursive)
- {
- if(recursive_mode!=3)
- {
- if(strcmp(Url->host,locationUrl->host))
- get=0;
- else
- if(recursive_mode!=2)
- {
- char *end=Url->path+strlen(Url->path);
- while(end>Url->path)
- if(*end=='/')
- break;
- else
- end--;
- if(*end)
- *++end=0;
- if(end!=Url->path && strncmp(Url->path,locationUrl->path,end-Url->path))
- get=0;
- }
- }
- if(get)
- refresh=CreateRefreshPath(recursive_depth,recursive_mode,force,
- stylesheets,images,frames,scripts,objects);
- }
- if(get)
- {
- PrintMessage(Debug,"Location=%s",locationUrl->name);
- more+=request_url(locationUrl,refresh,Url);
- }
- }
- return(more);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Make a request for a URL.
- int request_url Returns 1 on success, else 0.
- URL *Url The URL that was asked for.
- char *refresh The URL path that is required for refresh information.
- URL *refUrl The refering URL.
- ++++++++++++++++++++++++++++++++++++++*/
- static int request_url(URL *Url,char *refresh,URL *refUrl)
- {
- int retval=0;
- if(recursive && IsNotGotRecursive(Url->proto,Url->host,Url->path,Url->args))
- PrintMessage(Inform,"The server '%s://%s' and/or path '%s' is on the list not to get recursively.",Url->proto,Url->host,Url->path);
- else if(IsNotGot(Url->proto,Url->host,Url->path,Url->args))
- PrintMessage(Inform,"The server '%s://%s' and/or path '%s' is on the list not to get.",Url->proto,Url->host,Url->path);
- else
- {
- int new_outgoing=OpenOutgoingSpoolFile(0);
- if(new_outgoing==-1)
- PrintMessage(Warning,"Cannot open the new outgoing request to write.");
- else
- {
- URL *reqUrl;
- Header *new_request_head;
- char *head;
- if(refUrl->pass && !strcmp(refUrl->host,Url->host))
- AddURLPassword(Url,refUrl->user,refUrl->pass);
- if(refresh)
- {
- char *url=(char*)malloc(strlen(Url->file)+strlen(refresh)+4);
- strcpy(url,refresh);
- strcat(url,"/?");
- strcat(url,Url->file);
- reqUrl=SplitURL(url);
- free(url);
- }
- else
- reqUrl=Url;
- new_request_head=RequestURL(reqUrl,refUrl->name);
- if(force)
- AddToHeader(new_request_head,"Pragma","no-cache");
- head=HeaderString(new_request_head);
- write_string(new_outgoing,head);
- CloseOutgoingSpoolFile(new_outgoing,reqUrl);
- retval=1;
- if(reqUrl!=Url)
- free(reqUrl);
- free(head);
- FreeHeader(new_request_head);
- }
- }
- return(retval);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Create a Path for doing a refresh with options.
- char *CreateRefreshPath Returns a pointer to a static string.
- ++++++++++++++++++++++++++++++++++++++*/
- char *CreateRefreshPath(int recursive_depth,int recursive_mode,int force,
- int stylesheets,int images,int frames,int scripts,int objects)
- {
- static char refresh[64];
- strcpy(refresh,"/refresh");
- if(recursive_depth)
- {
- if(recursive_mode==1)
- strcat(refresh,"-dir");
- else if(recursive_mode==2)
- strcat(refresh,"-host");
- else /* recursive_mode==3 */
- strcat(refresh,"-any");
- sprintf(&refresh[strlen(refresh)],"-%d",recursive_depth);
- }
- if(force)
- strcat(refresh,"-force");
- if(stylesheets)
- strcat(refresh,"-stylesheets");
- if(images)
- strcat(refresh,"-images");
- if(frames)
- strcat(refresh,"-frames");
- if(scripts)
- strcat(refresh,"-scripts");
- if(objects)
- strcat(refresh,"-objects");
- if(!recursive_depth && !force && !stylesheets && !images && !frames && !scripts && !objects)
- strcat(refresh,"-none");
- return(refresh);
- }