Exemple #1
0
        bool TryProcessSpecialCommand(HttpSocket s, string uri)
        {
            uri = uri.ToLowerInvariant();
            switch (uri)
            {
            case "/bye!":
                s.WriteTextResponse(200, "plain", ":(", false);
                ThreadPool.QueueUserWorkItem(delegate { Thread.Sleep(100); Stop(); });
                return(true);

            case "/ping!":
                s.WriteTextResponse(200, "plain", ":)", false);
                return(true);

            case "/sl.png!":
                s.WriteBinaryResponse(200, "image/png", GetResourceBytes("sl.png"), false);
                return(true);

            case "/slx.png!":
                s.WriteBinaryResponse(200, "image/png", GetResourceBytes("slx.png"), false);
                return(true);

            case "/style.css!":
                s.WriteTextResponse(200, "css", HtmlFormatter.Style, false);
                return(true);

            default:
                return(false);
            }
        }
Exemple #2
0
        bool TryProcessXapRequest(HttpSocket s, string path)
        {
            // must end with XAP
            if (string.Compare(Path.GetExtension(path), ".xap", StringComparison.OrdinalIgnoreCase) != 0)
            {
                return(false);
            }

            // XAP already there?
            if (File.Exists(path))
            {
                return(false);
            }

            // Directory must be present
            string dir = Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(path);

            if (!Directory.Exists(dir))
            {
                return(false);
            }

            byte[] xapBytes = null;

            try {
                xapBytes = XapBuilder.XapToMemory(dir);
            }
            catch (Exception e) {
                s.WriteErrorResponse(500, "error generating XAP: " + e.Message);
                return(true);
            }

            s.WriteBinaryResponse(200, "application/x-zip-compressed", xapBytes, false);
            return(true);
        }
Exemple #3
0
        bool TryProcessAssemblyRequest(HttpSocket s, string uri)
        {
            if (Chiron.UrlPrefix == "")
            {
                return(false);
            }

            int slash = uri.LastIndexOf('/');

            if (slash == -1)
            {
                return(false);
            }

            // must start with URL prefix
            if (string.Compare(uri.Substring(0, slash + 1), Chiron.UrlPrefix, StringComparison.OrdinalIgnoreCase) != 0)
            {
                return(false);
            }

            uri = uri.Substring(slash + 1);

            // must end with DLL or PDB
            if (string.Compare(Path.GetExtension(uri), ".dll", StringComparison.OrdinalIgnoreCase) != 0 &&
                string.Compare(Path.GetExtension(uri), ".pdb", StringComparison.OrdinalIgnoreCase) != 0)
            {
                return(false);
            }

            // get mime type
            string mimeType = HttpSocket.GetMimeType(uri);

            if (string.IsNullOrEmpty(mimeType))
            {
                s.WriteErrorResponse(403);
                return(true);
            }

            // see if the file exists in the assembly reference path
            string path = Chiron.TryGetAssemblyPath(uri);

            if (path == null)
            {
                return(false);
            }

            // read the file
            byte[] body = null;
            try {
                body = File.ReadAllBytes(path);
            } catch (Exception ex) {
                s.WriteErrorResponse(500, ex.Message + "\r\n" + ex.StackTrace);
                return(true);
            }

            // write the response
            s.WriteResponse(200, string.Format("Content-type: {0}\r\n", mimeType), body, false);
            return(true);
        }
Exemple #4
0
        void ProcessRequest(HttpSocket s)
        {
            HttpRequestData r    = null;
            string          path = null;

            // reply to unreadable requests
            if (!s.TryReadRequest(out r))
            {
                s.WriteErrorResponse(400, "Unparsable bad request");
            }
            // deny non-GET requests
            else if (r.Method != "GET")
            {
                s.WriteErrorResponse(405, "Method other than GET");
            }
            // process special commands
            else if (TryProcessSpecialCommand(s, r.Uri))
            {
                // done
            }
            // deny requests that cannot be mapped to disk
            else if (!TryMapUri(r.Uri, out path))
            {
                s.WriteErrorResponse(404, "URI cannot be mapped to disk");
            }
            // process file requests
            else if (TryProcessFileRequest(s, r.Uri, path))
            {
                // done
            }
            // process directory requests
            else if (TryProcessDirectoryRequest(s, r.Uri, path))
            {
                // done
            }
            // process XAP requests
            else if (TryProcessXapRequest(s, path))
            {
                // done
            }
            // process XAP listing requests
            else if (TryProcessXapListingRequest(s, r.Uri, path))
            {
                // done
            }
            // process requests for files contained in Chiron's localAssemblyPath
            else if (TryProcessBuildRequest(s, r.Uri))
            {
                // done
            }
            else
            {
                // not found
                s.WriteErrorResponse(404, "Resource not found");
            }

            Chiron.Log(s.StatusCode, (r != null && r.Uri != null ? r.Uri : "[unknown]"), s.BytesSent, s.Message);
        }
