Esempio n. 1
0
        public void EnsurePathsOutsideContentDirAreForbidden()
        {
            routeMatch.AddParameter("path", @"..\forbidden\web.config");
            IWebCommandResult result     = cmd.Execute(context, routeMatch);
            HttpStatusResult  fileResult = (HttpStatusResult)result;

            Assert.AreEqual((int)HttpStatusCode.Forbidden, fileResult.StatusCode);
        }
Esempio n. 2
0
        public void EnsureAbsolutePathsAreDisabled()
        {
            routeMatch.AddParameter("path", @"d:/somedir/somepath.png");
            IWebCommandResult result     = cmd.Execute(context, routeMatch);
            HttpStatusResult  fileResult = (HttpStatusResult)result;

            Assert.AreEqual((int)HttpStatusCode.BadRequest, fileResult.StatusCode);
        }
Esempio n. 3
0
        public void FileDoesNotExist()
        {
            routeMatch.AddParameter("path", @"somedir/somepath.png");
            IWebCommandResult result     = cmd.Execute(context, routeMatch);
            HttpStatusResult  fileResult = (HttpStatusResult)result;

            Assert.AreEqual((int)HttpStatusCode.NotFound, fileResult.StatusCode);
        }
Esempio n. 4
0
        public bool ProcessIfMatch(IWebContext context, out IWebCommandResult result)
        {
            //log.DebugFormat("ApplicationUrl={0}, Url={1}, RawUrl={2}, ApplicationPath={3}", context.ApplicationUrl, context.Url, context.RawUrl, context.ApplicationPath);

            result = null;

            IWebServerConfiguration configuration = context.Configuration;

            if (context.IsSecureConnection)
            {
                return(false);
            }

            if (configuration.HttpsMode == HttpsMode.AllowBoth)
            {
                return(false);
            }

            if (configuration.HttpsMode == HttpsMode.RequireHttpsExceptLocal)
            {
                if (context.IsRequestLocal)
                {
                    return(false);
                }
            }

            HttpStatusResult httpStatusResult = new HttpStatusResult(HttpStatusCode.MovedPermanently);

            UriBuilder uriBuilder = new UriBuilder(context.Url);

            uriBuilder.Scheme = "https";

            if (configuration.HttpsPort.HasValue)
            {
                uriBuilder.Port = configuration.HttpsPort.Value;
            }
            else
            {
                uriBuilder.Port = -1;
            }

            string destinationUrl = uriBuilder.ToString();

            httpStatusResult.AddHeader(HttpConsts.HeaderLocation, destinationUrl);

            if (log.IsDebugEnabled)
            {
                log.DebugFormat("Redirecting request '{0}' to '{1}'", context.ApplicationUrl, destinationUrl);
            }

            result = httpStatusResult;
            return(true);
        }
Esempio n. 5
0
        public IWebCommandResult Execute(IWebContext context, WebRequestRouteMatch routeMatch)
        {
            string path = "favicon-" + routeMatch["path"];

            // do not allow rooted (absolute) paths
            if (Path.IsPathRooted(path))
            {
                HttpStatusResult httpStatusResult = new HttpStatusResult(HttpStatusCode.BadRequest);
                httpStatusResult.LoggingSeverity = LoggingSeverity.Error;
                return(httpStatusResult);
            }

            string fileFullPath = Path.Combine(faviconsDirectory, path);

            // do not allow access outside of the contents folder (and its children)
            fileFullPath = Path.GetFullPath(fileFullPath);

            if (!fileFullPath.StartsWith(faviconsDirectory, StringComparison.Ordinal))
            {
                return(new HttpStatusResult(HttpStatusCode.Forbidden));
            }

            if (fileSystem.DoesFileExist(fileFullPath))
            {
                ICachingPolicy cachingPolicy;

                if (context.Configuration.WebServerDevelopmentMode)
                {
                    cachingPolicy = new NoCachingPolicy();
                }
                else
                {
                    cachingPolicy = new CachingByMaxAgePolicy(TimeSpan.FromDays(30), FileLastModifiedFunc);
                }

                FileResult fileResult = new FileResult(fileFullPath, cachingPolicy);
                fileResult.LoggingSeverity = LoggingSeverity.Verbose;
                fileResult.FileCache       = fileCache;
                return(fileResult);
            }

            if (log.IsDebugEnabled)
            {
                log.DebugFormat("Request file {0} does not exist", fileFullPath);
            }

            HttpStatusResult notFoundResult = new HttpStatusResult(HttpStatusCode.NotFound);

            notFoundResult.LoggingSeverity = LoggingSeverity.Verbose;
            return(notFoundResult);
        }
