/* This program is distributed without any warranty of any kind! Author: Benjamin Shropshire (shro8822drop_this at uidaho edu) License: Freeware Please give credit where credit is due. Please don't remove this notice. Revision history: 31/Mar/2007: Rodney Berriman (rodneyDROP_THIS at optimail com au) Added support for HTTP GET method */ module xsltcgi; import std.stdio; import std.stream; import std.cstream; static import str = std.string; static import clib = std.c.stdlib; class CGI : Stream { char[][char[]] params; void Spill() { foreach(k,v; params) { this.writef("[%s: %s]\n",k,v); } //this.writef("QS: %s", str.toString(clib.getenv(str.toStringz("PATH_INFO")))); //this.writef("SN: %s", str.toString(clib.getenv(str.toStringz("SCRIPT_NAME")))); } char[] getPathInfo(bool clean = true) { char[] pi = str.toString(clib.getenv(str.toStringz("PATH_INFO"))); if (!clean) { return pi; } char[] ret = ""; foreach(c;pi) { // strip any characters that may cause problems.. if ((c < 32) || (c > 128)) { // out of bounds.. continue; } switch (c) { case '.': continue; default: ret ~= c; } } return ret; } this(char[][] argv) { char[] buffer, buffer_1, method; method = str.toString(clib.getenv(str.toStringz("REQUEST_METHOD"))); // silently ignore ISINDEX method, now deprecated for security reasons: if (method == "GET") { buffer_1 = str.toString(clib.getenv(str.toStringz("QUERY_STRING"))); } else if (method == "POST") { buffer_1 = StripStream(din); } int hex = 0; char ret, back; while(buffer_1.length > 0) { int i; foreach(ind,c; buffer_1) { i = ind; if(c == '=') { buffer = buffer_1[0..ind]; break; } } if(i < buffer_1.length) { buffer_1 = buffer_1[i+1..$]; params[buffer] = WalkCGItext(buffer_1); } } } char[] Value(char[] type){if(auto ret = type in params) return (*ret).dup; else return ""; } char[] WalkCGItext(inout char[] buffer_1) { // scope(exit) writef("_%d__
\n", buffer_1.length); char[] buffer; int hex = 0; char ret, back; loop: foreach(int i, char c; buffer_1) { if(hex>=1) { back = c; ret <<= 4; hex++; switch(c) { case 'A','B','C','D','E','F': back = c; ret += (c - 'A' + 10); break; case '0','1','2','3','4','5','6','7','8','9': back = c; ret += (c - '0'); break; default: buffer ~= '%'; buffer ~= back; } if(hex >= 3) { hex = 0; buffer ~= ret; ret = 0; } } else switch(c) { case '+': buffer~=' '; break; case '%': hex = 1; ret = 0; break; case '&': buffer_1 = buffer_1[i+1..$]; return buffer; default: buffer~=c; break; } } buffer_1.length = 0; return buffer; } static private char[] StripStream(Stream str) { char[][] set; int length = 0; int i; for(i = 0; !str.eof; i++) { if(set.length <= i) set.length = i+5; set[i].length = 30; set[i].length = str.read(cast(ubyte[])set[i]); length += set[i].length; } set.length = i; char[] buffer = new char[length]; int at = 0; foreach(s;set) { buffer[at..at + s.length] = s[0..$]; at += s.length; } return buffer; } size_t readBlock(void* buffer, size_t size) { return 0; } size_t writeBlock(void* buffer, size_t size) { return dout.writeBlock(buffer, size); } ulong seek(long offset, SeekPos whence) { return dout.seek(offset, whence); } }