Nancy - 管理静态内容

TL;DR: stick stuff in /Content ... done.

In Nancy parlance "Static Content" is things like javascript files, css, images etc, but can actually be anything, and Nancy uses a convention based approach for figuring out what static content it is able to serve at runtime. Nancy supports the notion of having multiple conventions for static content and each convention is represented by a delegate with the signature Func<NancyContext, string, Response>.

The delegate accepts two parameters: the context of the current request and the application root path. The output of the delegate is a standard Nancy Response object or null. A null response means that the convention had no static content to return given the current content and requested path.

Nancy supports multiple static content conventions at once and is shipped with a default convention that will look for files in the /Content path of your application. The static content handler in Nancy is executed as a BeforeRequest filter in the application pipeline.

For example, if you put a file called app.js in the Content folder of your application, it will be accessible at /Content/app.js.

Defining your own conventions using the bootstrapper

To define your own static content conventions, using the bootstrapper, you simply inherit a new bootstrapper and override the ConfigureConventions method.

The ConfigureConventions gives you the opportunity to modify the StaticContentsConventionsproperty, which is a list of conventions

public class CustomBootstrapper : DefaultNancyBootstrapper
{
    protected override void ConfigureConventions(NancyConventions conventions)
    {
        base.ConfigureConventions(conventions);

        conventions.StaticContentsConventions.Add((context, rootPath) => {
            // Return your response here or null
        });
    }
}

If that looks a little icky, don‘t worry, Nancy has a helper that will take care of (hopefully!) the vast majority of any static content convention tweaks.. the StaticContentConventionBuilder:

Using the StaticContentConventionBuilder

The StaticContentConventionBuilder is a helper class that is shipped with Nancy. It produces static content conventions for file system based files (e.g. files on the file system, if you want to embed files in an assembly then see the previous section). It encapsulates a lot of the leg work that you would have to write yourself if you wanted to provide an efficient and secure way of letting clients request files of the file system.

There are two methods that produce static content conventions

  • AddDirectory - For mapping directories
  • AddFile - For mapping individual files

Mapping a directory using AddDirectory

When using AddDirectory you are creating a mapping between a virtual and a physical folder on the filesystem. For instance you may store your static content in _ /assets_ on the file system, but wish for all requests, for that content, to be sent to /public

Forward slashes should always be used as the path separator, no matter on which platform the application is run. Nancy will ensure that, during run-time, these paths will be converted to valid paths for the platform that the application is running on.

It is important to be aware that you are mapping to a static content root folder and that it is valid to request resources from any sub-folder in that folder. For example if you map /public to /assets, you can then add a javascript sub-folder, in /assets which can then be requested using /public/javascript/

It is not permitted to map to the root of your application. Any attempt at doing so will result in anArgumentException being thrown. The reason for this is that it would make it possible to request anyfile in your application if you are not careful.

The AddDirectory method has the following signature

public static Func<NancyContext, string, Response> AddDirectory(string requestedPath,
                                                                string contentPath = null,
                                                                params string[] allowedExtensions)
  • requestedPath - the path that is actually requested by the client, relative to the application root e.g. /scripts.
  • contentPath - optional path that contains the content, again, relative the application root. With this parameter it‘s possible to "map" requests to /scripts to the /javascript folder in your physical directory structure on disk.
  • allowedExtensions - optional list of extensions that are allowed to be served, so in the above example, you may want to just specify that "js" files are allowed and nothing else.

The resulting convention provides the following features:

  • Specify which folder that the static content exists in
  • Optionally map the content folder to a virtual folder, so that the name of the requested directory is different to that of the actual folder
  • Optionally specify which extensions that the convention is valid for
  • Caches all file system path evaluations, such as making sure the folder and file actually exists, for improved performance on multiple requests
  • Protects against “leaving” the content folder and requesting files that are stored outside the folder and the application itself. Only files in the content folder, or a sub-folder, will be considered valid to return
  • Uses the MimeTypes list to automatically detect and set the correct content-type of the file response

Mapping individual files with AddFile

The AddFile method enables you to map individual file names and locations. For example if you do not wish to store your robots.txt file in the root of your application, but instead store it in your /assetsfolder, you could map the location of the file and Nancy would forward incoming requests, for that file, to the right location.

It is also possible to map extensionless files to physical files, for example /style could be mapped to/assets/style.css. If a file request is then sent to /style, then the /assets/style.css file will be returned in its place.

