Added the MIS web server
authorDick Porter <dick@acm.org>
Wed, 23 Jan 2002 19:27:53 +0000 (19:27 -0000)
committerDick Porter <dick@acm.org>
Wed, 23 Jan 2002 19:27:53 +0000 (19:27 -0000)
svn path=/trunk/mono/; revision=2128

mono/tests/mis.cs [new file with mode: 0755]

diff --git a/mono/tests/mis.cs b/mono/tests/mis.cs
new file mode 100755 (executable)
index 0000000..5375369
--- /dev/null
@@ -0,0 +1,228 @@
+
+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, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n");
+                       NetWrite(sock, "<HTML><HEAD>\r\n");
+                       NetWrite(sock, "<TITLE>404 Not Found</TITLE>\r\n");
+                       NetWrite(sock, "</HEAD><BODY>\r\n");
+                       NetWrite(sock, "<H1>Not Found</H1>\r\n");
+                       NetWrite(sock, "</BODY></HTML>\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<headers.Length; i++) {
+                               if(headers[i].StartsWith("User-Agent: ")) {
+                                       Console.WriteLine(headers[i]);
+                               }
+                       }
+
+                       // Remove the method, and prepend the docroot
+                       req=String.Concat(docroot, req.Remove(0, 4));
+
+                       // Trim the trailing protocol info
+                       int pos=req.IndexOfAny(new char[]{' '});
+                       if(pos>=0) {
+                               req=req.Remove(pos, req.Length-pos);
+                       }
+
+                       pos=req.LastIndexOf('.');
+                       String filetype=req.Substring(pos);
+
+                       Console.WriteLine("File is " + req);
+                       Console.WriteLine("Mime type is " + mime_types[filetype]);
+
+                       try {
+                               FileStream f=new FileStream(req, FileMode.Open, FileAccess.Read);
+                               byte[] fbuf=new byte[256];
+
+                               ReplyHeaders(sock, 200, "OK",
+                                            mime_types[filetype].ToString(),
+                                            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<headers.Length; i++) {
+                               if(headers[i].StartsWith("User-Agent: ")) {
+                                       Console.WriteLine(headers[i]);
+                               }
+                       }
+
+                       // Remove the method, and prepend the docroot
+                       req=String.Concat(docroot, req.Remove(0, 5));
+
+                       // Trim the trailing protocol info
+                       int pos=req.IndexOfAny(new char[]{' '});
+                       if(pos>=0) {
+                               req=req.Remove(pos, req.Length-pos);
+                       }
+
+                       pos=req.LastIndexOf('.');
+                       String filetype=req.Substring(pos);
+
+                       Console.WriteLine("File is " + req);
+                       Console.WriteLine("Mime type is " + mime_types[filetype]);
+
+                       try {
+                               FileStream f=new FileStream(req, FileMode.Open, FileAccess.Read);
+                               byte[] fbuf=new byte[256];
+
+                               ReplyHeaders(sock, 200, "OK",
+                                            mime_types[filetype].ToString(),
+                                            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 () {
+                       // 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");
+
+                       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();
+                       }
+
+                       return(0);
+               }
+       }
+}