Meta 8.94 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/* 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                                 */
17 18 19
/*                                                 */
/* Purpose: Handling META tags.                    */
/*                                                 */
20
/* Author : A.D.Hodgkinson                         */
21 22
/*                                                 */
/* History: 25-Jul-97: Created.                    */
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
/***************************************************/

#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"
44
#include "URLutils.h"
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79

#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 */

80 81 82 83
  name    = HtmlMETAname      (t);
  equiv   = HtmlMETAhttp_equiv(t);
  content = HtmlMETAcontent   (t);
  scheme  = HtmlMETAscheme    (t);
84 85 86 87 88 89 90 91

  /* 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                       */

92
    if (choices.client_pull)
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
    {
      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 */

123 124
  separator = strchr(content, ';');
  if (!separator) separator = strchr(content, ',');
125 126 127 128 129 130 131 132 133 134 135 136

  /* If we found a separator, skip white space */

  if (separator)
  {
    separator ++;

    while (*separator && *separator < 33) separator++;

    if (!*separator) separator = NULL;
    else
    {
137
      int success = 0;
138

139 140 141 142 143 144 145
      /* 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)
146 147 148
      {
        char * oldsep = separator;

149
        separator += success;
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191

        /* 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;

192
    b->meta_refresh_at = -atoi(content); /* Mark this as 'pending' with a value <= 0 */
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217

    /* 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;

218 219 220 221 222 223
  /* Nothing to do if we're still fetching */

  if (handle->anim_handler) return 0;

  /* Otherwise, check the current time */

224 225 226 227 228
  _swix(OS_ReadMonotonicTime,
        _OUT(0),

        &time_now);

229 230 231 232 233 234 235 236 237
  /* 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) */
  }

238 239 240 241 242 243 244 245 246
  /* 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;

247 248 249 250 251 252 253
  /* 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.                                                  */

254 255 256 257 258 259 260
  if (
       browser_current_url(handle) &&
       !urlutils_urlsscmp(handle->meta_refresh_url,
                          browser_current_url(handle))
     )
     handle->reloading = 1;

261 262
  ChkError(fetchpage_new(handle,
                         handle->meta_refresh_url,
263 264
                         1,
                         0));
265 266 267 268 269

  handle->meta_refresh_url = NULL;

  return 0;
}
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294

/*************************************************/
/* 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;
  }
}