The AddFile method has the following signature

public static Func<NancyContext, string, Response> AddFile(string requestedFile, string contentFile)
  • requestedFile - The name, including path, of the file that is requested by the client
  • contentFile - The name, including path, of the file that will be returned in place of the requested file

The resulting convention provides the following features:

  • Caches all file system path evaluations, such as making sure the folder and file actually exists, for improved performance on multiple requests
  • Protects against “leaving” the content folder and requesting files that are stored outside the folder and the application itself
  • Uses the MimeTypes list to automatically detect and set the correct content-type of the file response

Defining the new conventions for your application

Using the StaticContentConventionBuilder, to create new conventions is really easy

using Nancy.Conventions;

public class CustomBoostrapper : DefaultNancyBootstrapper
{
    protected override void ConfigureConventions(NancyConventions conventions)
    {
        base.ConfigureConventions(conventions);

        conventions.StaticContentsConventions.Add(
            StaticContentConventionBuilder.AddDirectory("assets", @"contentFolder/subFolder")
        );
    }
}

Alternative approaches..

If, for some reason, you don‘t want to use the methods above, you can also create conventions using the IConventions interface, or bypass the static content conventions completely and just serve your content from a module.

Defining your own conventions using IConvention

You can also create a class that implements the IConvention interface and in the Initialise method you add your conventions to the StaticContentsConventions property of the conventions that are passed in.

Nancy will locate all implementations of the interface and wire up the conventions, before they are passed onto the ConfigureConventions method of the bootstrapper.

Serving content from a module

You can also use an ordinary NancyModule to return static content, by returning responses with the correct body and content-type. Nancy even provides a few response formatters, to help you out, called AsFileAsImageAsJsonAsTextAsXml and AsRedirect.

The advantage of using a module to serve static content is that you can leverage the full power of a module to implement logic around your static content management, such as making use of moduledependencies. This can be used when more complex logic is required (such as adding a security layer on top).

However, there are disadvantages to using modules for static content management. Because it is a module, the request, for the static content, is subjected to the same request life-cycle as any other request.

This means that the request needs to go through things such as route resolving which can have a performance impact on your application.

Letting IIS handle static content

Sometimes you may want to allow IIS to handle static content for you rather than letting Nancy do it, maybe for performance reasons or possibly something gets misconfigured and it‘s not working. You can tell IIS to not use Nancy for static content by removing the handler for a specific path:

<location path="images">
  <system.webServer>
    <handlers>
      <remove name="Nancy"/>
    </handlers>
  </system.webServer>
</location>

You can change the path to be ‘images‘, ‘scripts‘, ‘content, or what ever you need, just be sure you don‘t have any routes defined which need to use this path, they will no longer work since you‘re basically telling IIS to not pass any of those requests to the Nancy Handler.

Extra steps required when using Microsoft.Owin.Host.SystemWeb

When you are hosting Nancy using Microsoft.Owin.Host.SystemWeb you need some additional configuration to get it working in IIS.

First of all, in your OWIN Startup.cs you will need to addapp.UseStageMarker(PipelineStage.MapHandler), for example:

using Microsoft.Owin.Extensions;
using Owin;

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseNancy();
        app.UseStageMarker(PipelineStage.MapHandler);
    }
}

You will also have to add the following to your Web.config:

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
</system.webServer>

Without this additional configuration, the StaticFileModule from OWIN would intercept the request and return a 404.

时间: 2024-10-09 10:17:56

Nancy - 管理静态内容的相关文章

云计算设计模式(二十二)——静态内容托管模式

部署静态内容到一个基于云的存储服务,可以直接向客户提供这些.这个模式可以减少潜在的昂贵的计算实例的需求. 景和问题 Web应用程序通常包括静态内容的一些元素.此静态内容可以包括HTML页面和诸如图像和可用到客户端的文件的其他资源,无论是作为一个HTML页的一部分(如嵌入式图像,样式表和客户端JavaScript文件)或作为单独的下载(如PDF文档). 尽管Web服务器以及调整通过有效的动态执行页代码和输出缓存优化的要求,他们仍然必须处理请求下载静态内容.这种吸收,可以经常得到更好的利用处理周期.

自己搭建CDN服务器静态内容加速-LuManager CDN使用教程

