Usage Example 2

Accessing HTTPFS (HFS822 server) via a POSIX File API

Let me show another example of reading and inquiring of remote files using the familiar open(), fopen(), etc. POSIX calls. As this example shows a remote resource being manipulated as a file not necessarily is a file on remote computer's filesystem.

 
int main(void)
{
  show_stat("http://sunhost/cgi-bin/admin/
	HFS822-server.pl/DeepestRoot/tmp/message1");
  show_file("http://sunhost/cgi-bin/admin/
	HFS822-server.pl/DeepestRoot/tmp/message1");
  ...

where show_stat() is a function that does stat() on its argument -- file name -- and prints out the result; show_file() opens a given file name via fopen() and copies the file contents to stdout. Here is the output produced by the show_stat() function above:
 
 
Information for a file 'http://sunhost/cgi-bin/admin/
     HFS822-server.pl/DeepestRoot/tmp/message1'...
        The file is a regular file, permission flags 644
        devno:ino           8388614:12      nlinks  1
        uid:gid             760:60
        size                1851     blocks  4
        Last access time:   Sun May 16 22:09:46 1999
        Last modif time:    Sun May 16 21:56:25 1999
        inode time:         Sun May 16 22:09:40 1999

 

The contents of the message (as printed out by the show_file() function) is as follows. The message is from the honorable Freenix track chairman. Some hostnames and IP addresses have been modified to protect him from spam. Note familiar message headers, followed by the body.
 
A 1851-byte long file 'http://sunhost/cgi-bin/admin/
     HFS822-server.pl/DeepestRoot/tmp/message1' is as follows
>>>From jkh@his.com Tue Mar 30 03:01:19 1999
Received: by chai (Postfix, from userid 201)
        id E4FAC6472; Mon, 29 Mar 1999 18:48:02 -0500 (EST)
Date: Mon, 29 Mar 1999 15:48:00 -0800 (PST)
From: "Jordan K. Hubbard" <jkh@his.com>
Message-Id: <199903292348.PAA42143@his.com>
To: oleg
Subject: final confirmation for FREENIX track
Content-Length: 1167
Status: OR

This message is just a final confirmation that you or one of
your co-conspirators have had a paper accepted at this year's
FREENIX track at the USENIX annual technical conference on
June 6th - June 11th.
...
<<<

 

Let's try a slight variation:
 
 ...
  show_stat("http://sunhost/cgi-bin/admin/
	HFS822-server.pl/DeepestRoot/tmp/message1/");
  show_stat("http://sunhost/cgi-bin/admin/
	HFS822-server.pl/DeepestRoot/tmp/message1/.");
  ...

Note a slash at the end of message1. These two functions produce the same output:
 
Information for a file 'http://sunhost/cgi-bin/admin/
     HFS822-server.pl/DeepestRoot/tmp/message1/'...
        The file is a directory, permission flags 644
        devno:ino           -12:1      nlinks  2
        uid:gid             760:60
        size                1851     blocks  4
        Last access time:   Sun May 16 22:10:08 1999
        Last modif time:    Tue Mar 30 03:01:19 1999
        inode time:         Tue Mar 30 03:01:19 1999
The stat() function now reports that /tmp/message1/ is a directory. Note its modification time: the time when the message was received.
 

As /tmp/message1 now acts as a directory, it should contain files. Let's try one of them:
 
 ...
  show_stat("http://sunhost/cgi-bin/admin/
	HFS822-server.pl/DeepestRoot/tmp/
	message1/date");
  ...

which prints:
 
Information for a file 'http://sunhost/cgi-bin/admin/
     HFS822-server.pl/DeepestRoot/tmp/message1/date'...
        The file is a regular file, permission flags 644
        devno:ino           -12:9      nlinks  1
        uid:gid             760:60
        size                37       blocks  4
        Last access time:   Sun May 16 22:10:08 1999
        Last modif time:    Tue Mar 30 03:01:19 1999
        inode time:         Tue Mar 30 03:01:19 1999

It is a regular file, of 37 bytes. Again, note the modification time. To see this file's contents, we'll invoke
 
 ...
  show_file("http://sunhost/cgi-bin/admin/
	HFS822-server.pl/DeepestRoot/tmp/
	message1/Date");
  ...
This gives us:
 
A 37-byte long file 'http://sunhost/cgi-bin/admin/
     HFS822-server.pl/DeepestRoot/tmp/message1/Date' is as follows

>>>Mon, 29 Mar 1999 15:48:00 -0800 (PST)
<<<
which is exactly the Date header of the original RFC822 message. Note that the HFS822 filesystem is case-insensitive.
 

The other statements in this sample code
 
 ...
  show_file("http://sunhost/cgi-bin/admin/
	HFS822-server.pl/DeepestRoot/tmp/
	message1/Subject");
  show_file("http://sunhost/cgi-bin/admin/
	HFS822-server.pl/DeepestRoot/tmp/
	message1/body");
  return 0;
}
work exactly as expected. The body is a special "header" that contains the body of the message.
 

This particular HTTPFS server allows access to a remote structured document as if it were a directory, and to its separate entities as if they were files. One can open these files with familiar open(), fopen(), ifstream, with-input-from-file system calls and library functions.

I could easily write a HTTPFS server that provides access to and probably modification of a remote XML document. It would've been a better example. However, parsing of an XML document is a little bit more involved than that of a RFC822 message -- and I simply didn't have time. The whole RFC822 server -- along with 200 lines of comments-specifications was written from scratch over one evening.

This main function itself ran on a Sun/Solaris and Linux/i686 computers. The entire code of this example -- file vhttp822.c -- is a part of the testing suite in the HTTPFS distribution.
 
Prev example Back to the Paper Next example

 


Last updated June 25, 1999

oleg-at-okmij.org
Your comments, problem reports, questions are very welcome!