Esempio n. 6
0
        public void IfHttpsIsRequiredAndRequestIsInsecureThenRedirectIt(HttpsMode mode, int?httpsPort)
        {
            configuration.Stub(x => x.HttpsMode).Return(mode);
            configuration.Stub(x => x.HttpsPort).Return(httpsPort);
            context     = new FakeWebContext("http://localhost", null, null, null, configuration);
            context.Url = new Uri("http://wagahaga.com/map/new-york");

            IWebCommandResult result;

            Assert.IsTrue(route.ProcessIfMatch(context, out result));

            HttpStatusResult statusResult = (HttpStatusResult)result;

            Assert.AreEqual((int)HttpStatusCode.MovedPermanently, statusResult.StatusCode);

            if (httpsPort.HasValue)
            {
                Assert.AreEqual("https://wagahaga.com:{0}/map/new-york".Fmt(httpsPort), statusResult.Headers[HttpConsts.HeaderLocation]);
            }
            else
            {
                Assert.AreEqual("https://wagahaga.com/map/new-york", statusResult.Headers[HttpConsts.HeaderLocation]);
            }
        }
Esempio n. 7
0
        public IWebCommandResult Execute(IWebContext context, WebRequestRouteMatch routeMatch)
        {
            // do not allow rooted (absolute) paths
            string path = routeMatch["path"];

            if (path == null)
            {
                return(new HttpStatusResult(HttpStatusCode.BadRequest));
            }

            if (Path.IsPathRooted(path))
            {
                HttpStatusResult httpStatusResult = new HttpStatusResult(HttpStatusCode.BadRequest);
                httpStatusResult.LoggingSeverity = LoggingSeverity.Error;
                return(httpStatusResult);
            }

            string fileFullPath = Path.Combine(contentRootDirectory, path);

            // do not allow access outside of the contents folder (and its children)
            fileFullPath = Path.GetFullPath(fileFullPath);

            if (!fileFullPath.StartsWith(contentRootDirectory, StringComparison.Ordinal))
            {
                return(new HttpStatusResult(HttpStatusCode.Forbidden));
            }

            if (fileSystem.DoesFileExist(fileFullPath))
            {
                ICachingPolicy cachingPolicy;

                if (context.Configuration.WebServerDevelopmentMode)
                {
                    cachingPolicy = new NoCachingPolicy();
                }
                else
                {
                    // choose the policy based on wildcard match
                    cachingPolicy = FindCachingPolicyForFile(path);
                }

                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Returning contents of the file '{0}'", fileFullPath);
                }

                FileResult result = new FileResult(fileFullPath, cachingPolicy);
                result.AllowGzipCompression = allowGzipCompression;
                result.FileCache            = fileCache;
                result.LoggingSeverity      = LoggingSeverity.Verbose;
                return(result);
            }

            if (log.IsDebugEnabled)
            {
                log.DebugFormat("Requested file '{0}' does not exist", fileFullPath);
            }

            HttpStatusResult notFoundResult = new HttpStatusResult(HttpStatusCode.NotFound);

            notFoundResult.LoggingSeverity = LoggingSeverity.Error;
            return(notFoundResult);
        }
