--
--	httplib.occ -- an occam HTTP library
--	Copyright (C) 2000 Fred Barnes <frmb2@ukc.ac.uk>
--
--	This program is free software; you can redistribute it and/or modify
--	it under the terms of the GNU General Public License as published by
--	the Free Software Foundation; either version 2 of the License, or
--	(at your option) any later version.
--
--	This program is distributed in the hope that it will be useful,
--	but WITHOUT ANY WARRANTY; without even the implied warranty of
--	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--	GNU General Public License for more details.
--
--	You should have received a copy of the GNU General Public License
--	along with this program; if not, write to the Free Software
--	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
--

#INCLUDE "socklib.inc"
#USE "sock.lib"
#INCLUDE "httplib.inc"
#INCLUDE "filelib.inc"
#USE "file.lib"


PROC http.process (CHAN OF HTTP.PROTO in, SOCKET out)
  INITIAL BOOL running IS TRUE:
  INT res:
  [512]BYTE text.buffer:
  INT text.len:
  WHILE running
    in ? CASE
      --{{{  header related stuff
      init.ok
        socket.fullwrite (out, "HTTP/1.0 200 OK*c*n", res)
      init.redirect
        socket.fullwrite (out, "HTTP/1.0 302 OK*c*n", res)
      redirect.to; text.len::text.buffer
        SEQ
          socket.fullwrite (out, "Status: 302*c*n", res)
          socket.fullwrite (out, "Location: ", res)
          socket.fullwrite (out, [text.buffer FOR text.len], res)
          socket.fullwrite (out, "*c*n", res)
      content.type; text.len::text.buffer
        SEQ
          socket.fullwrite (out, "Content-Type: ", res)
          socket.fullwrite (out, [text.buffer FOR text.len], res)
          socket.fullwrite (out, "*c*n", res)
      end.headers
        socket.fullwrite (out, "*c*n", res)
      --}}}  
      --{{{  section marking stuff
      begin.html
        socket.fullwrite (out, "<HTML>*c*n", res)
      end.html
        socket.fullwrite (out, "</HTML>*c*n", res)
      begin.head
        socket.fullwrite (out, "<HEAD>*c*n", res)
      title; text.len::[text.buffer FROM 7]
        SEQ
          [text.buffer FOR 7] := "<TITLE>"
          [text.buffer FROM (text.len + 7) FOR 10] := "</TITLE>*c*n"
          text.len := (text.len + 17)
          socket.fullwrite (out, [text.buffer FOR text.len], res)
      refresh; text.len::[text.buffer FROM 34]
        SEQ
          -- <META HTTP-EQUIV=REFRESH CONTENT="30;URL=http://'$XSERVER_NAME'/'$XSCRIPT_NAME'?disconnect">
          [text.buffer FOR 34] := "<META HTTP-EQUIV=REFRESH CONTENT=*""
          [text.buffer FROM (text.len + 34) FOR 4] := "*">*c*n"
          text.len := (text.len + 38)
          socket.fullwrite (out, [text.buffer FOR text.len], res)
      end.head
        socket.fullwrite (out, "</HEAD>*c*n", res)
      begin.body
        socket.fullwrite (out, "<BODY>*c*n", res)
      begin.body.params; text.len::[text.buffer FROM 6]
        SEQ
          [text.buffer FOR 6] := "<BODY "
          [text.buffer FROM (text.len + 6) FOR 3] := ">*c*n"
          text.len := (text.len + 9)
          socket.fullwrite (out, [text.buffer FOR text.len], res)
      end.body
        socket.fullwrite (out, "</BODY>*c*n", res)
      begin.pre
        socket.fullwrite (out, "<PRE>*c*n", res)
      end.pre
        socket.fullwrite (out, "</PRE>*c*n", res)
      begin.tag; text.len::[text.buffer FROM 1]
        SEQ
          text.buffer[0] := '<'
          [text.buffer FROM (text.len + 1) FOR 3] := ">*c*n"
          text.len := (text.len + 4)
          socket.fullwrite (out, [text.buffer FOR text.len], res)
      end.tag; text.len::[text.buffer FROM 2]
        SEQ
          [text.buffer FOR 2] := "</"
          [text.buffer FROM (text.len+2) FOR 3] := ">*c*n"
          text.len := (text.len + 5)
          socket.fullwrite (out, [text.buffer FOR text.len], res)
      strong; text.len::[text.buffer FROM 8]
        SEQ
          [text.buffer FOR 8] := "<STRONG>"
          [text.buffer FROM (text.len + 8) FOR 11] := "</STRONG>*c*n"
          text.len := (text.len + 19)
          socket.fullwrite (out, [text.buffer FOR text.len], res)
      par
        socket.fullwrite (out, "<P>*c*n", res)
      INT style:
      INT start.at:
      html; style; text.len::[text.buffer FROM 4]
        SEQ
          start.at := 0
          CASE style
            HTML.NONE
              start.at := 4
            HTML.H1
              SEQ
                [text.buffer FOR 4] := "<H1>"
                [text.buffer FROM (text.len + 4) FOR 7] := "</H1>*c*n"
                text.len := (text.len + 11)
            HTML.H2
              SEQ
                [text.buffer FOR 4] := "<H2>"
                [text.buffer FROM (text.len + 4) FOR 7] := "</H2>*c*n"
                text.len := (text.len + 11)
            HTML.H3
              SEQ
                [text.buffer FOR 4] := "<H3>"
                [text.buffer FROM (text.len + 4) FOR 7] := "</H3>*c*n"
                text.len := (text.len + 11)
            HTML.H4
              SEQ
                [text.buffer FOR 4] := "<H4>"
                [text.buffer FROM (text.len + 4) FOR 7] := "</H4>*c*n"
                text.len := (text.len + 11)
            HTML.TT
              SEQ
                [text.buffer FOR 4] := "<TT>"
                [text.buffer FROM (text.len + 4) FOR 7] := "</TT>*c*n"
                text.len := (text.len + 11)
          socket.fullwrite (out, [text.buffer FROM start.at FOR text.len], res)
      line.break
        socket.fullwrite (out, "<BR>*c*n", res)
      sendfile; text.len::text.buffer
        INT fd, bytes:
        SEQ
          file.size ([text.buffer FOR text.len], bytes)
          file.open ([text.buffer FOR text.len], O.RDONLY, fd)
          IF
            (fd < 0) OR (bytes < 0)
              socket.fullwrite (out, "httplib error: sendfile file does not exist!*c*n", res)
            TRUE
              INITIAL INT offset IS 0:
              SEQ
                file.sendfile (fd, out[fd], bytes, offset, res)
                IF
                  res <> bytes
                    socket.fullwrite (out, "httplib error: may not have sendfile()*'d it all..*c*n", res)
                  TRUE
                    SKIP
                file.close (fd, res)
                IF
                  res <> 0
                    socket.fullwrite (out, "httplib error: close failed*c*n", res)
                  TRUE
                    SKIP

      --}}}  
      --{{{  finishing stuff
      finish
        SEQ
          socket.fullwrite (out, "*c*n", res)
          running := FALSE
      --}}}  
:


