/// <summary>
        /// Executes the PUT method on the resource.
        /// </summary>
        /// <param name="Request">HTTP Request</param>
        /// <param name="Response">HTTP Response</param>
        /// <exception cref="HttpException">If an error occurred when processing the method.</exception>
        public async Task PUT(HttpRequest Request, HttpResponse Response)
        {
            string FullPath = this.GetFullPath(Request);

            if (!Request.HasData)
            {
                throw new BadRequestException();
            }

            string Folder = Path.GetDirectoryName(FullPath);

            if (!Directory.Exists(Folder))
            {
                Directory.CreateDirectory(Folder);
            }

            using (FileStream f = File.Create(FullPath))
            {
                Request.DataStream.CopyTo(f);
            }

            Response.StatusCode = 201;
            await Response.SendResponse();

            Response.Dispose();
        }
        private async Task RaiseFileNotFound(string FullPath, HttpRequest Request, HttpResponse Response)
        {
            NotFoundException        ex = new NotFoundException("File not found: " + FullPath.Substring(this.folderPath.Length));
            FileNotFoundEventHandler h  = this.FileNotFound;

            if (!(h is null))
            {
                FileNotFoundEventArgs e = new FileNotFoundEventArgs(ex, FullPath, Request, Response);

                try
                {
                    h(this, e);
                }
                catch (Exception ex2)
                {
                    Log.Critical(ex2);
                }

                ex = e.Exception;
                if (ex is null)
                {
                    return;                             // Sent asynchronously from event handler.
                }
            }

            Log.Warning("File not found.", FullPath, Request.RemoteEndPoint, "FileNotFound");

            await Response.SendResponse(ex);

            Response.Dispose();
        }
        /// <summary>
        /// Executes the ranged PUT method on the resource.
        /// </summary>
        /// <param name="Request">HTTP Request</param>
        /// <param name="Response">HTTP Response</param>
        /// <param name="Interval">Content byte range.</param>
        /// <exception cref="HttpException">If an error occurred when processing the method.</exception>
        public async Task PUT(HttpRequest Request, HttpResponse Response, ContentByteRangeInterval Interval)
        {
            string FullPath = this.GetFullPath(Request);

            if (!Request.HasData)
            {
                throw new BadRequestException();
            }

            string Folder = Path.GetDirectoryName(FullPath);

            if (!Directory.Exists(Folder))
            {
                Directory.CreateDirectory(Folder);
            }

            using (FileStream f = File.Exists(FullPath) ? File.OpenWrite(FullPath) : File.Create(FullPath))
            {
                long l;

                if ((l = Interval.First - f.Length) > 0)
                {
                    f.Position = f.Length;

                    int    BlockSize = (int)Math.Min(BufferSize, Interval.First - f.Length);
                    byte[] Block     = new byte[BlockSize];
                    int    i;

                    while (l > 0)
                    {
                        i = (int)Math.Min(l, BlockSize);
                        f.Write(Block, 0, i);
                        l -= i;
                    }
                }
                else
                {
                    f.Position = Interval.First;
                }

                Request.DataStream.CopyTo(f);
            }

            Response.StatusCode = 201;
            await Response.SendResponse();

            Response.Dispose();
        }
        /// <summary>
        /// Executes the DELETE method on the resource.
        /// </summary>
        /// <param name="Request">HTTP Request</param>
        /// <param name="Response">HTTP Response</param>
        /// <exception cref="HttpException">If an error occurred when processing the method.</exception>
        public void DELETE(HttpRequest Request, HttpResponse Response)
        {
            string FullPath = this.GetFullPath(Request);

            if (File.Exists(FullPath))
            {
                File.Delete(FullPath);
            }
            else if (Directory.Exists(FullPath))
            {
                Directory.Delete(FullPath, true);
            }
            else
            {
                throw new NotFoundException("File not found: " + FullPath.Substring(this.folderPath.Length));
            }

            Response.SendResponse();
            Response.Dispose();
        }
        /// <summary>
        /// Executes the DELETE method on the resource.
        /// </summary>
        /// <param name="Request">HTTP Request</param>
        /// <param name="Response">HTTP Response</param>
        /// <exception cref="HttpException">If an error occurred when processing the method.</exception>
        public async Task DELETE(HttpRequest Request, HttpResponse Response)
        {
            string FullPath = this.GetFullPath(Request);

            if (File.Exists(FullPath))
            {
                File.Delete(FullPath);
            }
            else if (Directory.Exists(FullPath))
            {
                Directory.Delete(FullPath, true);
            }
            else
            {
                throw new NotFoundException("File not found: " + Request.SubPath);
            }

            await Response.SendResponse();

            Response.Dispose();
        }