Exemple #5
0
        bool TryProcessDirectoryRequest(HttpSocket s, string uri, string path)
        {
            if (!Directory.Exists(path))
            {
                return(false);
            }

            string q = string.Empty;
            int    i = uri.IndexOf('?');

            if (i > 0)
            {
                q = uri.Substring(i); uri = uri.Substring(0, i);
            }

            // redirect to trailing '/' to fix-up relative links
            if (!uri.EndsWith("/"))
            {
                string newUri = uri + "/" + q;

                s.WriteResponse(302,
                                string.Format("Content-Type: text/html; charset=utf-8\r\nLocation: {0}\r\n", newUri),
                                Encoding.UTF8.GetBytes(
                                    string.Format(@"<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a href=""{0}"">here</a>.</h2></body></html>", newUri)),
                                false);

                return(true);
            }

            // get all files and subdirs
            FileSystemInfo[] infos;
            try {
                infos = new DirectoryInfo(path).GetFileSystemInfos();
            }
            catch {
                infos = new FileSystemInfo[0];
            }

            // decode %XX
            uri = DecodeUri(uri);

            // determine if parent is appropriate
            string parent = null;

            if (uri.Length > 1)
            {
                i      = uri.LastIndexOf('/', uri.Length - 2);
                parent = (i > 0) ? uri.Substring(0, i) : "/";
            }

            // write the response
            s.WriteTextResponse(200, "html", HtmlFormatter.FormatDirectoryListing(uri, parent, infos), false);
            return(true);
        }
