public void RunHook(string hook, ref HttpRequestInfo obj) { foreach (LoadedCallback callback in callbacks) { if (callback.hook == hook) { callback.method(ref obj); } } }
public void ProcessFile(ref HttpRequestInfo obj) { Console.WriteLine("Callback processing of requested file..."); //HttpRequestInfo theRequest = ref obj; if(obj.mimeType == "text/html") { string HTML = Encoding.UTF8.GetString(obj.rawFile); HTML = HTML.Replace("<", "<"); HTML = HTML.Replace(">", ">"); obj.finalizedFile = System.Text.Encoding.UTF8.GetBytes(HTML); } }
public int ProcessRequest(ref HttpRequestInfo request) { return 1; }
private bool handleRequest(NetworkStream clientStream, HttpRequestInfo theRequest) { CallbackSys.RunHook("start.request", ref theRequest); /* What are we doing here? */ switch (theRequest.method) { /* First, let us check to see if we can find the file */ case HttpMethod.GET: /* Build list of files to look for if the request was for a directory */ theRequest.file = HttpUtility.UrlDecode(theRequest.file); Console.WriteLine("Decoded: " + theRequest.file); if (theRequest.file[theRequest.file.Length - 1] == '/') { string[] indexFiles = config.directive["DirectoryIndex"].Split(' '); string realPath = config.directive["DocumentRoot"]; bool found = false; bool isDirectory = false; realPath = realPath.Replace('\\', '/'); if (Directory.Exists(realPath)) { realPath = realPath + theRequest.file.Substring(1); isDirectory = true; } /* Make sure root / works */ if (theRequest.file == "/") isDirectory = false; foreach (string file in indexFiles) { if (File.Exists(realPath + file.Trim())) { realPath += file.Trim(); theRequest.file = file.Trim(); found = true; break; } } /* Send the page */ if (found) { FileInfo fInfo = new FileInfo(realPath); Stream fileStream = File.OpenRead(realPath); byte[] buf = new byte[fInfo.Length]; /* Read up the file that was requested */ int offset = 0; long remaining = fInfo.Length; while (remaining > 0) { int read = fileStream.Read(buf, offset, buf.Length); if (read <= 0) throw new EndOfStreamException (String.Format("End of stream reached with {0} bytes left to read", remaining)); remaining -= read; offset += read; } theRequest.rawFile = buf; theRequest.finalizedFile = theRequest.rawFile; /* Call any modules that may need to process the raw file */ Console.WriteLine("\tCalling callback hooks..."); CallbackSys.RunHook("request.rawfile.process", ref theRequest); theRequest.mimeType = mimeTypes.GetMimeType(theRequest.file.Substring(theRequest.file.LastIndexOf('.') + 1)); if (theRequest.finalizedFile.Length == 0) { SendHeaders(clientStream, HttpStatus.OKAY, buf.Length, theRequest.mimeType); clientStream.Write(buf, 0, buf.Length); } else { SendHeaders(clientStream, theRequest.status, theRequest.finalizedFile.Length, theRequest.mimeType); clientStream.Write(theRequest.finalizedFile, 0, theRequest.finalizedFile.Length); } /* * If a module processed the file read in above and * ran it to generate HTML (like php) the plugin is * responsible for serving that to the client as all * we do is serve the content directly * / if (!theRequest.skipBuiltinServe) { clientStream.Write(buf, 0, buf.Length); } else { } //string mimeType = mimeTypes.GetMimeType(theRequest.file.Substring(theRequest.file.LastIndexOf('.') + 1)); //SendHeaders(clientStream, HttpStatus.OKAY, fInfo.Length, mimeType); /* Read file in and output it to client * using (FileStream fs = fInfo.OpenRead()) { byte[] buf = new byte[1024]; int? bytesRead = null; while (bytesRead != 0) { bytesRead = fs.Read(buf, 0, 1024); clientStream.Write(buf, 0, buf.Length); } }*/ clientStream.Flush(); } else if(isDirectory) { /* Attempt to list the directory */ SendHeaders(clientStream, HttpStatus.OKAY, "text/html"); ASCIIEncoding encoder = new ASCIIEncoding(); byte[] data = encoder.GetBytes(ShowDirectory(theRequest.file)); clientStream.Write(data, 0, data.Length); clientStream.Flush(); } else { /* Throw a 404 up */ SendHeaders(clientStream, HttpStatus.FILENOTFOUND, "text/html"); ASCIIEncoding encoder = new ASCIIEncoding(); byte[] data = encoder.GetBytes("<h1>Not found</h1>" + "<p>The request " + theRequest.file + " was not found on this server.</p>\n"); clientStream.Write(data, 0, data.Length); clientStream.Flush(); } } else // Direct file request { if (theRequest.file[0] == '/') { theRequest.file = theRequest.file.Substring(1); } string realPath = config.directive["DocumentRoot"] + theRequest.file.Trim(); bool found = false; bool isDirectory = false; realPath = realPath.Replace('\\', '/'); if (Directory.Exists(realPath)) { realPath = realPath + theRequest.file; theRequest.file = "/" + theRequest.file; isDirectory = true; } if (File.Exists(realPath)) { found = true; Console.WriteLine("File found! " + realPath); } /* Send the page */ if (found) { FileInfo fInfo = new FileInfo(realPath); byte[] buf = new byte[fInfo.Length]; try { theRequest.mimeType = mimeTypes.GetMimeType(theRequest.file.Substring(theRequest.file.LastIndexOf('.') + 1)); //SendHeaders(clientStream, HttpStatus.OKAY, fInfo.Length, mimeType); /* Read file in and output it to client * using (FileStream fs = fInfo.OpenRead()) { byte[] buf = new byte[1024]; int? bytesRead = null; while (bytesRead != 0) { bytesRead = fs.Read(buf, 0, 1024); clientStream.Write(buf, 0, buf.Length); } }*/ using(FileStream fileStream = fInfo.OpenRead()) { /* Read up the file that was requested */ int offset = 0; long remaining = fInfo.Length; while (remaining > 0) { int read = fileStream.Read(buf, offset, buf.Length); if (read <= 0) throw new EndOfStreamException (String.Format("End of stream reached with {0} bytes left to read", remaining)); remaining -= read; offset += read; } theRequest.rawFile = buf; theRequest.finalizedFile = theRequest.rawFile; /* Call any modules that may need to process the raw file */ Console.WriteLine("\tCalling callback hooks..."); CallbackSys.RunHook("request.rawfile.process", ref theRequest); if (theRequest.finalizedFile.Length == 0) { SendHeaders(clientStream, HttpStatus.OKAY, buf.Length, theRequest.mimeType); clientStream.Write(buf, 0, buf.Length); } else { SendHeaders(clientStream, theRequest.status, theRequest.finalizedFile.Length, theRequest.mimeType); clientStream.Write(theRequest.finalizedFile, 0, theRequest.finalizedFile.Length); } } } catch (Exception ex) { Console.WriteLine(">>" + ex.Message); } } else if (isDirectory) { /* Attempt to list the directory */ SendHeaders(clientStream, HttpStatus.OKAY, "text/html"); ASCIIEncoding encoder = new ASCIIEncoding(); byte[] data = encoder.GetBytes(ShowDirectory(theRequest.file)); clientStream.Write(data, 0, data.Length); clientStream.Flush(); } else { /* Throw a 404 up */ SendHeaders(clientStream, HttpStatus.FILENOTFOUND, "text/html"); ASCIIEncoding encoder = new ASCIIEncoding(); byte[] data = encoder.GetBytes("<h1>Not found</h1>" + "<p>The request " + theRequest.file + " was not found on this server.</p>\n"); clientStream.Write(data, 0, data.Length); clientStream.Flush(); } } break; default: /* Internal Server Error it up! */ SendHeaders(clientStream, HttpStatus.INTERNAL_ERROR, "text/html"); ASCIIEncoding encodr = new ASCIIEncoding(); byte[] data_ = encodr.GetBytes("Internal Server Error\n"); clientStream.Write(data_, 0, data_.Length); clientStream.Flush(); break; } //Console.WriteLine("Request ended."); return true; }
private void ClientHandler(object client) { Console.WriteLine("Client handler thread started..."); TcpClient tcpClient = (TcpClient)client; NetworkStream clientStream = tcpClient.GetStream(); ASCIIEncoding encoder = new ASCIIEncoding(); StringBuilder RequestLines = new StringBuilder(); byte[] message = new byte[4096]; int bytesRead = 0; while (encoder.GetString(message, 0, bytesRead).IndexOf("\r\n\r\n") == -1 && encoder.GetString(message, 0, bytesRead).IndexOf("\n\n") == -1) { bytesRead = 0; try { /* Wait for message... */ bytesRead = clientStream.Read(message, 0, 4096); } catch (Exception ex) { Console.WriteLine("Socket Error"); Debug.WriteLine("Socket error: " + ex.Message); clientStream.Close(); tcpClient.Close(); break; } if (bytesRead == 0) { /* Disconnected */ clientStream.Close(); tcpClient.Close(); return; } /* Message received, was ist das?! */ RequestLines.Append(encoder.GetString(message, 0, bytesRead)); } /* Go through the lines and gather request info */ HttpRequestInfo theRequest = new HttpRequestInfo(); string fullRequ = RequestLines.ToString(); string[] lines = fullRequ.Split('\n'); /* Get our method */ if (lines.Length > 0) { /* Only GET for now... */ if(lines[0].IndexOf(HttpMethod.GET) > -1) { theRequest.method = HttpMethod.GET; string[] words = lines[0].Split(' '); /* Store the requested file */ if (words.Length > 1) { theRequest.file = words[1]; } } } /* Process any other directives here */ for (int i = 1; i < lines.Length; i++) { int dirEnd = lines[i].IndexOf(": "); if (dirEnd > 1) { theRequest.directives.Add(lines[i].Substring(0, dirEnd), lines[i].Substring(dirEnd + 2)); } } if (!handleRequest(clientStream, theRequest)) { Console.WriteLine("Error handling request for " + theRequest.file); } clientStream.Close(); tcpClient.Close(); theRequest = null; if (Interlocked.Decrement(ref numBusy) == 0) { DoneEvent.Set(); } Console.WriteLine("Client handler thread exiting..."); }