1
  
2
  
3
  
4
  
5
  
6
  
7
  
8
  
9
  
10
  
11
  
12
  
13
  
14
  
15
  
16
  
17
  
18
  
19
  
20
  
21
  
22
  
23
  
24
  
25
  
26
  
27
  
28
  
29
  
30
  
31
  
32
  
33
  
34
  
35
  
36
  
37
  
38
  
39
  
40
  
41
  
42
  
43
  
44
  
45
  
46
  
47
  
48
  
49
  
50
  
51
  
52
  
53
  
54
  
55
  
56
  
57
  
58
  
59
  
60
  
61
  
62
  
63
  
64
  
65
  
66
  
67
  
68
  
69
  
70
  
71
  
72
  
73
  
74
  
75
  
76
  
77
  
78
  
79
  
80
  
81
  
82
  
83
  
84
  
85
  
86
  
87
  
88
  
89
  
90
  
91
  
92
  
93
  
94
  
95
  
96
  
97
  
98
  
99
  
100
  
101
  
102
  
103
  
104
  
105
  
106
  
107
  
108
  
109
  
110
  
111
  
112
  
113
  
114
  
115
  
116
  
117
  
118
  
#!/usr/local/bin/pike 
 
/* $Id: httpd.pike,v 1.2 1997/05/31 22:03:38 grubba Exp $ */ 
 
/* A very small httpd capable of fetching files only. 
 * Written by Fredrik Hübinette as a demonstration of Pike 
 */ 
 
#include <simulate.h> 
 
inherit "/precompiled/port"; 
 
/* number of bytes to read for each write */ 
#define BLOCK 16060 
 
/* Where do we have the html files ? */ 
#define BASE "/home/hubbe/pike/src/" 
 
/* 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 
 
program output_class=class 
{ 
  inherit "/precompiled/file" : socket; 
  inherit "/precompiled/file" : file; 
 
  int offset=0; 
 
  void write_callback() 
  { 
    int written; 
    string data; 
 
    file::seek(offset); 
    data=file::read(BLOCK); 
    if(strlen(data)) 
    { 
      written=socket::write(data); 
      if(written >= 0) 
      { 
        offset+=written; 
        return; 
      } 
      perror("Error: "+socket::errno()+".\n"); 
    } 
    destruct(this_object()); 
  } 
 
  string input=""; 
 
  void read_callback(mixed id,string data) 
  { 
    string cmd; 
 
    input+=data; 
    if(sscanf(input,"%s %s%*[\012\015 \t]",cmd,input)) 
    { 
      if(cmd!="GET") 
      { 
        perror("Only method GET is supported.\n"); 
        destruct(this_object()); 
        return; 
      } 
 
      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(); 
    } 
  } 
 
  void selfdestruct() { destruct(this_object()); } 
 
  void create(object f) 
  { 
    socket::assign(f); 
    socket::set_nonblocking(read_callback,0,selfdestruct); 
  } 
}; 
 
void accept_callback() 
{ 
  object tmp_output; 
  tmp_output=accept(); 
  if(!tmp_output) return; 
  clone(output_class, tmp_output); 
  destruct(tmp_output); 
} 
 
int main(int argc, string *argv) 
{ 
  perror("Starting minimal httpd\n"); 
 
  if(!bind(PORT, accept_callback)) 
  { 
    perror("Failed to open socket (already bound?)\n"); 
    return 17; 
  } 
 
  return - 17; /* Keep going */ 
}