Esempio n. 8
0
        // ReSharper disable once InconsistentNaming
        private static void Application_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication application = (HttpApplication)sender;
            HttpContext     httpContext = application.Context;

            try
            {
                SyborgHttpModuleAppHost appHost = (SyborgHttpModuleAppHost)application.Application[KeyAppHost];

                if (appHost.WebServerConfiguration.SimulatedResponseLag > TimeSpan.Zero)
                {
                    Thread.Sleep(appHost.WebServerConfiguration.SimulatedResponseLag);
                }

                IWebContext context = appHost.CreateWebContext(httpContext);

                //if (log.IsDebugEnabled)
                //    log.DebugFormat("Request: {0}", context.RawUrl);

                // this is to prevent protocol violation error
                if (context.HttpMethod == "HEAD")
                {
                    context.CloseResponse();
                    return;
                }

                IWebCommandResult webCommandResult = null;
                try
                {
                    foreach (IWebRequestRoute route in appHost.Routes)
                    {
                        if (route.ProcessIfMatch(context, out webCommandResult))
                        {
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    log.FatalFormat("Web request failed when routing: {0}", ex);
                    webCommandResult = new HttpStatusResult(
                        HttpStatusCode.InternalServerError,
                        "Ooops... an error occurred during the processing of your request. If this error persists, please contact our site administrator at [email protected]. Thank you!");
                }

                if (webCommandResult == null)
                {
                    webCommandResult = new HttpStatusResult(HttpStatusCode.BadRequest);
                }

                webCommandResult.Apply(context);

                if (!context.IsResponseClosed)
                {
                    log.ErrorFormat(
                        CultureInfo.InvariantCulture,
                        "BUG: the response was not closed properly (thread {0}, URL={1})!",
                        Thread.CurrentThread.ManagedThreadId,
                        context.RawUrl);
                    context.StatusCode = (int)HttpStatusCode.InternalServerError;
                    context.CloseResponse();
                }

                LogTraffic(context);
            }
            catch (HttpListenerException ex)
            {
                // An operation was attempted on a nonexistent network connection
                if ((uint)ex.ErrorCode == 0x80004005)
                {
                    //log.WarnFormat("HttpListenerException: {0:X}", ex.ErrorCode);
                    // ignore this
                }
                else
                {
                    log.Warn("HttpListenerException", ex);
                }
            }
            catch (ObjectDisposedException ex)
            {
                log.Warn("ObjectDisposedException", ex);
            }
            catch (Exception ex)
            {
                log.FatalFormat("Web request failed when applying the result: {0}", ex);
            }
        }
Esempio n. 9
0
        // ReSharper disable once CyclomaticComplexity
        private void WebRequestCallback(IAsyncResult result)
        {
            if (log.IsDebugEnabled)
            {
                log.DebugFormat("WebRequestCallback (thread {0})", Thread.CurrentThread.ManagedThreadId);
            }

            try
            {
                if (!httpListener.IsListening)
                {
                    log.Info("Received web request, but HTTP listener is not listening");
                    return;
                }

                if (configuration.SimulatedResponseLag > TimeSpan.Zero)
                {
                    Thread.Sleep(configuration.SimulatedResponseLag);
                }

                HttpListenerContext listenerContext = httpListener.EndGetContext(result);
                Contract.Assume(listenerContext != null);

                IWebContext context = new HttpListenerWebContext(
                    listenerContext, FullWebServerUrl, applicationPath, fileSystem, applicationInfo, timeService, configuration, viewRenderingEngine, fileMimeTypesMap);

                OnRequestReceived(context);

                foreach (IWebPolicy policy in policies)
                {
                    context.AddPolicy(policy);
                }

                httpListener.BeginGetContext(WebRequestCallback, httpListener);

                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Request: {0} {1}", context.HttpMethod, context.RawUrl);
                }

                // this is to prevent protocol violation error
                if (context.HttpMethod == "HEAD")
                {
                    context.CloseResponse();
                    return;
                }

                IWebCommandResult webCommandResult = null;
                try
                {
                    foreach (IWebRequestRoute route in routes)
                    {
                        if (route.ProcessIfMatch(context, out webCommandResult))
                        {
                            break;
                        }
                    }
                }
                catch (KeyNotFoundException ex)
                {
                    log.InfoFormat("Error processing request: {0}", ex);
                    webCommandResult = new HttpStatusResult(HttpStatusCode.NotFound);
                }
                catch (Exception ex)
                {
                    webCommandResult = new HttpStatusResult(HttpStatusCode.InternalServerError);
                    log.Error("InternalServerError - processing routes", ex);
                }

                if (webCommandResult == null)
                {
                    webCommandResult = new HttpStatusResult(HttpStatusCode.BadRequest);
                }

                try
                {
                    webCommandResult.Apply(context);
                }
                catch (Exception ex)
                {
                    webCommandResult = new HttpStatusResult(HttpStatusCode.InternalServerError);
                    log.Error("InternalServerError - apply web command result", ex);
                    webCommandResult.Apply(context);
                }

                if (!context.IsResponseClosed)
                {
                    log.ErrorFormat("BUG: the response was not closed properly (thread {0}, URL={1})!", Thread.CurrentThread.ManagedThreadId, context.RawUrl);
                    context.StatusCode = (int)HttpStatusCode.InternalServerError;
                    context.CloseResponse();
                }
            }
            catch (HttpListenerException ex)
            {
                // An operation was attempted on a nonexistent network connection
                if ((uint)ex.ErrorCode == 0x80004005)
                {
                    //log.WarnFormat("HttpListenerException: {0:X}", ex.ErrorCode);
                    // ignore this
                }
                else
                {
                    log.Warn("HttpListenerException", ex);
                }
            }
            catch (ObjectDisposedException ex)
            {
                log.Warn("ObjectDisposedException", ex);
            }
            catch (Exception ex)
            {
                log.Fatal("Web request processing thread failed", ex);
                webServerController.SignalToAbort("Web request processing thread failed");
            }

            if (log.IsDebugEnabled)
            {
                log.DebugFormat("Finished WebRequestCallback (thread {0})", Thread.CurrentThread.ManagedThreadId);
            }
        }