%!

%===================================================
% PS-HTTPD V1.3
% Copyright 2000 Anders Karlsson, pugo@pugo.org
% License: GNU General Public License
%===================================================

% This dictionary maps between extensions and mime-types
% Observe that "html" isn't part of this dict, that's because
% it's default in print_header.

/extensiondict 27 dict def
extensiondict begin
        /jpg (Content-type: image/jpeg\n) def
        /jpeg (Content-type: image/jpeg\n) def
        /gif (Content-type: image/gif\n) def
        /png (Content-type: image/png\n) def
        /tif (Content-type: image/tiff\n) def
        /tiff (Content-type: image/tiff\n) def
        /txt (Content-type: text/plain\n) def
        /css (Content-type: text/css\n) def
        /ps (Content-type: application/postscript\n) def
        /pdf (Content-type: application/pdf\n) def
        /eps (Content-type: application/postscript\n) def
        /tar (Content-type: application/x-tar\n) def
        /rpm (Content-type: application/x-rpm\n) def
        /zip (Content-type: application/zip\n) def
        /mp3 (Content-type: audio/mpeg\n) def
        /mp2 (Content-type: audio/mpeg\n) def
        /mid (Content-type: audio/midi\n) def
        /midi (Content-type: audio/midi\n) def
        /wav (Content-type: audio/x-wav\n) def
        /au (Content-type: audio/basic\n) def
        /ram (Content-type: audio/x-pn-realaudio\n) def
        /ra (Content-type: audio/x-realaudio\n) def
        /mpg (Content-type: video/mpeg\n) def
        /mpeg (Content-type: video/mpeg\n) def
        /qt (Content-type: video/quicktime\n) def
        /mov (Content-type: video/quicktime\n) def
        /avi (Content-type: video/x-msvideo\n) def
end


/get_file % read file /infile and send it to %stdout
{
        /buff 2048 string def
        
        { % loop
                infile buff readstring
                { stdout exch writestring }
                { stdout exch writestring infile closefile exit } ifelse
        } bind loop
} bind def


/read_command % read command from stdin and define it to /command
{
        /stdin (%stdin) (r) file def
        /inbuff 256 string def
        
        stdin inbuff readline
        pop
        /command exch def
} bind def


/conbcatstr % A better string-concat
{
exch dup length 2 index length add string
dup dup 4 2 roll copy length 4 -1 roll putinterval
} bind def
        
        

/hitcount % Add 1 to the hitcount-file
{
(/home/pugo/psweb/hits) (r+) file
dup dup
dup 16 string readline pop
1 index 0 setfileposition
cvi 1 add 16 string cvs
writestring (\n) writestring
closefile
} bind def


% Return extension of file on stack
/get_extension % (filepath.ext) -- (bool) (ext)
{
        dup
        { % loop
                (.) search
                { pop pop }
                { exit } ifelse
        } loop
        exch 1 index ne
} bind def


% Print a HTTP-header
/print_header
{
        stdout (HTTP/1.0 200 OK\n) writestring
        stdout (MIME-Version: 1.0\n) writestring
        stdout (Server: PS-HTTPD/1.3\n) writestring

        get_extension
        {
                % If the extension exists in dictionary, then use it,
                % otherwise hope that text/html is good enough.
                dup extensiondict exch known
                { extensiondict exch get stdout exch writestring }
                { pop stdout (Content-type: text/html\n) writestring } ifelse
        }
        { % Couldn't get extension, guess it's text/html
                pop stdout (Content-type: text/plain\n) writestring
        } ifelse
        
        stdout (\n) writestring
} bind def


% Parse the HTTP-command read from user
/parse_result
{
        command token
        {
                (GET) eq
                {
                        ( ) search
                        {
                         root exch conbcatstr % build path
                         /filename exch def pop pop % define filename and clean stack
                         filename filename length 1 sub 1 getinterval (/) eq
                         { filename (index.html) conbcatstr
                                 /filename exch def } if % add index.html
                        
                         filename (..) search % Check if user tries to use ".."
                         { stdout (4711 Stupid user error!\n\n) writestring quit } if pop
                        
                         filename /infile exch (r) file def % open file
                        
                         filename print_header
                         get_file
                        } if
                } if
        } if
} bind def


% Redefine handleerror in errordict to quit on all errors.
% Otherwise it will be possible to telnet and get a postscript-prompt
errordict begin
/handleerror { stdout (PS-HTTPD ERROR
Probably wrong URL\n\n) writestring quit } def
end


% Init environment
/stdout (%stdout) (w) file def
/command () def


% Root-path (root of WWW-pages)
/root (/home/pugo/psweb) def


hitcount % add one to the hitcount

% Read a command from the server
read_command
parse_result

quit