                     uniqueItems: true
 
     @configDefaults:
+        hostnames: []
         port: 8613
         reload: null
         middleware: []
         key: ""
         cert: ""
+        csp: {}
 
     @stateDefaults:
         files: {}
 
     init: ->
         @app = express()
+        @app.use csp @config.csp, @config.hostnames, @config.reload
 
         if @config.key and @config.cert
             @server = https.createServer {

    @schema: ->
        description: "Webserver with optional Testem and Reload integration."
        properties:
            key:
                description: "Private key to use for SSL (default: \"\")"
                type: "string"

    }();
"""

csp = (config, hostnames, reload) ->
    defaults =
        defaultSrc: ["'none'"]
        connectSrc: ["'self'"]
        fontSrc: ["'self'"]
        frameSrc: ["'self'"]
        imgSrc: ["'self'"]
        mediaSrc: ["'self'"]
        objectSrc: ["'self'"]
        scriptSrc: ["'self'"]
        styleSrc: ["'self'"]

    dasherize = (s) -> s.replace /([A-Z])/g, (_, m) -> "-#{m.toLowerCase()}"

    headerValues = for key, value of defaults
        config[key] = value if not config[key]

        if reload
            if key is "scriptSrc"
                crypto = require "crypto"
                hash = crypto.createHash "sha256"
                hash.update reloadCode
                config[key].push "'sha256-#{hash.digest "base64"}'"
            else if key is "connectSrc"
                if not ~hostnames.indexOf "localhost"
                    hostnames = hostnames.concat ["localhost"]
                config[key].push hostnames.map((h) -> "ws://#{h}:*").join " "
        "#{dasherize key} #{config[key].join " "}"

    headerValue = headerValues.join "; "

    return (req, res, next) ->
        return next() if not minimatch req.path.split("/").pop(), "*.html"

        res.setHeader "Content-Security-Policy", headerValue
        next()

reload = (pattern) ->
    script = """
