Ejemplo n.º 1
0
		public WebAPIContext(WebAPIClient client, WebAPIMethod method, string uri)
		{
			Client = client;

			Method = method;
			Uri = uri;

			Request = new WebAPIRequest(Client);
			Response = new WebAPIResponse(Client);
		}
Ejemplo n.º 2
0
        public WebAPIContext(WebAPIClient client, WebAPIMethod method, string uri)
        {
            Client = client;

            Method = method;
            Uri    = uri;

            Request  = new WebAPIRequest(Client);
            Response = new WebAPIResponse(Client);
        }
Ejemplo n.º 3
0
        public WebAPIRequest(WebAPIClient client)
        {
            Client = client;

            Headers = new WebAPIHeaders();
            Queries = new WebAPIQueries();

            ContentType = FileMime.Default;
            Encoding    = Encoding.UTF8;

            Data   = String.Empty;
            Length = 0;
        }
Ejemplo n.º 4
0
		public WebAPIRequest(WebAPIClient client)
		{
			Client = client;

			Headers = new WebAPIHeaders();
			Queries = new WebAPIQueries();

			ContentType = FileMime.Default;
			Encoding = Encoding.UTF8;

			Data = String.Empty;
			Length = 0;
		}
Ejemplo n.º 5
0
        public WebAPIResponse(WebAPIClient client)
        {
            Client = client;

            Headers = new WebAPIHeaders();

            Compress = false;
            FreeData = true;

            Cache    = -1;
            FileName = String.Empty;
            Encoding = Encoding.UTF8;

            Status      = HttpStatusCode.OK;
            ContentType = FileMime.Default;
        }
Ejemplo n.º 6
0
		public WebAPIResponse(WebAPIClient client)
		{
			Client = client;

			Headers = new WebAPIHeaders();

			Compress = false;
			FreeData = true;

			Cache = -1;
			FileName = String.Empty;
			Encoding = Encoding.UTF8;

			Status = HttpStatusCode.OK;
			ContentType = FileMime.Default;
		}
Ejemplo n.º 7
0
        public static void Disconnect(WebAPIClient client)
        {
            VitaNexCore.TryCatch(
                () =>
            {
                lock (Clients)
                {
                    if (!Clients.Remove(client))
                    {
                        return;
                    }
                }

                if (!client.IsDisposed)
                {
                    var addr = client.Client.Client.RemoteEndPoint;

                    if (ClientDisconnected != null)
                    {
                        ClientDisconnected(client);
                    }

                    client.Close(true);

                    CSOptions.ToConsole("[{0}] Client Disconnected: {1}", Clients.Count, addr);
                }
            },
                e =>
            {
                CSOptions.ToConsole(e);

                lock (Clients)
                {
                    Clients.Remove(client);
                }

                client.Close(true);
            });
        }
Ejemplo n.º 8
0
        public static void Connect(WebAPIClient client)
        {
            VitaNexCore.TryCatch(
                () =>
            {
                lock (Clients)
                {
                    if (Clients.Contains(client))
                    {
                        return;
                    }

                    Clients.Add(client);
                }

                CSOptions.ToConsole("[{0}] Client Connected: {1}", Clients.Count, client.Client.Client.RemoteEndPoint);

                if (ClientConnected != null)
                {
                    ClientConnected(client);
                }

                if (!client.IsDisposed && client.Connected)
                {
                    ClientUtility.HandleConnection(client);
                }
                else
                {
                    Disconnect(client);
                }
            },
                e =>
            {
                CSOptions.ToConsole(e);

                Disconnect(client);
            });
        }
Ejemplo n.º 9
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);
            }