next up previous
Next: Bibliography Up: A. WEBeye Source Code Previous: A.43 vc-zoomer.setl

  
A.44 webutil.setl

Textually #included by:
vc-httpd.setl     (Section A.19 [vc-httpd.setl])
vc-push.setl     (Section A.34 [vc-push.setl])
vc-snap.setl     (Section A.41 [vc-snap.setl])

Source code: *

-- Read and parse a GET or POST command into a triple consisting of
-- a URI string, a protocol string (such as `HTTP/1.0' or `HTTP/1.1'),
-- and a MIME-header map:
--
proc get_request (fd);
  s := getline fd ? `';
  s(`^\r') := `'; s(`\r$') := `';  -- kill any \n\r or \r\n effects
  if #(t := split (s)) = 0 then return [ ]; end if;
  [cmduriprotocol] := t;
  if to_upper cmd notin {`GET', `POST'} then return [ ]; end if;
  uri ?:= `/';
  protocol ?:= `';
  mime_headers := {};
  if (to_upper protocol)(`^HTTP') /= om then
    -- Read more lines
    k := 0;
    loop doing
      s := getline fd ? `';
      s(`^\r') := `'; s(`\r$') := `';  -- kill \n\r or \r\n effects
    while #split (s) > 0 do
      h := break (s, `:');
      if s(`^:') /= om then
        s(`^:[ \t]*') := `';
        mime_headers with:= [hs];
        if to_lower h = `content-lengthand s(`^[0-9]') /= om then
          k := val s(`^[0-9]*');
        end if;
      end if;
    end loop;
    if k > 0 then
      content := getn (fdk) ? `';
      if #content /= k then
        printa (stderrmyname, `:',
               `expected', k, `bytes of content but got', #content);
      end if;
      uri +:= `?' + content;
    end if;
  end if;
  return [uriprotocolmime_headers];
end proc get_request;
 
-- Parse a URI into a map, such that `/', `?', and `&' are taken as
-- delimiters between map elements, and `.' and `=' are taken to
-- separate a key and associate within each map element.
--
-- The first delimited element is treated specially:  its key is
-- taken to be `cmd', and the whole element is the associate.
--
-- Also, any element consisting of a comma-separated pair of
-- unsigned integers is taken to be the associate of key `click'.
--
-- Otherwise, a missing associate is taken to be the null string.
--
-- In elements containing multiple separators, only the first is
-- recognized, and what remains is taken to be the associate.
--
op massage_uri (uri);
  if uri = om or uri = `' or uri = `/then
    return {};  -- null map, no command or parameters
  end if;
  if not is_string uri or uri(1) /= `/then
    return om;  -- I simply cannot respect this as a URI
  end if;
  r := {};
  uri(1) := `';
  r.cmd := sub (uri, `^[^/?&]*');
  r +:= {general_pair unescape p : p in split (uri, `[/?&]')};
  return r;
end op;
 
op general_pair (p);
  if #p = 0 then return omend if;
  if p(`^[0-9]+,[0-9]+$') /= om then
    return [`click', numericize p];
  end if;
  x := sub (p, `^[^=.]*');
  y := if #p > 0 then p(2..else `' end;
  return [xnumericize y];
end op;
 
op numericize (s);
  if s(`^[-+]?[0-9]+$') /= om then
    return val s;
  elseif s(`^[-+]?[0-9]*[.][0-9]*$') /= om then
    return val s;
  elseif `,in s then
    return [numericize x : x in split(s,`,')];
  else
    return s;
  end if;
end op;
 
op escape (x);  -- convert certain characters to %HH (hex)
  return `' +/ [if c in `~`!@#$%^&*()+=[]{};:\'"<>?\\|then `%' + hex c
              else c end : c in x];
end op;
 
op escape_map (f);  -- escape a SETL map for Web transmission
  r := `' +/ [`&' + x + `=' + escape y : y = f(x)];
  if #r > 0 then r(1) := `'; end if;
  gsub (r, ` ', `+');
  return r;
end op;
 
op unescape (x);  -- convert %HH hex escapes to normal chars
  r := `';
  while #x > 2 loop
    if x(1) = `%and x(2..3)(`[0-9a-fA-F][0-9a-fA-F]') /= om then
      r +:= unhex x(2..3);
      x(1..3) := `';
    else
      r +:= len (x, 1);
    end if;
  end loop;
  r +:= x;
  return r;
end op;
 
op unescape_map (s);  -- convert Web form-type spam to a SETL map
  gsub (s, `\\+', ` ');  -- change plusses to blanks
  r := {pair unescape x : x in split (s, `\\&')};  -- decode
end op;
 
op pair (x);
  s := break (x, `=');  -- s := part of x before `=' or all of xx := x(`='..) or `'
  return [sif #x > 0 then x(2..else `' end];
end op;


next up previous
Next: Bibliography Up: A. WEBeye Source Code Previous: A.43 vc-zoomer.setl
David Bacon
1999-12-10