06983f1996-09-22Fredrik Hübinette (Hubbe) #!/usr/local/bin/pike
129b401995-10-29Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe) /* A very small httpd capable of fetching files only.
06983f1996-09-22Fredrik Hübinette (Hubbe)  * Written by Fredrik Hübinette as a demonstration of Pike
5267b71995-08-09Fredrik Hübinette (Hubbe)  */
06983f1996-09-22Fredrik Hübinette (Hubbe) #include <simulate.h>
5267b71995-08-09Fredrik Hübinette (Hubbe) inherit "/precompiled/port"; /* number of bytes to read for each write */ #define BLOCK 16060 /* Where do we have the html files ? */
06983f1996-09-22Fredrik Hübinette (Hubbe) #define BASE "/home/hubbe/pike/src/"
5267b71995-08-09Fredrik Hübinette (Hubbe)  /* File to return when we can't find the file requested */ #define NOFILE "/home/hubbe/www/html/nofile.html" /* Port to open */ #define PORT 1905
129b401995-10-29Fredrik Hübinette (Hubbe) program output_class=class
5267b71995-08-09Fredrik Hübinette (Hubbe) {
129b401995-10-29Fredrik Hübinette (Hubbe)  inherit "/precompiled/file" : socket; inherit "/precompiled/file" : file; int offset=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
129b401995-10-29Fredrik Hübinette (Hubbe)  void write_callback()
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
129b401995-10-29Fredrik Hübinette (Hubbe)  int written; string data; file::seek(offset); data=file::read(BLOCK);
cb22561995-10-11Fredrik Hübinette (Hubbe)  if(strlen(data))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
129b401995-10-29Fredrik Hübinette (Hubbe)  written=socket::write(data);
cb22561995-10-11Fredrik Hübinette (Hubbe)  if(written >= 0)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
129b401995-10-29Fredrik Hübinette (Hubbe)  offset+=written;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return; }
129b401995-10-29Fredrik Hübinette (Hubbe)  perror("Error: "+socket::errno()+".\n");
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
129b401995-10-29Fredrik Hübinette (Hubbe)  destruct(this_object());
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
129b401995-10-29Fredrik Hübinette (Hubbe)  string input="";
5267b71995-08-09Fredrik Hübinette (Hubbe) 
129b401995-10-29Fredrik Hübinette (Hubbe)  void read_callback(mixed id,string data)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
129b401995-10-29Fredrik Hübinette (Hubbe)  string cmd; input+=data; if(sscanf(input,"%s %s%*[\012\015 \t]",cmd,input))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
129b401995-10-29Fredrik Hübinette (Hubbe)  if(cmd!="GET")
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
129b401995-10-29Fredrik Hübinette (Hubbe)  perror("Only method GET is supported.\n"); destruct(this_object()); return;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
129b401995-10-29Fredrik Hübinette (Hubbe)  sscanf(input,"%*[/]%s",input); input=combine_path(BASE,input); if(!file::open(input,"r")) { if(!file::open(NOFILE,"r")) { perror("Couldn't find default file.\n"); destruct(this_object()); return; } } socket::set_buffer(65536,"w"); socket::set_nonblocking(0,write_callback,0); write_callback();
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
129b401995-10-29Fredrik Hübinette (Hubbe)  } void selfdestruct() { destruct(this_object()); }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
129b401995-10-29Fredrik Hübinette (Hubbe)  void create(object f) { socket::assign(f); socket::set_nonblocking(read_callback,0,selfdestruct);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
129b401995-10-29Fredrik Hübinette (Hubbe) };
5267b71995-08-09Fredrik Hübinette (Hubbe)  void accept_callback() {
129b401995-10-29Fredrik Hübinette (Hubbe)  object tmp_output; tmp_output=accept(); if(!tmp_output) return; clone(output_class, tmp_output); destruct(tmp_output);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
129b401995-10-29Fredrik Hübinette (Hubbe) int main(int argc, string *argv)
5267b71995-08-09Fredrik Hübinette (Hubbe) { perror("Starting minimal httpd\n"); if(!bind(PORT, accept_callback)) { perror("Failed to open socket (already bound?)\n"); return 17; }
cb22561995-10-11Fredrik Hübinette (Hubbe)  return - 17; /* Keep going */
5267b71995-08-09Fredrik Hübinette (Hubbe) }