Beispiel #1
0
        public void ProcessRequest(HttpContext context, string httpMethod, Stream inputStream)
        {
            ODataRequest   odataReq      = null;
            ODataFormatter formatter     = null;
            var            portalContext = (PortalContext)context.Items[PortalContext.CONTEXT_ITEM_KEY];

            try
            {
                Content content;

                odataReq = portalContext.ODataRequest;
                if (odataReq == null)
                {
                    formatter = ODataFormatter.Create("json", portalContext);
                    throw new ODataException("The Request is not an OData request.", ODataExceptionCode.RequestError);
                }

                this.ODataRequest = portalContext.ODataRequest;
                Exception requestError = this.ODataRequest.RequestError;

                formatter = ODataFormatter.Create(portalContext, odataReq);
                if (formatter == null)
                {
                    formatter = ODataFormatter.Create("json", portalContext);
                    throw new ODataException(ODataExceptionCode.InvalidFormatParameter);
                }

                if (requestError != null)
                {
                    var innerOdataError = requestError as ODataException;
                    var message         = "An error occured during request parsing. " + requestError.Message +
                                          " See inner exception for details.";
                    var code = innerOdataError?.ODataExceptionCode ?? ODataExceptionCode.RequestError;
                    throw new ODataException(message, code, requestError);
                }

                odataReq.Format = formatter.FormatName;
                formatter.Initialize(odataReq);

                // Cross-Origin Resource Sharing (CORS)
                // Do this after the formatter was initialized to be able to provide a proper error message.
                if (!HttpHeaderTools.IsOriginHeaderAllowed())
                {
                    throw new ODataException(ODataExceptionCode.Forbidden);
                }

                var exists = Node.Exists(odataReq.RepositoryPath);
                if (!exists && !odataReq.IsServiceDocumentRequest && !odataReq.IsMetadataRequest && !AllowedMethodNamesWithoutContent.Contains(httpMethod))
                {
                    ContentNotFound(context, odataReq.RepositoryPath);
                    return;
                }

                JObject model = null;
                switch (httpMethod)
                {
                case "GET":
                    if (odataReq.IsServiceDocumentRequest)
                    {
                        formatter.WriteServiceDocument(portalContext, odataReq);
                    }
                    else if (odataReq.IsMetadataRequest)
                    {
                        formatter.WriteMetadata(context, odataReq);
                    }
                    else
                    {
                        if (!Node.Exists(odataReq.RepositoryPath))
                        {
                            ContentNotFound(context, odataReq.RepositoryPath);
                        }
                        else if (odataReq.IsCollection)
                        {
                            formatter.WriteChildrenCollection(odataReq.RepositoryPath, portalContext, odataReq);
                        }
                        else if (odataReq.IsMemberRequest)
                        {
                            formatter.WriteContentProperty(odataReq.RepositoryPath, odataReq.PropertyName,
                                                           odataReq.IsRawValueRequest, portalContext, odataReq);
                        }
                        else
                        {
                            formatter.WriteSingleContent(odataReq.RepositoryPath, portalContext);
                        }
                    }
                    break;

                case "PUT":     // update
                    if (odataReq.IsMemberRequest)
                    {
                        throw new ODataException("Cannot access a member with HTTP PUT.",
                                                 ODataExceptionCode.IllegalInvoke);
                    }
                    else
                    {
                        model   = Read(inputStream);
                        content = LoadContentOrVirtualChild(odataReq);
                        if (content == null)
                        {
                            ContentNotFound(context, odataReq.RepositoryPath);
                            return;
                        }

                        ResetContent(content);
                        UpdateContent(content, model, odataReq);
                        formatter.WriteSingleContent(content, portalContext);
                    }
                    break;

                case "MERGE":
                case "PATCH":     // update
                    if (odataReq.IsMemberRequest)
                    {
                        throw new ODataException(
                                  String.Concat("Cannot access a member with HTTP ", httpMethod, "."),
                                  ODataExceptionCode.IllegalInvoke);
                    }
                    else
                    {
                        model   = Read(inputStream);
                        content = LoadContentOrVirtualChild(odataReq);
                        if (content == null)
                        {
                            ContentNotFound(context, odataReq.RepositoryPath);
                            return;
                        }

                        UpdateContent(content, model, odataReq);
                        formatter.WriteSingleContent(content, portalContext);
                    }
                    break;

                case "POST":     // invoke an action, create content
                    if (odataReq.IsMemberRequest)
                    {
                        formatter.WriteOperationResult(inputStream, portalContext, odataReq);
                    }
                    else
                    {
                        // parent must exist
                        if (!Node.Exists(odataReq.RepositoryPath))
                        {
                            ContentNotFound(context, odataReq.RepositoryPath);
                            return;
                        }
                        model   = Read(inputStream);
                        content = CreateContent(model, odataReq);
                        formatter.WriteSingleContent(content, portalContext);
                    }
                    break;

                case "DELETE":
                    if (odataReq.IsMemberRequest)
                    {
                        throw new ODataException(
                                  String.Concat("Cannot access a member with HTTP ", httpMethod, "."),
                                  ODataExceptionCode.IllegalInvoke);
                    }
                    else
                    {
                        content = LoadContentOrVirtualChild(odataReq);
                        if (content != null)
                        {
                            content.Delete();
                        }
                    }
                    break;

                case "OPTIONS":
                    // set allowed methods and headers
                    HttpHeaderTools.SetPreflightResponse();
                    break;
                }
            }
            catch (ContentNotFoundException e)
            {
                var oe = new ODataException(ODataExceptionCode.ResourceNotFound, e);

                formatter.WriteErrorResponse(context, oe);
            }
            catch (ODataException e)
            {
                if (e.HttpStatusCode == 500)
                {
                    SnLog.WriteException(e);
                }

                formatter.WriteErrorResponse(context, e);
            }
            catch (SenseNetSecurityException e)
            {
                // In case of a visitor we should not expose the information that this content actually exists. We return
                // a simple 404 instead to provide exactly the same response as the regular 404, where the content
                // really does not exist. But do this only if the visitor really does not have permission for the
                // requested content (because security exception could be thrown by an action or something else too).
                if (odataReq != null && User.Current.Id == User.Visitor.Id)
                {
                    var head = NodeHead.Get(odataReq.RepositoryPath);
                    if (head != null && !SecurityHandler.HasPermission(head, PermissionType.Open))
                    {
                        ContentNotFound(context, odataReq.RepositoryPath);
                        return;
                    }
                }

                var oe = new ODataException(ODataExceptionCode.NotSpecified, e);

                SnLog.WriteException(oe);

                formatter.WriteErrorResponse(context, oe);
            }
            catch (InvalidContentActionException ex)
            {
                var oe = new ODataException(ODataExceptionCode.NotSpecified, ex);
                if (ex.Reason != InvalidContentActionReason.NotSpecified)
                {
                    oe.ErrorCode = Enum.GetName(typeof(InvalidContentActionReason), ex.Reason);
                }

                // it is unnecessary to log this exception as this is not a real error
                formatter.WriteErrorResponse(context, oe);
            }
            catch (ContentRepository.Storage.Data.NodeAlreadyExistsException nae)
            {
                var oe = new ODataException(ODataExceptionCode.ContentAlreadyExists, nae);

                formatter.WriteErrorResponse(context, oe);
            }
            catch (System.Threading.ThreadAbortException tae)
            {
                if (!context.Response.IsRequestBeingRedirected)
                {
                    var oe = new ODataException(ODataExceptionCode.RequestError, tae);
                    formatter.WriteErrorResponse(context, oe);
                }
                // specific redirect response so do nothing
            }
            catch (Exception ex)
            {
                var oe = new ODataException(ODataExceptionCode.NotSpecified, ex);

                SnLog.WriteException(oe);

                formatter.WriteErrorResponse(context, oe);
            }
            finally
            {
                context.Response.End();
            }
        }
