Example #1
0
        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;
            }
        }
Example #2
0
            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);
            }
Example #3
0
            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);
            }
Example #4
0
		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";
			}
		}
Example #5
0
            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);
            }
Example #6
0
            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;
            }
Example #7
0
            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);
            }
Example #8
0
            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;
            }
Example #9
0
		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";
		}
Example #10
0
		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);
		}
Example #11
0
		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";
		}