1 |
|
2 |
|
3 | var path = require("path")
|
4 |
|
5 |
|
6 | module.exports = function createStatic(_root, _opts) {
|
7 | var root = path.resolve(_root)
|
8 | , opts = Object.assign({
|
9 | index: "index.html",
|
10 | maxAge: 31536000, // One year
|
11 | cacheControl: {
|
12 | "cache.manifest": 0,
|
13 | "worker.js": 0
|
14 | }
|
15 | }, _opts)
|
16 |
|
17 | if (opts.cacheControl) {
|
18 | var map = {}
|
19 | Object.each(opts.cacheControl, function(time, file) {
|
20 | map[path.resolve(root, file)] = time
|
21 | })
|
22 | opts.cacheControl = map
|
23 | }
|
24 |
|
25 | return function(req, res, next) {
|
26 | var file
|
27 | , method = req.method
|
28 |
|
29 | if (method !== "GET" && method !== "HEAD") {
|
30 | res.setHeader("Allow", "GET, HEAD")
|
31 | return res.sendStatus(405) // Method not allowed
|
32 | }
|
33 |
|
34 | if (req.url === "/" && !opts.index) {
|
35 | return res.sendStatus(404)
|
36 | }
|
37 |
|
38 | try {
|
39 | file = path.resolve(root, (
|
40 | req.url === "/" ?
|
41 | opts.index :
|
42 | "." + decodeURIComponent(req.url.split("?")[0].replace(/\+/g, " "))
|
43 | ))
|
44 | } catch (e) {
|
45 | return res.sendStatus(400)
|
46 | }
|
47 |
|
48 | if (file.slice(0, root.length) !== root) {
|
49 | return res.sendStatus(404)
|
50 | }
|
51 | res.sendFile(file, opts, function(err) {
|
52 | if (err && (err.name === "EISDIR" || err.name === "ERANGE" )) {
|
53 | res.sendStatus(err.code)
|
54 | } else {
|
55 | next()
|
56 | }
|
57 | })
|
58 | }
|
59 | }
|
60 |
|
61 |
|
62 |
|
63 |
|
64 | /*
|
65 |
|
66 | 300 Multiple Choices
|
67 | --------------------
|
68 | // https://www.w3.org/Style/Examples/007/figures.h
|
69 |
|
70 | The document name you requested (/Style/Examples/007/figures.) could not be found on this server. However, we found documents with names similar to the one you requested.
|
71 | Available documents:
|
72 | - /Style/Examples/007/figures.it.html.redirect (common basename)
|
73 |
|
74 | Please consider informing the owner of the __referring page__ about the broken link.
|
75 |
|
76 | - It is possible to communicate the list using a set of Link header fields [RFC5988],
|
77 | each with a relationship of "alternate".
|
78 | - https://tools.ietf.org/html/rfc2295 Transparent Content Negotiation in HTTP
|
79 | https://tools.ietf.org/html/draft-ietf-http-alternates-01
|
80 | Alternates: {"http://x.org/paper.1" 0.9 {type text/html} {language en}}, {"http://x.org/paper.2" 0.7 {type text/html} {language fr}}
|
81 |
|
82 |
|
83 | 406 Not Acceptable
|
84 | ------------------
|
85 |
|
86 | It is not what anyone would expect, but if you're sure:
|
87 | you can for example use a custom header like Accept-confirm: confirm-delete, and return 406 Not Acceptable if the Accept-confirm header is not what you expect.
|
88 |
|
89 |
|
90 | This is done through the following code:
|
91 |
|
92 | <a href="javascript:void(0);"
|
93 | onclick="document.execCommand('SaveAs',true,'file.html');"
|
94 | >Save this page</a>
|
95 |
|
96 | However, usually you want to save another file, the file a hyperlink leads to. To do that javascript is not enough (at least there is no such standard way) and something must be done on the server.
|
97 | Forcing SaveAs using the HTTP header
|
98 |
|
99 | In order to force the browser to show SaveAs dialog when clicking a hyperlink you have to include the following header in HTTP response of the file to be downloaded:
|
100 |
|
101 | Content-Disposition: attachment; filename="<file name.ext>"
|
102 |
|
103 | Where <file name.ext> is the filename you want to appear in SaveAs dialog (like finances.xls or mortgage.pdf) - without < and > symbols.
|
104 |
|
105 | You have to keep the following in mind:
|
106 |
|
107 | The filename should be in US-ASCII charset and shouldn't contain special characters: < > \ " / : | ? * space.
|
108 | The filename should not have any directory path information specified.
|
109 | The filename should be enclosed in double quotes but most browsers will support file names without double quotes.
|
110 | Ancient browsers also required the following (not needed nowadays, but for a fool proof solution might be worth doing):
|
111 |
|
112 | Content-Type header should be before Content-Disposition.
|
113 | Content-Type header should refer to an unknown MIME type (at least until the older browsers go away).
|
114 |
|
115 |
|
116 |
|
117 | Try downloading files with Content-disposition
|
118 |
|
119 | Try the header support in your browser, click here:
|
120 |
|
121 | Text file with Content-Type of application/x-unknown.
|
122 |
|
123 | */
|
124 |
|
125 |
|
126 |
|
127 |
|