Beispiel #2
0
        //================================================================================= IHttpHandler

        public void ProcessRequest(HttpContext context)
        {
            // Handling If-Modified-Since

            var modifiedSinceHeader = HttpContext.Current.Request.Headers["If-Modified-Since"];

            if (modifiedSinceHeader != null)
            {
                DateTime ifModifiedSince = DateTime.MinValue;
                DateTime.TryParse(modifiedSinceHeader, out ifModifiedSince);

                if (ifModifiedSince != DateTime.MinValue)
                {
                    // TODO: Once you can query properly in text files, only take into account the
                    //       resource files which contain the resource class in question.
                    var lastModificationDate = GetLastResourceModificationDate(ifModifiedSince);

                    if (lastModificationDate != null && lastModificationDate <= ifModifiedSince)
                    {
                        context.Response.Clear();
                        context.Response.StatusCode = 304;
                        context.Response.Flush();
                        context.Response.End();
                    }
                }
            }

            // Handling the rest of the request

            var shouldDeny = true;

            try
            {
                var parsedUrl = ParseUrl(context.Request.RawUrl);

                if (parsedUrl != null)
                {
                    var         cultureName = parsedUrl.Item1;
                    var         className   = parsedUrl.Item2;
                    CultureInfo culture     = null;

                    if (!string.IsNullOrEmpty(cultureName))
                    {
                        culture = CultureInfo.GetCultureInfo(cultureName);
                    }

                    if (culture != null && !string.IsNullOrEmpty(className))
                    {
                        var script = ResourceScripter.RenderResourceScript(className, culture);
                        var lastModificationDate = GetLastResourceModificationDate(null);

                        HttpHeaderTools.SetCacheControlHeaders(lastModified: lastModificationDate);

                        // TODO: add an expires header when appropriate, but without clashing with the resource editor

                        context.Response.ContentType = "text/javascript";
                        context.Response.Write(script);
                        context.Response.Flush();

                        shouldDeny = false;
                    }
                }
            }
            catch
            {
                shouldDeny = true;
            }

            // If it failed for some reason, deny it

            if (shouldDeny)
            {
                DenyRequest(context);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Processes the request.
        /// </summary>
        public virtual void ProcessRequestCore(HttpContextBase context)
        {
            var propertyName  = PropertyName;
            var requestedNode = RequestedNode;

            if (string.IsNullOrEmpty(propertyName) || requestedNode == null)
            {
                context.Response.StatusCode = 404;
                return;
            }

            // Get the stream through our provider to let 3rd party developers serve custom data
            string         contentType;
            BinaryFileName fileName;
            var            binaryStream = DocumentBinaryProvider.Current.GetStream(requestedNode, propertyName, out contentType, out fileName);

            if (binaryStream == null)
            {
                return;
            }

            Stream resizedStream;

            // If this is an image and we need to resize it
            if (Width.HasValue && Height.HasValue)
            {
                resizedStream = Image.CreateResizedImageFile(binaryStream, string.Empty, Width.Value, Height.Value, 0, contentType);
            }
            else
            {
                resizedStream = binaryStream;
            }

            // We need to Flush the headers before
            // We start to stream the actual binary.

            context.Response.ContentType = contentType;
            context.Response.AppendHeader("Content-Length", resizedStream.Length.ToString());

            HttpHeaderTools.SetContentDispositionHeader(fileName);

            HttpHeaderTools.SetCacheControlHeaders(lastModified: requestedNode.ModificationDate);
            if (this.MaxAge.HasValue)
            {
                HttpHeaderTools.SetCacheControlHeaders(maxAge: this.MaxAge);
            }

            context.Response.StatusCode = 200;
            context.Response.Flush();

            resizedStream.Position = 0;

            var buffer = new byte[Math.Min(resizedStream.Length, RepositoryConfiguration.BinaryChunkSize)];
            int bytesRead;

            //while (bytesRead > 0)
            while ((bytesRead = resizedStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                context.Response.OutputStream.Write(buffer, 0, bytesRead);
                context.Response.Flush();
            }

            // Let the client code log file downloads
            var file = requestedNode as ContentRepository.File;

            if (file != null)
            {
                ContentRepository.File.Downloaded(file.Id);
            }
        }
Beispiel #4
0
        //========================================================================================= Overrides

        protected override void CreateChildControls()
        {
            Controls.Clear();

            var node = GetContextNode();

            if (node == null)
            {
                if (this.RenderException != null)
                {
                    this.Controls.Clear();
                    this.Controls.Add(new LiteralControl(String.Concat("Portlet Error: ", this.RenderException.Message)));
                }

                return;
            }

            try
            {
                if (!string.IsNullOrEmpty(this.Renderer))
                {
                    var viewControl = Page.LoadControl(this.Renderer);
                    if (viewControl != null)
                    {
                        this.Controls.Add(viewControl);
                    }

                    if (UrlListView == null)
                    {
                        throw new Exception("UrlListView is missing from the view: " + this.Renderer);
                    }

                    if (PortalContext.ProxyIPs.Count == 0)
                    {
                        UrlListView.Visible = true;

                        if (this.ErrorPlaceholder != null)
                        {
                            var errorLabel = new Label();
                            errorLabel.Text     = HttpContext.GetGlobalResourceObject("Portal", "NoProxyServers") as string;
                            errorLabel.CssClass = "sn-purge-error";

                            this.ErrorPlaceholder.Visible = true;
                            this.ErrorPlaceholder.Controls.Add(errorLabel);
                        }

                        return;
                    }

                    var urlCollector = TypeHandler.ResolveProvider <PurgeUrlCollector>();
                    if (urlCollector == null)
                    {
                        throw new Exception("UrlCollector type is missing");
                    }

                    var urlList     = urlCollector.GetUrls(node);
                    var purgeResult = HttpHeaderTools.PurgeUrlsFromProxy(urlList);
                    var resultList  = from url in urlList
                                      where !string.IsNullOrEmpty(url) && purgeResult.ContainsKey(url)
                                      select new ProxyPurgeResult {
                        Url = url, Result = purgeResult[url]
                    };

                    UrlListView.ItemDataBound += UrlListView_ItemDataBound;
                    UrlListView.DataSource     = resultList;
                    UrlListView.DataBind();
                }
            }
            catch (Exception ex)
            {
                Logger.WriteException(ex);
                Controls.Add(new LiteralControl(ex.Message));
            }

            ChildControlsCreated = true;
        }