Exemple #6
0
        public static string FormatDirectoryListing(string dirPath, string parentPath, IList <FileSystemInfo> elements)
        {
            StringBuilder sb = new StringBuilder();

            if (parentPath != null)
            {
                if (!parentPath.EndsWith("/"))
                {
                    parentPath += "/";
                }
                sb.AppendFormat("<a href=\"{0}\">[To Parent Directory]</a>\r\n", parentPath);
            }

            foreach (FileSystemInfo e in elements)
            {
                if (e is FileInfo)
                {
                    if (e.Name.EndsWith(".xap", StringComparison.OrdinalIgnoreCase))
                    {
                        // special handling of XAP files to allow listing requests
                        sb.AppendFormat(
                            @"{0,38:dddd, MMMM dd, yyyy hh:mm tt} {1,12:n0} <a href=""{2}/"">{3}</a>&nbsp;<a href=""{4}""><img border=""0"" src=""/slx.png!"" title=""Download XAP file"" /></a>
", e.LastWriteTime, ((FileInfo)e).Length, e.Name, e.Name, e.Name);
                    }
                    else if (string.IsNullOrEmpty(HttpSocket.GetMimeType(e.Name)))
                    {
                        sb.AppendFormat(
                            @"{0,38:dddd, MMMM dd, yyyy hh:mm tt} {1,12:n0} {2}</a>
", e.LastWriteTime, ((FileInfo)e).Length, e.Name);
                    }
                    else
                    {
                        sb.AppendFormat(
                            @"{0,38:dddd, MMMM dd, yyyy hh:mm tt} {1,12:n0} <a href=""{2}"">{3}</a>
", e.LastWriteTime, ((FileInfo)e).Length, e.Name, e.Name);
                    }
                }
                else if (e is DirectoryInfo)
                {
                    sb.AppendFormat(
                        @"{0,38:dddd, MMMM dd, yyyy hh:mm tt}        [dir] <a href=""{1}/"">{2}</a>&nbsp;<a href=""{3}.xap""><img border=""0"" src=""/slx.png!"" title=""Create XAP file from directory contents"" /></a>
",
                        e.LastWriteTime, e.Name, e.Name, e.Name);
                }
            }

            return(string.Format(DirListingFormat, dirPath, dirPath, sb.ToString(),
                                 typeof(Chiron).Assembly.GetName().Version.ToString()));
        }
Exemple #7
0
        public static string FormatXapListing(string xapPath, IList <ZipArchiveFile> elements)
        {
            StringBuilder sb = new StringBuilder();

            foreach (ZipArchiveFile f in elements)
            {
                if (string.IsNullOrEmpty(HttpSocket.GetMimeType(f.Name)))
                {
                    sb.AppendFormat(
                        @"{0,38:dddd, MMMM dd, yyyy hh:mm tt} {1,12:n0} {2}</a>
", f.LastWriteTime, f.Length, f.Name);
                }
                else
                {
                    sb.AppendFormat(
                        @"{0,38:dddd, MMMM dd, yyyy hh:mm tt} {1,12:n0} <a href=""{2}?{3}"">{4}</a>
", f.LastWriteTime, f.Length, xapPath, f.Name, f.Name);
                }
            }

            return(string.Format(XapListingFormat, xapPath, xapPath, sb.ToString(),
                                 typeof(Chiron).Assembly.GetName().Version.ToString()));
        }
Exemple #8
0
        bool TryProcessFileRequest(HttpSocket s, string uri, string path)
        {
            // path shouldn't end with '\' (that's for XAP listing)
            if (path.EndsWith(Path.DirectorySeparatorChar.ToString()))
            {
                return(false);
            }

            // file must exist
            if (!File.Exists(path))
            {
                return(false);
            }

            // check extension
            string mimeType = HttpSocket.GetMimeType(path);

            if (string.IsNullOrEmpty(mimeType))
            {
                s.WriteErrorResponse(403);
                return(true);
            }

            // read the file
            byte[] body = null;
            try {
                body = File.ReadAllBytes(path);
            }
            catch (Exception ex) {
                s.WriteErrorResponse(500, ex.Message + "\r\n" + ex.StackTrace);
                return(true);
            }

            // write the response
            s.WriteResponse(200, string.Format("Content-type: {0}\r\n", mimeType), body, false);
            return(true);
        }
Exemple #9
0
        bool TryProcessXapListingRequest(HttpSocket s, string uri, string path)
        {
            // path should end with '\' (for XAP listing)
            if (!path.EndsWith(Path.DirectorySeparatorChar.ToString()))
            {
                return(false);
            }
            path = path.Substring(0, path.Length - 1);

            // must end with XAP
            if (string.Compare(Path.GetExtension(path), ".xap", StringComparison.OrdinalIgnoreCase) != 0)
            {
                return(false);
            }

            // file must exist
            if (!File.Exists(path))
            {
                return(false);
            }

            // see if need to serve file from XAP
            string filename = null;
            int    iq       = uri.IndexOf('?');

            if (iq >= 0)
            {
                filename = uri.Substring(iq + 1);
            }

            ZipArchive xap = null;

            try {
                // open XAP file
                xap = new ZipArchive(path, FileAccess.Read);

                if (string.IsNullOrEmpty(filename))
                {
                    // list contents
                    List <ZipArchiveFile> xapContents = new List <ZipArchiveFile>();
                    foreach (KeyValuePair <string, ZipArchiveFile> p in xap.entries)
                    {
                        xapContents.Add(p.Value);
                    }
                    s.WriteTextResponse(200, "html", HtmlFormatter.FormatXapListing(uri, xapContents), false);
                    return(true);
                }

                // server file from XAP
                ZipArchiveFile f = null;
                if (!xap.entries.TryGetValue(filename, out f))
                {
                    s.WriteErrorResponse(404, "Resource not found in XAP");
                    return(true);
                }

                // check mime type
                string mimeType = HttpSocket.GetMimeType(filename);
                if (string.IsNullOrEmpty(mimeType))
                {
                    s.WriteErrorResponse(403);
                    return(true);
                }

                // get the content
                byte[] body = new byte[(int)f.Length];
                if (body.Length > 0)
                {
                    using (Stream fs = f.OpenRead()) {
                        fs.Read(body, 0, body.Length);
                    }
                }

                // write the resposne
                s.WriteResponse(200, string.Format("Content-type: {0}\r\n", mimeType), body, false);
                return(true);
            }
            catch {
                s.WriteErrorResponse(500, "error reading XAP");
                return(true);
            }
            finally {
                if (xap != null)
                {
                    xap.Close();
                }
            }
        }
Exemple #10
0
        bool TryProcessAssemblyRequest(HttpSocket s, string uri) {
            if (Chiron.UrlPrefix == "")
                return false;

            int slash = uri.LastIndexOf('/');
            if (slash == -1)
                return false;

            // must start with URL prefix
            if (string.Compare(uri.Substring(0, slash + 1), Chiron.UrlPrefix, StringComparison.OrdinalIgnoreCase) != 0)
                return false;

            uri = uri.Substring(slash + 1);

            // must end with DLL or PDB
            if (string.Compare(Path.GetExtension(uri), ".dll", StringComparison.OrdinalIgnoreCase) != 0 &&
                string.Compare(Path.GetExtension(uri), ".pdb", StringComparison.OrdinalIgnoreCase) != 0)
                return false;

            // get mime type
            string mimeType = HttpSocket.GetMimeType(uri);
            if (string.IsNullOrEmpty(mimeType)) {
                s.WriteErrorResponse(403);
                return true;
            }

            // see if the file exists in the assembly reference path
            string path = Chiron.TryGetAssemblyPath(uri);
            if (path == null)
                return false;

            // read the file
            byte[] body = null;
            try {
                body = File.ReadAllBytes(path);
            } catch (Exception ex) {
                s.WriteErrorResponse(500, ex.Message + "\r\n" + ex.StackTrace);
                return true;
            }

            // write the response
            s.WriteResponse(200, string.Format("Content-type: {0}\r\n", mimeType), body, false);
            return true;
        }
Exemple #11
0
        bool TryProcessXapListingRequest(HttpSocket s, string uri, string path) {
            // path should end with '\' (for XAP listing)
            if (!path.EndsWith(Path.DirectorySeparatorChar.ToString())) return false;
            path = path.Substring(0, path.Length - 1);

            // must end with XAP
            if (string.Compare(Path.GetExtension(path), ".xap", StringComparison.OrdinalIgnoreCase) != 0)
                return false;

            // file must exist
            if (!File.Exists(path)) return false;

            // see if need to serve file from XAP
            string filename = null;
            int iq = uri.IndexOf('?');
            if (iq >= 0) filename = uri.Substring(iq + 1);

            ZipArchive xap = null;

            try {
                // open XAP file
                xap = new ZipArchive(path, FileAccess.Read);

                if (string.IsNullOrEmpty(filename)) {
                    // list contents
                    List<ZipArchiveFile> xapContents = new List<ZipArchiveFile>();
                    foreach (KeyValuePair<string, ZipArchiveFile> p in xap.entries) xapContents.Add(p.Value);
                    s.WriteTextResponse(200, "html", HtmlFormatter.FormatXapListing(uri, xapContents), false);
                    return true;
                }

                // server file from XAP
                ZipArchiveFile f = null;
                if (!xap.entries.TryGetValue(filename, out f)) {
                    s.WriteErrorResponse(404, "Resource not found in XAP");
                    return true;
                }

                // check mime type
                string mimeType = HttpSocket.GetMimeType(filename);
                if (string.IsNullOrEmpty(mimeType)) {
                    s.WriteErrorResponse(403);
                    return true;
                }

                // get the content
                byte[] body = new byte[(int)f.Length];
                if (body.Length > 0) {
                    using (Stream fs = f.OpenRead()) {
                        fs.Read(body, 0, body.Length);
                    }
                }

                // write the resposne
                s.WriteResponse(200, string.Format("Content-type: {0}\r\n", mimeType), body, false);
                return true;
            }
            catch {
                s.WriteErrorResponse(500, "error reading XAP");
                return true;
            }
            finally {
                if (xap != null) xap.Close();
            }
        }
Exemple #12
0
        bool TryProcessXapRequest(HttpSocket s, string path) {
            // must end with XAP
            if (string.Compare(Path.GetExtension(path), ".xap", StringComparison.OrdinalIgnoreCase) != 0)
                return false;

            // XAP already there?
            if (File.Exists(path))
                return false;

            // Directory must be present
            string dir = Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(path);
            if (!Directory.Exists(dir))
                return false;

            byte[] xapBytes = null;

            try {
                xapBytes = XapBuilder.XapToMemory(dir);
            }
            catch (Exception e) {
                s.WriteErrorResponse(500, "error generating XAP: " + e.Message);
                return true;
            }

            s.WriteBinaryResponse(200, "application/x-zip-compressed", xapBytes, false);
            return true;
        }
Exemple #13
0
        bool TryProcessDirectoryRequest(HttpSocket s, string uri, string path) {
            if (!Directory.Exists(path)) return false;

            string q = string.Empty;
            int i = uri.IndexOf('?');
            if (i > 0) { q = uri.Substring(i); uri = uri.Substring(0, i); }

            // redirect to trailing '/' to fix-up relative links
            if (!uri.EndsWith("/")) {
                string newUri = uri + "/" + q;

                s.WriteResponse(302,
                    string.Format("Content-Type: text/html; charset=utf-8\r\nLocation: {0}\r\n", newUri),
                    Encoding.UTF8.GetBytes(
string.Format(@"<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a href=""{0}"">here</a>.</h2></body></html>", newUri)),
                    false);

                return true;
            }

            // get all files and subdirs
            FileSystemInfo[] infos;
            try {
                infos = new DirectoryInfo(path).GetFileSystemInfos();
            }
            catch {
                infos = new FileSystemInfo[0];
            }

            // decode %XX
            uri = DecodeUri(uri);

            // determine if parent is appropriate
            string parent = null;
            if (uri.Length > 1) {
                i = uri.LastIndexOf('/', uri.Length-2);
                parent = (i > 0) ? uri.Substring(0, i) : "/";
            }

            // write the response
            s.WriteTextResponse(200, "html", HtmlFormatter.FormatDirectoryListing(uri, parent, infos), false);
            return true;
        }
Exemple #14
0
        bool TryProcessFileRequest(HttpSocket s, string uri, string path) {
            // path shouldn't end with '\' (that's for XAP listing)
            if (path.EndsWith(Path.DirectorySeparatorChar.ToString())) return false;

            // file must exist
            if (!File.Exists(path)) return false;

            // check extension
            string mimeType = HttpSocket.GetMimeType(path);
            if (string.IsNullOrEmpty(mimeType)) {
                s.WriteErrorResponse(403);
                return true;
            }

            // read the file
            byte[] body = null;
            try {
                body = File.ReadAllBytes(path);
            }
            catch (Exception ex) {
                s.WriteErrorResponse(500, ex.Message + "\r\n" + ex.StackTrace);
                return true;
            }

            // write the response
            s.WriteResponse(200, string.Format("Content-type: {0}\r\n", mimeType), body, false);
            return true;
        }
Exemple #15
0
 bool TryProcessSpecialCommand(HttpSocket s, string uri) {
     uri = uri.ToLowerInvariant();
     switch (uri) {
         case "/bye!":
             s.WriteTextResponse(200,  "plain", ":(", false);
             ThreadPool.QueueUserWorkItem(delegate { Thread.Sleep(100); Stop(); });
             return true;
         case "/ping!":
             s.WriteTextResponse(200, "plain", ":)", false);
             return true;
         case "/sl.png!":
             s.WriteBinaryResponse(200, "image/png", GetResourceBytes("sl.png"), false);
             return true;
         case "/slx.png!":
             s.WriteBinaryResponse(200, "image/png", GetResourceBytes("slx.png"), false);
             return true;
         case "/style.css!":
             s.WriteTextResponse(200, "css", HtmlFormatter.Style, false);
             return true;
         default:
             return false;
     }
 }
Exemple #16
0
        void ProcessRequest(HttpSocket s) {
            HttpRequestData r = null;
            string path = null;

            // reply to unreadable requests
            if (!s.TryReadRequest(out r)) {
                s.WriteErrorResponse(400, "Unparsable bad request");
            }
            // deny non-GET requests
            else if (r.Method != "GET") {
                s.WriteErrorResponse(405, "Method other than GET");
            }
            // process special commands
            else if (TryProcessSpecialCommand(s, r.Uri)) {
                // done
            }
            // deny requests that cannot be mapped to disk
            else if (!TryMapUri(r.Uri, out path)) {
                s.WriteErrorResponse(404, "URI cannot be mapped to disk");
            }
            // process file requests
            else if (TryProcessFileRequest(s, r.Uri, path)) {
                // done
            }
            // process directory requests
            else if (TryProcessDirectoryRequest(s, r.Uri, path)) {
                // done
            }
            // process XAP requests
            else if (TryProcessXapRequest(s, path)) {
                // done
            }
            // process XAP listing requests
            else if (TryProcessXapListingRequest(s, r.Uri, path)) {
                // done
            }
            // process requests for assemblies contained in Chiron's localAssemblyPath
            else if (TryProcessAssemblyRequest(s, r.Uri)) {
                // done
            } else {
                // not found
                s.WriteErrorResponse(404, "Resource not found");
            }

            Chiron.Log(s.StatusCode, (r != null && r.Uri != null ? r.Uri : "[unknown]"), s.BytesSent, s.Message);
        }