Register for EarthWeb's Million Dollar Sweepstakes!
home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

HTML 4.0 Sourcebook
(Publisher: John Wiley & Sons, Inc.)
Author(s): Ian S. Graham
ISBN: 0471257249
Publication Date: 04/01/98

Bookmark It

Search this book:
 
Previous Table of Contents Next


which assumes that the HTML document and gateway program are on the same server. The client will access the indicated URL to download the requested image. A browser that understands multipart messages will play the image sequence as a simple animation. Browsers that do not understand the multipart MIME type will display nothing or will display a symbol representing a missing or broken image link.


Figure 11.3 Simple C program nph-doit2.c, for pushing a sequence of images to a client. The files are read from the indicated directory. Commentary not originally in the program listing is in boldface italics.

/*
 * doit-2.c
 * Based on doit.c --
 *   Quick hack to play a sequence of GIF files, by Rob McCool.
 *   This code is released into the public domain. Do whatever
 *   you want with it.
 *
 * Doit-2.c Modifications by By Ian Graham, July 23 1995
 * to make it a simpler demonstration example -- or so I thought!
 */

#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>

/* Define the server directives and response headers    */

#define HEADER1  “HTTP/1.0 200 OK\r\n”    /* Nph-response header*/
#define HEADER2 \
  “Content-type: multipart/x-mixed-replace;boundary=aRd4xBloobies\r\n”

/* Define the boundary strings, the Content-type header, and the*/
/* path to the directory containing the images  */

#define BOUNDARY    “\r\n--aRd4xBloobies\r\n”
#define END_BOUND   “\r\n--aRd4xBloobies--\r\n\r\n”
#define CONTENT     “Content-type: image/gif\r\n\r\n”
#define IMG_DIR     “/abs/path/image_dir”   /*  where the files are*/

int main(int argc, char *argv[])
{
   static char   *file;
   char          *files[1024], *tmp, buf[127];
   caddr_t        fp;
   int            fd, i, ndir=0;
   DIR           *dirp;
   struct dirent *dp;
   struct stat    fi;
   /* Get list of all files in image directory -- we will       */
   /* spit them out in alphabetical order       */
	                                       /* ** GET LIST    **  */
   dirp = opendir(IMG_DIR);
   while ( ((dp = readdir(dirp)) != NULL) && (ndir < 1024) ) {
      if( strncmp(dp->d_name,“.”, 1)) {
	 files[ndir] = malloc(strlen(dp->d_name)+1+strlen(IMG_DIR));
	 sprintf(files[ndir], “%s/%s”, IMG_DIR, dp->d_name);
	 ndir++;
      }
   }
   closedir(dirp);
                                            /* ** GOT LIST   **  */
      /* Write out server directives, and first multipart boundary*/
                                            /* ** PRINT SERVER RESPONSE HEADERS    **  */
   if(write(STDOUT_FILENO, HEADER1, strlen(HEADER1)) == -1)   exit(0);
   if(write(STDOUT_FILENO, HEADER2, strlen(HEADER2)) == -1)   exit(0);
   if(write(STDOUT_FILENO, BOUNDARY, strlen(BOUNDARY)) == -1) exit(0);
  
   /* Now loop over all files, and write to client      */
   for (i=0; i<ndir; i++)  {
      fprintf(stderr, “Doing output loop -- i=%i\n”, i);
      sleep(1);
	                                       /* ** WRITE PART CONTENT-TYPE   ***/
      if(write(STDOUT_FILENO, CONTENT, strlen(CONTENT)) == -1) exit(0);
      if( ( fd=open(files[i],O_RDONLY)) == -1 ) {
	  fprintf(stderr,“Unable to open file %s\n”, files[i]);
	  continue;
      }
      fstat(fd, &fi);        /*  find size of file and   */
      tmp=malloc(fi.st_size*sizeof(char));      /*  allocate memory for it  */
      read(fd, tmp, fi.st_size);
	                                       /* ** WRITE THE IMAGE DATA ** */
      if(write(STDOUT_FILENO, tmp, fi.st_size) == -1) exit(0);          
	/* ERROR: unable to write image    */
      free(tmp);
      close(fd);
                                            /* ** WRITE THE PART BOUNDARY ** */
      if(write(STDOUT_FILENO, BOUNDARY, strlen(BOUNDARY)) == -1) exit(0);
	/* ERROR unable to write boundary  */
   }
  
   /* Write out the boundary marking the end of the multipart*/
   /* message. Then we are done.        */
   write(STDOUT_FILENO, END_BOUND, strlen(END_BOUND));
   exit(0);
}

The first part of the program (between the GET LIST and GOT LIST comments) gets a list of all the image files in the directory /abs/path/image_dir and creates an array ( files[]) of absolute path filenames pointing to these files. The program then writes out the necessary server response headers, as well as the initial multipart headers and message dividers required by the multipart message (just after the PRINT SERVER RESPONSE HEADERS comment). The subsequent loop iterates over the different image files, sending them one after the other to the client, and each file is followed by the required multipart boundary marker (after the WRITE THE PART BOUNDARY comment). When finished with the list, the program exits, writes out the final boundary marking the end of the multipart message, and ends the connection.

Because this is a gateway program, you can pass variables to the program using the usual tricks. Thus you can use extra path information in a URL (the PATH_INFO environment variable) to pass the location of the image directory to the CGI program, instead of using a hard-wired location as done in this example.

Both client-pull and server-push are simple, but not terribly flexible techniques for automatically updating page content. For example, client-pull can be mimicked by a JavaScript program, but with added functionality such as user control of the time delay between pages. Similarly, server-push is a rudimentary way of pushing data to the browser and is being supplanted by animated GIFs, Java applets, Macromedia Shockwave plug-ins, and push-channel technologies.

Server-Side Includes

A recurring HTML authoring question is: “Can I include a file within my HTML document in the same way I include an image?” Generally, the answer is no, as there are no elements in HTML that allow arbitrary document inclusions (other than for frame elements, of course). If you want to have documents that are created dynamically (which is what is implied by inclusion), you are supposed to use a CGI program. Needless to say, this is overkill if all you want to do is patch a small piece of text into an otherwise stable document. Some kind of include HTML command would be far easier than a full CGI program.

Most HTTP servers support file inclusion via a mechanism called server-side includes, or SSI. With SSI, a server parses specially marked documents (called parsable HTML documents, often with the filename extension .shtml), looking for specially encoded HTML comment strings containing SSI directives. The server replaces these special comments with the output generated by processing the directive. There are several different directives: some that “include” other text or HTML files into the document, and others that can execute server-side programs and include the program output within the document.


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.