为什么要自己来搭建一个CDN服务器实现网站访问加速?一是免费CDN服务稳定性和加速效果都不怎么行:二是用国内的付费CDN服务价格贵得要死,一般的草根站长无法承受:三是最现实的问题国内的CDN要求域名Be案. 有了Be案的域名自然是选择国内的主机,没有Be案的域名都是使用的美国主机,国内访问美国空间的速度有时会不理想,且始终比不上国内机房的访问速度,相对于美国空间,日本.香港等地的机房在国内访问速度非常快. 于是很多人都喜欢将自己的网站放在日本或者香港机房,就连CDN服务,我们都会希望找到有日本或

django基础知识之管理静态文件css,js,images:

管理静态文件 项目中的CSS.图片.js都是静态文件 配置静态文件 在settings 文件中定义静态内容 STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static'), ] 在项目根目录下创建static目录,再创建当前应用名称的目录 mysite/static/myapp/ 在模板中可以使用硬编码 /static/my_app/myexample.jpg 在模板中可以使用static编码 { % l

静态内容生成器&mdash;&mdash;Wyam

(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:今天继续静态网站的话题,介绍我选用的一个使用.NET开发的静态内容生成器--Wyam. 技术选型 在决定开始搞静态网站之后,面临的第一个问题就是如何生成静态内容.有现成工具吗?这样的工具符合近期和远期要求吗?如果不符合,有什么技术思路自己开发吗? 带着这样的问题,我迅速Bing到了https://www.staticgen.com/这个网站,这个网站汇聚了市面上存在的几乎所有开源静态网站生成器

用ArrayAdapter来创建Spinner(自定义布局、默认布局、动态内容、静态内容)

         android:dropDownWidth 下拉列表宽度 android:dropDownHorizontalOffset 下拉列表距离左边的距离 android:dropDownVerticalOffset     下拉菜单和文本之间的垂直偏移量 android:popupBackground   下拉列表中的背景色 android:prompt 下拉列表中的提示信息(基本没用了) MainActivity.java package com.kale.spinner; imp

Nginx作为静态内容服务器(Windows环境)

1.简单安装 1)下载 http://nginx.org/en/download.html 2)解压后的路径 E:\Study\nginx\nginx-1.7.6 3)执行nginx.exe,访问http://localhost ,出现Welcome to nginx!欢迎内容,安装成功. 4)在安装路径的logs目录下,会自动生成一个nginx.pid文件,文件内容就是nginx的主进程pid. 2.简单使用命令 nginx -s stop 快速停止 nginx -s quit 安全退出(会处

django “如何”系列10:如何管理静态文件

django开发者最关心的是web应用中的动态部分-视图函数和模板.但是明显,web应用还有其他需要注意的部分:静态文件(图片,css,javascript等等),那些都是渲染一个完整的页面需要的东西. 对于小项目来说,这不是一个大问题,因为你只需要把你要用到的静态文件放到服务器能访问到的地方就ok了.然而,在比较大的项目里面-尤其是那些由多个app组成的-处理不同app之间的静态文件开始变得麻烦起来.这就是django.contrib.staticfiles的价值所在:它会收集你每个应用程序里

gulp管理静态资源缓存

前端项目在版本迭代的时候,难免会遇到静态缓存的问题,明明开发的是ok的,但是一部署到服务器上,发现页面变得乱七八糟,这是由于静态缓存引起的. 从上面这张图片可以看出,浏览器加载css,js等资源时,size一栏是from cache,也就是直接使用了本地的资源,而没有向服务器请求.这样做的好处是提升页面渲染速度,坏处是当服务器的对应的文件发生变化时,浏览器却还是使用缓存,造成布局混乱的问题. 解决办法 一个比较原始的办法是在修改了文件之后,手动改变文件名称,然后再在html手动更新资源的path

centos 7的用户和权限管理相关内容

1.用户,组知识即相关命令 a.用户的类别: 管理员:root 普通用户: 系统用户:仅用于运行服务程序: 登录用户:系统资源的正常使用者: 用户标识:UserID, UID 16bits二进制数字:0-65535: 管理员:0 普通用户: 系统用户: CentOS 5, 6: 1-499 CentOS 7: 1-999 登录用户: CentOS 5,6: 500+ CentOS 7: 1000+ 用户和组的管理: 主要以命令进行: 组:groupadd,  groupmod, groupdel