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); } }
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); }
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); }
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); }
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); }
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> <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> <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())); }
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())); }
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); }
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(); } } }
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; }
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(); } }
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; }
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; }
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; }
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; } }
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); }