private static void HandleRoot(WebAPIContext context) { if (!CSOptions.WebServer) { context.Response.Status = HttpStatusCode.ServiceUnavailable; return; } var root = IOUtility.EnsureDirectory(Core.BaseDirectory + "/web"); var path = IOUtility.GetSafeFilePath(root + "/" + context.Uri, true); if (Path.HasExtension(path)) { var file = new FileInfo(path); context.Response.FileName = file.Name; context.Response.Data = file.Directory; } else if (Directory.Exists(path)) { context.Response.Data = new DirectoryInfo(path); } else { context.Response.Status = HttpStatusCode.BadRequest; } }
private static bool FromImage(WebAPIContext context, Image image, out byte[] buffer, out int length) { buffer = _EmptyBuffer; length = 0; if (image == null) { context.Response.Status = HttpStatusCode.NotFound; return(false); } using (var ms = new MemoryStream()) { lock (_Lock) { try { image.Save(ms, ImageFormat.Png); } catch { using (var clone = new Bitmap(image)) { clone.Save(ms, ImageFormat.Png); } } } buffer = ms.ToArray(); length = buffer.Length; } if (String.IsNullOrWhiteSpace(context.Response.FileName)) { context.Response.FileName = image.GetHashCode() + ".png"; } else if (!Insensitive.EndsWith(context.Response.FileName, ".png")) { context.Response.FileName += ".png"; } context.Response.ContentType = context.Response.FileName; context.Response.Status = HttpStatusCode.OK; return(true); }
private static bool FromFile( WebAPIContext context, FileInfo file, out byte[] buffer, out int length, out bool encoded) { buffer = _EmptyBuffer; length = 0; encoded = false; if (file == null) { context.Response.Status = HttpStatusCode.NotFound; return(false); } file.Refresh(); if (!file.Exists) { context.Response.Status = HttpStatusCode.NotFound; return(false); } if (file.Length > CSOptions.MaxSendBufferSizeBytes) { context.Response.Status = HttpStatusCode.RequestEntityTooLarge; return(false); } buffer = file.ReadAllBytes(); length = buffer.Length; context.Response.FileName = file.Name; context.Response.ContentType = file.GetMimeType(); context.Response.Status = HttpStatusCode.OK; encoded = context.Response.ContentType.IsCommonText(); return(true); }
private static void HandleWebRequest(WebAPIContext context) { if (context.Request.Queries["banner"] != null) { context.Response.Data = GetBanner(false); context.Response.ContentType = "png"; } else { WebStatsRequestFlags flags; if (context.Request.Queries.Count > 0) { if (context.Request.Queries["flags"] != null) { var f = context.Request.Queries["flags"]; int v; if (f.StartsWith("0x")) { if (!Int32.TryParse(f.Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out v) || v < 0) { v = 0; } } else if (!Int32.TryParse(f, out v) || v < 0) { v = 0; } flags = (WebStatsRequestFlags)v; } else { flags = WebStatsRequestFlags.Server | WebStatsRequestFlags.Stats | WebStatsRequestFlags.Players; bool? server = null, stats = null, players = null; foreach (var q in context.Request.Queries) { var value = !q.Value.EqualsAny(true, "false", "no", "off", "disabled", "0", String.Empty); if (Insensitive.Equals(q.Key, "server")) { server = value; } else if (Insensitive.Equals(q.Key, "stats")) { stats = value; } else if (Insensitive.Equals(q.Key, "players")) { players = value; } } if (server != null && !server.Value) { flags &= ~WebStatsRequestFlags.Server; } if (stats != null && !stats.Value) { flags &= ~WebStatsRequestFlags.Stats; } if (players != null && !players.Value) { flags &= ~WebStatsRequestFlags.Players; } } } else { flags = WebStatsRequestFlags.Server | WebStatsRequestFlags.Stats | WebStatsRequestFlags.Players; } context.Response.Data = GetJson(flags, false); context.Response.ContentType = "json"; } }
public static bool HandleConnection(WebAPIClient client) { using (client) { KeyValueString[] headers; if (!client.ReceiveHeaders(out headers)) { return(false); } var m = headers[0].Key; if (String.IsNullOrWhiteSpace(m)) { return(false); } WebAPIMethod method; if (!Enum.TryParse(m, out method)) { return(false); } var u = headers[0].Value; var i = u.LastIndexOf(' '); if (i > -1) { u = u.Substring(0, i); } u = HttpUtility.UrlDecode(u); if (String.IsNullOrWhiteSpace(u)) { u = "/"; } using (var context = new WebAPIContext(client, method, u)) { foreach (var h in headers.Skip(1)) { context.Request.Headers[h.Key] = h.Value; } foreach (var q in DecodeQuery(u)) { context.Request.Queries[q.Key] = q.Value; } if (!String.IsNullOrWhiteSpace(context.Request.Headers["Content-Type"])) { context.Request.ContentType = context.Request.Headers["Content-Type"]; } var length = 0; if (!String.IsNullOrWhiteSpace(context.Request.Headers["Content-Length"])) { Int32.TryParse(context.Request.Headers["Content-Length"], out length); } if (Insensitive.Contains(context.Request.Headers["Accept-Encoding"], "deflate")) { context.Response.Compress = true; } var encoding = Encoding.UTF8; if (!String.IsNullOrWhiteSpace(context.Request.Headers["Accept-Charset"])) { var h = context.Request.Headers["Accept-Charset"].Trim(); if (h.Contains(',')) { foreach (var e in h.Split(',')) { try { encoding = Encoding.GetEncoding(e.Trim()); } catch { encoding = Encoding.UTF8; } } } else { try { encoding = Encoding.GetEncoding(h); } catch { encoding = Encoding.UTF8; } } } context.Request.Encoding = context.Response.Encoding = encoding; context.Response.Headers["Date"] = DateTime.UtcNow.ToSimpleString("D, d M y t@h:m:s@") + " GMT"; context.Response.Headers["Server"] = String.Format( "Vita-Nex: Core/{0} [{1}/{2}] ({3})", VitaNexCore.Version, CSOptions.ServiceName, CSOptions.ServiceVersion, ServerList.ServerName); if (!context.Method.AnyFlags(WebAPIMethod.OPTIONS, WebAPIMethod.GET, WebAPIMethod.POST)) { context.Response.Headers["Allow"] = "OPTIONS, GET, POST"; context.Response.Headers["Connection"] = "close"; client.Send(false, "HTTP/1.1 405 Method Not Allowed\r\n" + context.Response.Headers, Encoding.ASCII); return(true); } if (context.Method == WebAPIMethod.OPTIONS) { if (!String.IsNullOrWhiteSpace(context.Request.Headers["Origin"])) { context.Response.Headers["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS"; context.Response.Headers["Access-Control-Allow-Headers"] = "Origin, X-Requested-With, Content-Type, Accept"; context.Response.Headers["Access-Control-Allow-Origin"] = context.Request.Headers["Origin"]; } context.Response.Headers["Vary"] = "Accept-Encoding"; context.Response.Headers["Keep-Alive"] = "timeout=2, max=120"; context.Response.Headers["Connection"] = "keep-alive"; client.Send(false, "HTTP/1.1 200 OK\r\n" + context.Response.Headers, Encoding.ASCII); return(true); } if (length > CSOptions.MaxReceiveBufferSizeBytes) { context.Response.Headers["Connection"] = "close"; client.Send(false, "HTTP/1.1 413 Request Entity Too Large\r\n" + context.Response.Headers, Encoding.ASCII); return(true); } WebAPIHandler handler; var key = u.Trim(); var idx = u.IndexOf('?'); if (idx > 0) { key = u.Substring(0, idx); } if (key.Length > 1) { key = key.TrimEnd('/'); } if (!Handlers.TryGetValue(key, out handler) || handler == null) { key = "/"; } byte[] buffer; if (handler != null || (Handlers.TryGetValue(key, out handler) && handler != null)) { try { if (length > 0) { string data; client.Receive(false, context.Request.Encoding, out data, out buffer, out length); context.Request.Data = data; context.Request.Length = length; } handler.Handler(context); } catch (Exception e) { CSOptions.ToConsole(e); if (e is InternalBufferOverflowException) { context.Response.Status = HttpStatusCode.RequestEntityTooLarge; } else { context.Response.Status = HttpStatusCode.InternalServerError; } } } else { context.Response.Status = HttpStatusCode.NotFound; } if (ContextHandler != null) { ContextHandler(context); } string status; if ((int)context.Response.Status >= 400) { context.Response.Headers["Connection"] = "close"; status = String.Format("{0} {1}", (int)context.Response.Status, context.Response.Status.ToString().SpaceWords()); client.Send(false, "HTTP/1.1 " + status + "\r\n" + context.Response.Headers, Encoding.ASCII); return(true); } var encoded = false; var compressed = false; try { GetResponseBuffer(context, out buffer, out length, out encoded); if (length > 0 && context.Response.Compress) { client.Compress(ref buffer, ref length); compressed = true; } } catch (Exception e) { CSOptions.ToConsole(e); buffer = _EmptyBuffer; length = 0; if (e is InternalBufferOverflowException) { context.Response.Status = HttpStatusCode.RequestEntityTooLarge; } else { context.Response.Status = HttpStatusCode.InternalServerError; } } if (!String.IsNullOrWhiteSpace(context.Request.Headers["Origin"])) { context.Response.Headers["Access-Control-Allow-Origin"] = context.Request.Headers["Origin"]; } if (String.IsNullOrWhiteSpace(context.Response.Headers["Vary"])) { context.Response.Headers["Vary"] = "Accept-Encoding"; } if (length > 0) { if (compressed) { context.Response.Headers["Content-Encoding"] = "deflate"; } if (context.Response.ContentType.IsDefault && !String.IsNullOrWhiteSpace(context.Response.FileName)) { var mime = FileMime.Lookup(context.Response.FileName); if (!mime.IsDefault && mime != context.Response.ContentType) { context.Response.ContentType = mime; } } var contentType = context.Response.ContentType.MimeType; if (encoded) { contentType = String.Format("{0}; charset={1}", contentType, context.Response.Encoding.WebName); } context.Response.Headers["Content-Type"] = contentType; context.Response.Headers["Content-Length"] = length.ToString(); if (!String.IsNullOrWhiteSpace(context.Response.FileName)) { var inline = context.Response.ContentType.IsCommonText() || context.Response.ContentType.IsCommonImage(); var disp = inline ? "inline" : "attachment"; disp = String.Format("{0}; filename=\"{1}\"", disp, context.Response.FileName); context.Response.Headers["Content-Disposition"] = disp; } } if (context.Response.Cache < 0) { context.Response.Headers["Pragma"] = "no-cache"; context.Response.Headers["Cache-Control"] = "no-cache, no-store"; } else if (context.Response.Cache > 0) { context.Response.Headers["Cache-Control"] = "max-age=" + context.Response.Cache; } if (String.IsNullOrWhiteSpace(context.Response.Headers["Connection"])) { context.Response.Headers["Connection"] = "close"; } status = String.Format("{0} {1}", (int)context.Response.Status, context.Response.Status.ToString().SpaceWords()); client.Send(false, "HTTP/1.1 " + status + "\r\n" + context.Response.Headers, Encoding.ASCII); if (buffer.Length > 0 && length > 0) { client.Send(false, ref buffer, ref length); } } } return(true); }
private static void GetResponseBuffer(WebAPIContext context, out byte[] buffer, out int length, out bool encoded) { buffer = _EmptyBuffer; length = 0; encoded = false; if (context.Response.Data == null) { return; } if (context.Response.Data is byte[]) { buffer = (byte[])context.Response.Data; length = buffer.Length; encoded = context.Response.ContentType.IsCommonText(); return; } if (context.Response.Data is Image) { var image = (Image)context.Response.Data; if (FromImage(context, image, out buffer, out length)) { context.Response.Status = HttpStatusCode.OK; } return; } if (context.Response.Data is DirectoryInfo) { var dir = (DirectoryInfo)context.Response.Data; FileInfo file = null; if (!String.IsNullOrWhiteSpace(context.Response.FileName)) { file = new FileInfo(IOUtility.GetSafeFilePath(dir + "/" + context.Response.FileName, true)); } if (file == null || !file.Exists) { file = new FileInfo(IOUtility.GetSafeFilePath(dir + "/index.html", true)); } if (FromFile(context, file, out buffer, out length, out encoded) || (CSOptions.DirectoryIndex && FromDir(context, dir, out buffer, out length, out encoded))) { context.Response.Status = HttpStatusCode.OK; } return; } if (context.Response.Data is FileInfo) { var file = (FileInfo)context.Response.Data; if (FromFile(context, file, out buffer, out length, out encoded)) { context.Response.Status = HttpStatusCode.OK; } return; } string response; if (context.Response.Data is string || context.Response.Data is StringBuilder || context.Response.Data is ValueType) { response = context.Response.Data.ToString(); if (!context.Response.ContentType.IsCommonText()) { context.Response.ContentType = "txt"; } } else { JsonException je; response = Json.Encode(context.Response.Data, out je) ?? String.Empty; if (je != null) { response = je.ToString(); if (!context.Response.ContentType.IsCommonText()) { context.Response.ContentType = "txt"; } } else if (!String.IsNullOrWhiteSpace(response)) { context.Response.ContentType = "json"; } } if (String.IsNullOrWhiteSpace(context.Response.FileName)) { context.Response.FileName = // Math.Abs(response.GetHashCode()) + "." + // context.Response.ContentType.Extension; } encoded = true; context.Client.Encode(context.Response.Encoding, response, out buffer, out length); context.Response.Status = HttpStatusCode.OK; }
private static bool FromDir(WebAPIContext c, DirectoryInfo dir, out byte[] buffer, out int length, out bool enc) { buffer = _EmptyBuffer; length = 0; enc = false; if (dir == null) { c.Response.Status = HttpStatusCode.NotFound; return(false); } dir.Refresh(); if (!dir.Exists) { c.Response.Status = HttpStatusCode.NotFound; return(false); } var name = "/" + dir.Name; if (Insensitive.Equals(dir.Name, "web")) { name = "/"; } var html = new StringBuilder(); html.AppendLine("<!DOCTYPE html>"); html.AppendLine("<html>"); html.AppendLine("\t<head>"); html.AppendLine("\t\t<title>Index of {0}</title>", name); html.AppendLine("\t</head>"); html.AppendLine("\t<body>"); html.AppendLine("\t\t<h1>Index of {0}</h1>", name); html.AppendLine("\t\t<ul>"); if (name != "/") { html.AppendLine("\t\t\t<li><a href='/'>Parent Directory</a></li>"); } foreach (var o in dir.EnumerateFileSystemInfos("*", SearchOption.TopDirectoryOnly).OrderByNatural(o => o.Name)) { if (o is FileInfo) { html.AppendLine("\t\t\t<li><a href='{0}' alt='{0}'>{0}</a></li>", o.Name); } else if (o is DirectoryInfo) { html.AppendLine("\t\t\t<li><a href='{0}/' alt='{0}'>{0}/</a></li>", o.Name); } } html.AppendLine("\t\t</ul>"); html.AppendLine("\t</body>"); html.AppendLine("</html>"); enc = true; c.Client.Encode(c.Response.Encoding, html.ToString(), out buffer, out length); c.Response.FileName = "index.html"; c.Response.ContentType = "html"; c.Response.Status = HttpStatusCode.OK; return(true); }
private static void GetResponseBuffer(WebAPIContext context, out byte[] buffer, out int length, out bool encoded) { buffer = _EmptyBuffer; length = 0; encoded = false; if (context.Response.Data == null) { return; } if (context.Response.Data is byte[]) { buffer = (byte[])context.Response.Data; length = buffer.Length; encoded = context.Response.ContentType.IsCommonText(); return; } if (context.Response.Data is Image) { var image = (Image)context.Response.Data; var path = VitaNexCore.CacheDirectory + "/WebAPI/Images/" + image.GetHashCode() + ".png"; var file = IOUtility.EnsureFile(path, true); image.Save(file.FullName, ImageFormat.Png); if (FromFile(context, file, out buffer, out length, out encoded)) { context.Response.Status = HttpStatusCode.OK; } file.Delete(); return; } if (context.Response.Data is DirectoryInfo) { var dir = (DirectoryInfo)context.Response.Data; FileInfo file = null; if (!String.IsNullOrWhiteSpace(context.Response.FileName)) { file = new FileInfo(IOUtility.GetSafeFilePath(dir + "/" + context.Response.FileName, true)); } if (file == null || !file.Exists) { file = new FileInfo(IOUtility.GetSafeFilePath(dir + "/index.html", true)); } if (FromFile(context, file, out buffer, out length, out encoded) || (CSOptions.DirectoryIndex && FromDirectory(context, dir, out buffer, out length, out encoded))) { context.Response.Status = HttpStatusCode.OK; } return; } if (context.Response.Data is FileInfo) { var file = (FileInfo)context.Response.Data; if (FromFile(context, file, out buffer, out length, out encoded)) { context.Response.Status = HttpStatusCode.OK; } return; } string response; if (context.Response.Data is string || context.Response.Data is StringBuilder || context.Response.Data is ValueType) { response = context.Response.Data.ToString(); if (!context.Response.ContentType.IsCommonText()) { context.Response.ContentType = "txt"; } } else { response = Json.Encode(context.Response.Data); context.Response.ContentType = "json"; } if (String.IsNullOrWhiteSpace(context.Response.FileName)) { context.Response.FileName = Math.Abs(response.GetHashCode()) + "." + context.Response.ContentType.Extension; } context.Client.Encode(context.Response.Encoding, response, out buffer, out length); encoded = true; }
private static void HandleWebForm(WebAPIContext context) { if (!CMOptions.WebForm.Enabled) { context.Response.Data = String.Empty; context.Response.Status = HttpStatusCode.NoContent; return; } context.Response.Data = CMOptions.WebForm.Generate(); context.Response.ContentType = "html"; }
private static void HandleIPN(WebAPIContext context) { var test = context.Request.Queries["test"] != null || Insensitive.Contains(context.Request.Data, "test_ipn=1"); var endpoint = test ? "www.sandbox" : "www"; var paypal = String.Format("https://{0}.paypal.com/cgi-bin/webscr", endpoint); WebAPI.BeginRequest(paypal, context.Request.Data, BeginVerification, EndVerification); }
private static void HandleAccountCheck(WebAPIContext context) { if (!String.IsNullOrWhiteSpace(context.Request.Queries["username"])) { var acc = Accounts.GetAccount(context.Request.Queries["username"]); context.Response.Data = acc != null ? "VALID" : "INVALID"; } else { context.Response.Data = "INVALID"; } context.Response.ContentType = "txt"; }