/** * This is the main method of each thread of HTTP processing. We pass this method * to the thread constructor when starting a new connection. */ public void process() { try { // Increment the number of current connections Interlocked.Increment(ref threads); // Bundle up our sockets nice and tight in various streams ns = new NetworkStream(s, FileAccess.ReadWrite); // It looks like these streams buffer sr = new StreamReader(ns); sw = new StreamWriter(ns); // Parse the request, if that succeeds, read the headers, if that // succeeds, then write the given URL to the stream, if possible. while (parseRequest()) { if (readHeaders()) { if (method == "POST") { bool tmp = readBody(); //Console.WriteLine(tmp.ToString() + ": " + url + " - " + body); if (tmp) { ParseParams(body, ref parameters); } else { writeError(400, "_FAILEDSEND_" + url + "_"); return; } } // This makes sure we don't have too many persistent connections and also // checks to see if the client can maintain keep-alive, if so then we will // keep this http processor around to process again. if (threads <= NUMSIMUL && "Keep-Alive".Equals(headers["Connection"])) { keepAlive = true; } DoResponse(); // If keep alive is not active then we want to close down the streams // and shutdown the socket if (!keepAlive) { ns.Close(); s.Shutdown(SocketShutdown.Both); break; } } } } finally { // Always decrement the number of connections Interlocked.Decrement(ref threads); doCallback = null; } }
/** * Each HTTP processor object handles one client. If Keep-Alive is enabled then this * object will be reused for subsequent requests until the client breaks keep-alive. * This usually happens when it times out. Because this could easily lead to a DoS * attack, we keep track of the number of open processors and only allow 100 to be * persistent active at any one time. Additionally, we do not allow more than 500 * outstanding requests. */ public HttpProcessor(Socket s, HttpServer.httpCallback hcb) { this.s = s; headers = new Hashtable(); doCallback = hcb; }