Exemple #6
0
        /// <summary>
        /// Executes a method on the resource. The default behaviour is to call the corresponding execution methods defined in the specialized
        /// interfaces <see cref="IHttpGetMethod"/>, <see cref="IHttpPostMethod"/>, <see cref="IHttpPutMethod"/> and <see cref="IHttpDeleteMethod"/>
        /// if they are defined for the resource.
        /// </summary>
        /// <param name="Server">HTTP Server</param>
        /// <param name="Request">HTTP Request</param>
        /// <param name="Response">HTTP Response</param>
        /// <exception cref="HttpException">If an error occurred when processing the method.</exception>
        public virtual void Execute(HttpServer Server, HttpRequest Request, HttpResponse Response)
        {
            HttpRequestHeader Header = Request.Header;
            string            Method = Request.Header.Method;

            if (this.UserSessions)
            {
                HttpFieldCookie Cookie;
                string          HttpSessionID;

                if ((Cookie = Request.Header.Cookie) is null || string.IsNullOrEmpty(HttpSessionID = Cookie["HttpSessionID"]))
                {
                    HttpSessionID = System.Convert.ToBase64String(Hashes.ComputeSHA512Hash(Guid.NewGuid().ToByteArray()));
                    Response.SetCookie(new HTTP.Cookie("HttpSessionID", HttpSessionID, null, "/", null, false, true));
                }

                Request.Session = Server.GetSession(HttpSessionID);
            }

            switch (Method)
            {
            case "GET":
            case "HEAD":
                if (this.getRanges != null)
                {
                    Response.SetHeader("Accept-Ranges", "bytes");

                    if (Header.Range != null)
                    {
                        ByteRangeInterval FirstInterval = Header.Range.FirstInterval;
                        if (FirstInterval is null)
                        {
                            throw new RangeNotSatisfiableException();
                        }
                        else
                        {
                            Response.OnlyHeader    = Method == "HEAD";
                            Response.StatusCode    = 206;
                            Response.StatusMessage = "Partial Content";

                            this.getRanges.GET(Request, Response, FirstInterval);
                        }
                    }
                    else
                    {
                        Response.OnlyHeader = Method == "HEAD";

                        if (this.get != null)
                        {
                            this.get.GET(Request, Response);
                        }
                        else
                        {
                            this.getRanges.GET(Request, Response, new ByteRangeInterval(0, null));
                        }
                    }
                }
                else if (this.get != null)
                {
                    Response.OnlyHeader = Method == "HEAD";
                    this.get.GET(Request, Response);
                }
                else
                {
                    throw new MethodNotAllowedException(this.allowedMethods);
                }
                break;

            case "POST":
                if (this.postRanges != null)
                {
                    if (Header.ContentRange != null)
                    {
                        ContentByteRangeInterval Interval = Header.ContentRange.Interval;
                        if (Interval is null)
                        {
                            throw new RangeNotSatisfiableException();
                        }
                        else
                        {
                            this.postRanges.POST(Request, Response, Interval);
                        }
                    }
                    else
                    {
                        if (this.post != null)
                        {
                            this.post.POST(Request, Response);
                        }
                        else
                        {
                            long Total;

                            if (Header.ContentLength != null)
                            {
                                Total = Header.ContentLength.ContentLength;
                            }
                            else if (Request.DataStream != null)
                            {
                                Total = Request.DataStream.Position;
                            }
                            else
                            {
                                Total = 0;
                            }

                            this.postRanges.POST(Request, Response, new ContentByteRangeInterval(0, Total - 1, Total));
                        }
                    }
                }
                else if (this.post != null)
                {
                    this.post.POST(Request, Response);
                }
                else
                {
                    throw new MethodNotAllowedException(this.allowedMethods);
                }
                break;

            case "PUT":
                if (this.putRanges != null)
                {
                    if (Header.ContentRange != null)
                    {
                        ContentByteRangeInterval Interval = Header.ContentRange.Interval;
                        if (Interval is null)
                        {
                            throw new RangeNotSatisfiableException();
                        }
                        else
                        {
                            this.putRanges.PUT(Request, Response, Interval);
                        }
                    }
                    else
                    {
                        if (this.put != null)
                        {
                            this.put.PUT(Request, Response);
                        }
                        else
                        {
                            long Total;

                            if (Header.ContentLength != null)
                            {
                                Total = Header.ContentLength.ContentLength;
                            }
                            else if (Request.DataStream != null)
                            {
                                Total = Request.DataStream.Position;
                            }
                            else
                            {
                                Total = 0;
                            }

                            this.putRanges.PUT(Request, Response, new ContentByteRangeInterval(0, Total - 1, Total));
                        }
                    }
                }
                else if (this.put != null)
                {
                    this.put.PUT(Request, Response);
                }
                else
                {
                    throw new MethodNotAllowedException(this.allowedMethods);
                }
                break;

            case "DELETE":
                if (this.delete is null)
                {
                    throw new MethodNotAllowedException(this.allowedMethods);
                }
                else
                {
                    this.delete.DELETE(Request, Response);
                }
                break;

            case "OPTIONS":
                if (this.options is null)
                {
                    throw new MethodNotAllowedException(this.allowedMethods);
                }
                else
                {
                    this.options.OPTIONS(Request, Response);
                }
                break;

            case "TRACE":
                if (this.trace is null)
                {
                    throw new MethodNotAllowedException(this.allowedMethods);
                }
                else
                {
                    this.trace.TRACE(Request, Response);
                }
                break;

            default:
                throw new MethodNotAllowedException(this.allowedMethods);
            }

            if (this.Synchronous)
            {
                Response.SendResponse();
                Response.Dispose();
            }
        }