/* Copyright 1997 Acorn Computers Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /***************************************************/ /* File : Meta.c */ /* */ /* Purpose: Handling META tags. */ /* */ /* Author : A.D.Hodgkinson */ /* */ /* History: 25-Jul-97: Created. */ /***************************************************/ #include <stdlib.h> #include <stdio.h> #include <string.h> #include "swis.h" #include "flex.h" #include "HTMLLib.h" /* HTML library API, Which will include html2_ext.h, tags.h and struct.h */ #include "wimp.h" #include "wimplib.h" #include "event.h" #include "svcprint.h" #include "Global.h" #include "Utils.h" #include "Browser.h" #include "FetchPage.h" #include "URLutils.h" #include "Meta.h" /* Static function prototypes */ static _kernel_oserror * meta_process_refresh(browser_data * b, HStream * t, const char * content); /*************************************************/ /* meta_process_tag() */ /* */ /* In HTML, META tags can contain a great */ /* variety of information (so much so that this */ /* source file is entirely dedicated to them). */ /* This function is the entry point for dealing */ /* with a new META tag. */ /* */ /* Parameters: Pointer to a browser_data struct */ /* relevant to the token stream */ /* holding the META tag; */ /* */ /* Pointer to the token representing */ /* the META tag. */ /*************************************************/ _kernel_oserror * meta_process_tag(browser_data * b, HStream * t) { const char * name; const char * equiv; const char * content; const char * scheme; if (!t || !b) return NULL; /* Extract information from the token */ name = HtmlMETAname (t); equiv = HtmlMETAhttp_equiv(t); content = HtmlMETAcontent (t); scheme = HtmlMETAscheme (t); /* Work out what to do */ if (!utils_strcasecmp(equiv, "refresh")) { /* Refresh - load a new page or reload the current page */ /* after a certain amount of time */ if (choices.client_pull) { return meta_process_refresh(b, t, content); } } return NULL; } /*************************************************/ /* meta_process_refresh() */ /* */ /* Handles META tags specify that a page */ /* refresh (reload) should occur at some time. */ /* */ /* Parameters: Pointer to a browser_data struct */ /* relevant to the META tag; */ /* */ /* The content string for the tag. */ /*************************************************/ static _kernel_oserror * meta_process_refresh(browser_data * b, HStream * t, const char * content) { _kernel_oserror * e; char * separator; int time_now; if (!content || !b) return NULL; /* See if there's any URL specified - else it's the current page that is to be refetched */ separator = strchr(content, ';'); if (!separator) separator = strchr(content, ','); /* If we found a separator, skip white space */ if (separator) { separator ++; while (*separator && *separator < 33) separator++; if (!*separator) separator = NULL; else { int success = 0; /* May have a 'url=' before the actual URL, */ /* or 'name=' in some broken examples... */ if (!utils_strncasecmp(separator, "url", 3)) success = 3; else if (!utils_strncasecmp(separator, "name", 4)) success = 4; if (success) { char * oldsep = separator; separator += success; /* Skip any white space */ while (*separator && *separator < 33) separator++; /* Should be at an '='; if not, sssume 'url' was the URL to fetch! */ if (*separator != '=') separator = oldsep; else { /* Skip the '=' and any more white space */ separator ++; while (*separator && *separator < 33) separator++; /* Should be at the URL now, but make sure... */ if (!*separator) separator = NULL; } } } } /* Work out the URL to fetch */ b->meta_refresh_url = HtmlRelativiseURL(browser_current_url(b), separator ? separator : "", t); /* Only proceed if HtmlRelativiseURL didn't fail */ if (b->meta_refresh_url) { /* Work out what time to fetch at */ e = _swix(OS_ReadMonotonicTime, _OUT(0), &time_now); if (e) return e; b->meta_refresh_at = -atoi(content); /* Mark this as 'pending' with a value <= 0 */ /* Install the handler */ register_null_claimant(Wimp_ENull, (WimpEventHandler *) meta_check_refresh, b); } return NULL; } /*************************************************/ /* meta_check_refresh() */ /* */ /* After a META tag specifying a page (re)load */ /* (refresh) has been processed, this null */ /* handler will initiate the appropriate fetch */ /* after the appropriate delay. */ /* */ /* Paramters are as standard for a Wimp event */ /* handler. */ /*************************************************/ int meta_check_refresh(int eventcode, WimpPollBlock * b, IdBlock * idb, browser_data * handle) { int time_now; /* Nothing to do if we're still fetching */ if (handle->anim_handler) return 0; /* Otherwise, check the current time */ _swix(OS_ReadMonotonicTime, _OUT(0), &time_now); /* If we've stopped fetching, change the refresh field from */ /* <= 0 to show 'pending' to an actual time when the new */ /* fetch should start. */ if (handle->meta_refresh_at <= 0) { handle->meta_refresh_at = (100 * -handle->meta_refresh_at) + time_now; /* ('* 100' for seconds -> centiseconds) */ } /* Exit if we haven't reached the fetch time */ if (time_now < handle->meta_refresh_at) return 0; /* Otherwise, deregister this handler and start the fetch */ deregister_null_claimant(Wimp_ENull, (WimpEventHandler *) meta_check_refresh, handle); handle->meta_refresh_at = 0; /* If we're on the same page, force an uncached fetch - NB, if */ /* you don't set reloading you'll need to modify the top of */ /* fetchpage_preprocessed where it deals with checking for a */ /* fragment (jump to a named anchor). Otherwise client pull on */ /* sites such as http://jupiter.beseen.com/chat/rooms/g/1678/ */ /* will fail. */ if ( browser_current_url(handle) && !urlutils_urlsscmp(handle->meta_refresh_url, browser_current_url(handle)) ) handle->reloading = 1; ChkError(fetchpage_new(handle, handle->meta_refresh_url, 1, 0)); handle->meta_refresh_url = NULL; return 0; } /*************************************************/ /* meta_cancel_refresh() */ /* */ /* Cancels any registered null handler to deal */ /* with client pull (through */ /* META HTTP-EQUIV="Refresh"). */ /* */ /* Does not clear the browser-local 'client */ /* pull' flag. */ /* */ /* Parameters: Pointer to a browser_data struct */ /* relevant to the handler. */ /*************************************************/ void meta_cancel_refresh(browser_data * b) { if (b->meta_refresh_url && b->meta_refresh_at) { deregister_null_claimant(Wimp_ENull, (WimpEventHandler *) meta_check_refresh, b); b->meta_refresh_at = 0; b->meta_refresh_url = NULL; } }