using System.Net; using System.Net.Sockets; using System.IO; using System; using System.Text; using System.Collections; namespace T { public class T { private static String docroot="/home/dick/mono/install/html"; //private static String docroot="./"; private static Hashtable mime_types = new Hashtable(); private static Socket NetSetup() { Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); s.Bind(new IPEndPoint(IPAddress.Any, 8000)); Console.WriteLine("Listening on " + s.LocalEndPoint.ToString()); s.Listen(5); return(s); } private static String NetRead(Socket sock) { byte[] buf=new byte[256]; int count=sock.Receive(buf); // Supply the length because otherwise I get a // string of 260-odd chars instead of 30 for some reason String req=new String(Encoding.UTF8.GetChars(buf), 0, count); return(req); } private static void NetWrite(Socket sock, String data) { byte[] buf=new UTF8Encoding().GetBytes(data); sock.Send(buf); } private static void ReplyHeaders(Socket sock, int code, String detail, String content_type, String content_opt, long content_length) { NetWrite(sock, "HTTP/1.0 " + code + " " + detail + "\r\n"); NetWrite(sock, "Date: Sat, 12 Jan 2002 01:52:56 GMT\r\n"); NetWrite(sock, "Server: MIS\r\n"); NetWrite(sock, "Last-Modified: Sat, 12 Jan 2002 01:52:56 GMT\r\n"); NetWrite(sock, "Connection: close\r\n"); if(content_length>0) { NetWrite(sock, "Content-Length: " + content_length + "\r\n"); } NetWrite(sock, "Content-type: " + content_type); if(content_opt!=null) { NetWrite(sock, "; " + content_opt); } NetWrite(sock, "\r\n"); NetWrite(sock, "\r\n"); } private static void NotFound(Socket sock) { ReplyHeaders(sock, 404, "Not Found", "text/html", "charset=iso-8859-1", 0); NetWrite(sock, "\r\n"); NetWrite(sock, "\r\n"); NetWrite(sock, "404 Not Found\r\n"); NetWrite(sock, "\r\n"); NetWrite(sock, "

Not Found

\r\n"); NetWrite(sock, "\r\n"); } static void GetHeaders(out String req, out String[] headers, String data, Socket sock) { // First, find the \r\n denoting the end of the // request line int pos=data.IndexOf("\r\n"); while(pos==-1) { Console.WriteLine("Couldn't isolate request"); data=data+NetRead(sock); pos=data.IndexOf("\r\n"); } req=data.Remove(pos, data.Length-pos); // We've isolated the request line, now get the headers // Make sure we have all the headers pos=data.IndexOf("\r\n\r\n"); while(pos==-1) { //Console.WriteLine("Didn't read all the headers"); data=data+NetRead(sock); pos=data.IndexOf("\r\n\r\n"); } String hdr=data.Remove(0, req.Length+2); headers=hdr.Split(new char[]{'\r', '\n'}); } private static void Get(Socket sock, String data) { String req; String[] headers; GetHeaders(out req, out headers, data, sock); for(int i=0; i=0) { req=req.Remove(pos, req.Length-pos); } pos=req.LastIndexOf('.'); String filetype; if (pos != -1) filetype = req.Substring(pos); else filetype = ""; string mime_type = (string) mime_types [filetype]; if (mime_type == null) mime_type = "text/plain"; Console.WriteLine("File is " + req); Console.WriteLine("Mime type is " + mime_type); try { FileStream f=new FileStream(req, FileMode.Open, FileAccess.Read); byte[] fbuf=new byte[256]; ReplyHeaders(sock, 200, "OK", mime_type, null, f.Length); int count; while((count=f.Read(fbuf, 0, 256))>0) { // Specify amount, so the last // block doesnt send extra crud at // the end sock.Send(fbuf, count, SocketFlags.None); } f.Close(); } catch(FileNotFoundException) { Console.WriteLine("File not found"); NotFound(sock); } catch(IOException) { Console.WriteLine("IO error"); NotFound(sock); } } private static void Head(Socket sock, String data) { String req; String[] headers; GetHeaders(out req, out headers, data, sock); for(int i=0; i=0) { req=req.Remove(pos, req.Length-pos); } pos=req.LastIndexOf('.'); string filetype; if (pos != -1) filetype=req.Substring(pos); else filetype = ""; string mime_type = (string) mime_types [filetype]; if (mime_type == null) mime_type = "text/plain"; Console.WriteLine("File is " + req); Console.WriteLine("Mime type is " + mime_type); try { FileStream f=new FileStream(req, FileMode.Open, FileAccess.Read); byte[] fbuf=new byte[256]; ReplyHeaders(sock, 200, "OK", mime_type, null, f.Length); f.Close(); } catch(FileNotFoundException) { Console.WriteLine("File not found"); NotFound(sock); } catch(IOException) { Console.WriteLine("IO error"); NotFound(sock); } } public static int Main (string [] args) { // Set up mime types mime_types.Add(".html", "text/html"); mime_types.Add(".jpeg", "image/jpeg"); mime_types.Add(".png", "image/png"); mime_types.Add(".cs", "text/plain"); if (args.Length == 2 && args [0] == "--root"){ docroot = args [1]; } Socket s=NetSetup(); while(true) { Socket newsock=s.Accept(); String req=NetRead(newsock); if(String.Compare(req, 0, "GET ", 0, 4)==0) { Get(newsock, req); } else if(String.Compare(req, 0, "HEAD ", 0, 5)==0) { Head(newsock, req); } else { Console.WriteLine("Unknown method!"); Console.WriteLine("[" + req + "]"); } newsock.Close(); } } } }