3 using System
.Net
.Sockets
;
4 using System
.Collections
.Specialized
;
5 using System
.Collections
.Generic
;
13 public class WvHttpSession
: Dictionary
<string,string>
15 WvLog log
= new WvLog("session");
18 public string sessid { get { return _sessid; }
}
20 public WvHttpSession(WvDbi dbi
, string sessid
)
23 this._sessid
= sessid
;
27 public WvHttpSession(WvDbi dbi
)
30 this._sessid
= new_sessid();
31 dbi
.execute("insert into Session (ixSession, dtSaved, bData) "
32 + "values (?, ?, ?) ", sessid
, DateTime
.Now
, "");
35 static string new_sessid()
37 return wv
.randombytes(20).ToHex();
42 log
.print("Loading session '{0}'\n", sessid
);
44 // There should actually be only one row
46 dbi
.select("select dtSaved, bData from Session "
47 + "where ixSession=? ",
51 if (dt
+ TimeSpan
.FromSeconds(60*60) >= DateTime
.Now
)
52 wv
.urlsplit(this, r
[1]);
58 List
<string> l
= new List
<string>();
59 foreach (string k
in Keys
)
60 l
.Add(HttpUtility
.UrlEncode(k
)
62 + HttpUtility
.UrlEncode(this[k
]));
63 string data
= l
.Join("&");
67 dbi
.execute("insert into Session (ixSession, dtSaved, bData) "
69 sessid
, DateTime
.Now
, "");
73 dbi
.execute("update Session set bData=?, dtSaved=? "
74 + "where ixSession=?", data
, DateTime
.Now
, sessid
);
78 public interface IWvHttpRequest
80 string request_uri { get; }
81 Web
.Cgi
.Method request_method { get; }
83 string query_string { get; }
84 Dictionary
<string,string> headers { get; }
85 // FIXME: This sucks, it should really be a Dictionary<string,string>
86 // to match the headers, but Wv.Cgi already has this as a
87 // NameValueCollection
88 NameValueCollection request { get; }
91 public class WvHttpRequest
: IWvHttpRequest
93 public string _request_uri
;
94 public string request_uri
96 get { return _request_uri; }
97 set { _request_uri = value; }
100 public Web
.Cgi
.Method request_method
102 get { return Web.Cgi.Method.Get; }
107 get { return request_uri.Split(new char[] {'?'}
, 2)[0]; }
110 public string query_string
114 string[] parts
= request_uri
.Split(new char[] {'?'}
, 2);
115 if (parts
.Length
>= 2)
122 public Dictionary
<string,string> _headers
123 = new Dictionary
<string,string>();
124 public Dictionary
<string,string> headers
126 get { return _headers; }
129 public NameValueCollection request
134 public WvHttpRequest() { }
136 public WvHttpRequest(string s
)
138 parse_request(wv
.fmt("GET {0} HTTP/1.0", s
));
141 public void parse_request(string s
)
143 string[] parts
= s
.Split(new char[] {' '}
, 3);
144 if (parts
.Length
< 3)
145 throw new Exception("Not enough words in request!");
146 if (parts
[0] != "GET")
147 throw new Exception("Request should start with GET");
148 request_uri
= parts
[1];
151 public void parse_header(string s
)
155 string[] parts
= s
.Split(new char[] {':'}
, 2,
156 StringSplitOptions
.None
);
157 string key
= parts
[0].ToLower();
159 if (parts
.Length
< 2)
160 headers
.Add(key
, "");
162 headers
.Add(key
, parts
[1].Trim());
166 public class WvHttpCgiRequest
: IWvHttpRequest
170 public string request_uri
172 get { return cgi.cgivars["REQUEST_URI"]; }
175 public Web
.Cgi
.Method request_method
177 get { return cgi.method; }
182 get { return cgi.script_name; }
185 public string query_string
187 get { return cgi.query_string; }
190 public Dictionary
<string,string> _headers
191 = new Dictionary
<string,string>();
192 public Dictionary
<string,string> headers
194 get { return _headers; }
197 public NameValueCollection request
199 get { return cgi.request; }
202 public WvHttpCgiRequest()
206 foreach (string key
in cgi
.cgivars
)
208 if (key
.StartsWith("HTTP_"))
210 // Turn "HTTP_HEADER_NAME" into "header-name"
212 key
.Substring(5).ToLower().Replace('_', '-'),
219 public class WvHttpServer
222 WvLog log
= new WvLog("HTTP Server", WvLog
.L
.Info
);
224 public delegate void Responder(WvHttpRequest req
, Stream s
);
227 public WvHttpServer(int port
, Responder responder
)
229 this.responder
= responder
;
230 log
.print("World's dumbest http server initializing. (and how!)\n");
231 log
.print("Trying port {0}.\n", port
);
232 server
= new TcpListener(port
);
234 log
.print("Listening on {0}\n", server
.LocalEndpoint
);
237 public void runonce()
239 TcpClient client
= server
.AcceptTcpClient();
240 log
.print("Incoming connection.\n");
242 NetworkStream stream
= client
.GetStream();
243 StreamReader r
= new StreamReader(stream
);
245 WvHttpRequest req
= new WvHttpRequest();
246 string s
= r
.ReadLine();
247 log
.print("Got request line: '{0}'\n", s
);
248 req
.parse_request(s
);
249 log
.print("Path is: '{0}'\n", req
.request_uri
);
253 log
.print("Got header line: '{0}'\n", s
);
258 responder(req
, stream
);
260 log
.print("Closing connection.\n");