root/trunk/cgi/cgi.d

Revision 59, 6.5 kB (checked in by lindquist, 1 year ago)

merged the dsssify branch into trunk noone has complained. some module identifiers have changed.
updated tinyjpeg to version 20070609

Line 
1 /*
2 This program is distributed without any warranty of any kind!
3
4 Author: Benjamin Shropshire (shro8822drop_this at vandals dot uidaho edu)
5
6 License: Freeware
7 Please give credit where credit is due. Please don't remove this notice.
8
9    Revision history:
10       31/Mar/2007: Rodney Berriman (rodneyDROP_THIS at optimail com au)
11                     Added support for HTTP GET method
12   
13 */
14
15 module cgi;
16
17 import std.stdio;
18 import std.stream;
19 import std.cstream;
20 static import str = std.string;
21 static import clib = std.c.stdlib;
22
23 class CGI : Stream
24 {
25     char[][char[]] params;
26
27     void Spill()
28     {
29         foreach(k,v; params)
30             this.writef("[%s: %s]\n",k,v);
31     }
32
33     this(char[][] argv)
34     {
35         char[] buffer, buffer_1, method;
36         method = str.toString(clib.getenv(str.toStringz("REQUEST_METHOD")));
37         // silently ignore ISINDEX method, now deprecated for security reasons:
38         if (method == "GET")
39           buffer_1 = str.toString(clib.getenv(str.toStringz("QUERY_STRING")));
40         else if (method == "POST")
41           buffer_1 = StripStream(din);
42
43         int hex = 0;
44         char ret, back;
45
46         while(buffer_1.length > 0)
47         {
48             int i;
49             foreach(ind,c; buffer_1)
50             {
51                 i = ind;
52                 if(c == '=')
53                 {
54                     buffer = buffer_1[0..ind];
55                     break;
56                 }
57             }
58             if(i < buffer_1.length)
59             {
60                 buffer_1 = buffer_1[i+1..$];
61                 params[buffer] = WalkCGItext(buffer_1);
62             }
63         }
64
65     }
66
67     char[] Value(char[] type){if(auto ret = type in params) return (*ret).dup; else return ""; }
68
69     char[] WalkCGItext(inout char[] buffer_1)
70     {
71     //  scope(exit) writef("_%d__<br>\n", buffer_1.length);
72         char[] buffer;
73
74         int hex = 0;
75         char ret, back;
76         loop: foreach(int i, char c; buffer_1)
77         {
78             if(hex>=1)
79             {
80                 back = c;
81                 ret <<= 4;
82                 hex++;
83                 switch(c)
84                 {
85                     case 'A','B','C','D','E','F':
86                         back = c;
87                         ret += (c - 'A' + 10);
88                         break;
89
90                     case '0','1','2','3','4','5','6','7','8','9':
91                         back = c;
92                         ret += (c - '0');
93                         break;
94
95                     default:
96                         buffer ~= '%';
97                         buffer ~= back;
98                 }
99                 if(hex >= 3)
100                 {
101                     hex = 0;
102                     buffer ~= ret;
103                     ret = 0;
104                 }
105             }
106             else switch(c)
107             {
108                 case '+':
109                     buffer~=' ';
110                     break;
111
112                 case '%':
113                     hex = 1;
114                     ret = 0;
115                     break;
116
117                 case '&':
118                     buffer_1 = buffer_1[i+1..$];
119                     return buffer;
120
121                 default:
122                     buffer~=c;
123                     break;
124             }
125         }
126
127         buffer_1.length = 0;
128         return buffer;
129     }
130
131     static private char[] StripStream(Stream str)
132     {
133         char[][] set;
134         int length = 0;
135         int i;
136         for(i = 0; !str.eof; i++)
137         {
138             if(set.length <= i) set.length = i+5;
139             set[i].length = 30;
140             set[i].length = str.read(cast(ubyte[])set[i]);
141             length += set[i].length;
142         }
143         set.length = i;
144
145         char[] buffer = new char[length];
146
147         int at = 0;
148         foreach(s;set)
149         {
150             buffer[at..at + s.length] = s[0..$];
151             at += s.length;
152         }
153         return buffer;
154     }
155
156     size_t readBlock(void* buffer, size_t size) { return 0; }
157     size_t writeBlock(void* buffer, size_t size)    { return dout.writeBlock(buffer, size); }
158     ulong seek(long offset, SeekPos whence)     { return dout.seek(offset, whence); }
159 }
160
161
162 class TextCGI : CGI
163 {
164     this(char[][] argv)
165     {
166         writef("Content-type: text/plain\n\n\n");
167         super(argv);
168     }
169 }
170
171
172 class HTML_CGI : CGI
173 {
174     bool head = false;
175     bool bod = false;
176     this(char[][] argv)
177     {
178         this.writef("Content-type: text/html\n\n\n<html>\n");
179         super(argv);
180     }
181
182     ~this()
183     {
184         this.writef("</html>");
185     }
186
187     void Head(void delegate() dg)
188     {
189         if(head) throw new Error("Only One head is allowed"); else head=true;
190         this.writef("<head>\n");
191         scope(exit) this.writef("</head>\n");
192         dg();
193     }
194     void Head(char[] data)
195     {
196         if(head) throw new Error("Only One head is allowed"); else head=true;
197         this.writef("<head>\n%s</head>\n", data);
198     }
199
200     void Body(void delegate() dg)
201     {
202         if(bod) throw new Error("Only One body is allowed"); else bod=true;
203         this.writef("<body>\n");
204         scope(exit) this.writef("</body>\n");
205         dg();
206
207     }
208     void Body(char[] data)
209     {
210         if(bod) throw new Error("Only One body is allowed"); else bod=true;
211         this.writef("<body>\n%s</body>\n",data);
212     }
213
214     void Form(char[] act, char[] method, char[] data)   {this.writef("<form action=%s method=%s>\n%s\n</form>\n", act, method, data);}
215     void Form(char[] act, char[] method, void delegate() dg)
216     {
217         this.writef("<form action=%s method=%s>\n", act, method);
218         scope(exit) this.writef("\n</form>\n");
219         dg();
220     }
221
222     void InputText(char[] name, uint size)
223         {this.writef("<input type=text name=%s size=%d>", name, size);}
224
225     void InputText(char[] name, uint size, char[] def)
226         {this.writef("<input type=text name=%s value=\"%s\" size=%d>", name, def, size);}
227
228     void InputSubmit(char[] value)
229         {this.writef("<input type=submit value=\"%s\">", value);}
230
231     void InputCheckbox(char[] name, bool ck=false)
232         {this.writef("<INPUT TYPE=checkbox NAME=\"%s\"%s>",name, ck?" CHECKED":"");}
233
234     void SelectList(char[] name, char[] sel, char[][] options...)
235     {
236         this.writef("<SELECT NAME=\"%s\">",name);
237         scope(exit) this.writef("</SELECT>");
238         foreach(char[] op; options)
239             this.writef("<option%s>%s</option>", op==sel?" SELECTED":"",op);
240     }
241
242     void TableData(char[] data){this.writef("<td>%s</td>", data);}
243     void TableData(void delegate() dg)
244     {
245         this.writef("<td>");
246         scope(exit) this.writef("</td>");
247         dg();
248     }
249     void TableData(int span, char[] data){this.writef("<td colspan=%d>%s</td>", span, data);}
250     void TableData(int span, void delegate() dg)
251     {
252         this.writef("<td colspan=%d>", span);
253         scope(exit) this.writef("</td>");
254         dg();
255     }
256
257     void TableRow(char[] data)      {this.writef("<tr>\n%s\n</tr>\n", data);}
258     void TableRow(void delegate() dg)
259     {
260         this.writef("<tr>\n");
261         scope(exit) this.writef("\n</tr>\n");
262         dg();
263     }
264
265     void Table(char[] data)     {this.writef("<table>\n%s\n</table>\n", data);}
266     void Table(void delegate() dg)
267     {
268         this.writef("<table>\n");
269         scope(exit) this.writef("\n</table>\n");
270         dg();
271     }
272
273     void Heading1(char[] data){this.writef("<h1>%s</h1>\n", data);}
274     void Heading1(void delegate() dg)
275     {
276         this.writef("<h1>");
277         scope(exit) this.writef("</h1>\n");
278         dg();
279     }
280
281     void Heading2(char[] data){this.writef("<h2>%s</h2>\n", data);}
282     void Heading2(void delegate() dg)
283     {
284         this.writef("<h2>");
285         scope(exit) this.writef("</h2>\n");
286         dg();
287     }
288
289     void Heading3(char[] data){this.writef("<h3>%s</h3>\n", data);}
290     void Heading3(void delegate() dg)
291     {
292         this.writef("<h3>");
293         scope(exit) this.writef("</h3>\n");
294         dg();
295     }
296
297     void Heading4(char[] data){this.writef("<h4>%s</h4>\n", data);}
298     void Heading4(void delegate() dg)
299     {
300         this.writef("<h4>");
301         scope(exit) this.writef("</h4>\n");
302         dg();
303     }
304
305     void Link(char[] name, char[] text) { this.writef(`<A HREF="%s">%s</A>`, name,text);}
306     void Link(char[] name) { this.writef(`<A HREF="%s">%s</A>`, name,name);}
307
308 }
Note: See TracBrowser for help on using the browser.