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); }
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); }
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); }
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); }
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); }
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]); } }
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); }
// 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); } }
// 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); } }