1
1
module Hyper.Node.FileServer (fileServer ) where
2
2
3
3
import Prelude
4
- import Node.Buffer as Buffer
5
- import Node.Path as Path
4
+
6
5
import Control.IxMonad (ibind , (:>>=))
7
6
import Control.Monad.Aff.Class (liftAff , class MonadAff )
8
7
import Control.Monad.Eff.Class (liftEff )
8
+ import Data.Array (last )
9
+ import Data.Map (Map , fromFoldable , lookup )
10
+ import Data.Maybe (maybe )
11
+ import Data.String (Pattern (..), split )
9
12
import Data.Tuple (Tuple (Tuple))
10
13
import Hyper.Conn (Conn )
11
14
import Hyper.Middleware (Middleware , lift' )
@@ -14,10 +17,65 @@ import Hyper.Request (class Request, getRequestData)
14
17
import Hyper.Response (class ResponseWritable , class Response , ResponseEnded , StatusLineOpen , end , headers , send , toResponse , writeStatus )
15
18
import Hyper.Status (statusOK )
16
19
import Node.Buffer (BUFFER , Buffer )
20
+ import Node.Buffer as Buffer
17
21
import Node.FS (FS )
18
22
import Node.FS.Aff (readFile , stat , exists )
19
23
import Node.FS.Stats (isDirectory , isFile )
20
24
import Node.Path (FilePath )
25
+ import Node.Path as Path
26
+
27
+ htaccess :: Map String String
28
+ htaccess = fromFoldable $
29
+ [ Tuple " aab" " application/x-authorware-bin"
30
+ , Tuple " aam" " application/x-authorware-map"
31
+ , Tuple " aas" " application/x-authorware-seg"
32
+ , Tuple " asf" " video/x-ms-asf"
33
+ , Tuple " asp" " text/html"
34
+ , Tuple " asx" " video/x-ms-asf"
35
+ , Tuple " class" " application/x-java-applet"
36
+ , Tuple " css" " text/css"
37
+ , Tuple " dcr" " application/x-director"
38
+ , Tuple " dir" " application/x-director"
39
+ , Tuple " dmg" " application/octet-stream"
40
+ , Tuple " dxr" " application/x-director"
41
+ , Tuple " fgd" " application/x-director"
42
+ , Tuple " fh" " image/x-freehand"
43
+ , Tuple " fh4" " image/x-freehand"
44
+ , Tuple " fh5" " image/x-freehand"
45
+ , Tuple " fh7" " image/x-freehand"
46
+ , Tuple " fhc" " image/x-freehand"
47
+ , Tuple " gtar" " application/x-gtar"
48
+ , Tuple " gz" " application/x-gzip"
49
+ , Tuple " ico" " image/vnd.microsoft.icon"
50
+ , Tuple " m3u" " audio/x-mpegurl"
51
+ , Tuple " mov" " video/quicktime"
52
+ , Tuple " pdf" " application/pdf"
53
+ , Tuple " qt" " video/quicktime"
54
+ , Tuple " ra" " audio/vnd.rn-realaudio"
55
+ , Tuple " ram" " audio/vnd.rn-realaudio"
56
+ , Tuple " rar" " application/x-rar-compressed"
57
+ , Tuple " rm" " application/vnd.rn-realmedia"
58
+ , Tuple " rpm" " audio/x-pn-realaudio-plugin"
59
+ , Tuple " rv" " video/vnd.rn-realvideo"
60
+ , Tuple " shtml" " text/html"
61
+ , Tuple " svg" " image/svg+xml"
62
+ , Tuple " svgz" " image/svg+xml"
63
+ , Tuple " swf" " application/x-shockwave-flash"
64
+ , Tuple " torrent" " application/x-bittorrent"
65
+ , Tuple " wav" " audio/x-wav"
66
+ , Tuple " wax" " audio/x-ms-wax"
67
+ , Tuple " wm" " video/x-ms-wm"
68
+ , Tuple " wma" " audio/x-ms-wma"
69
+ , Tuple " wmd" " application/x-ms-wmd"
70
+ , Tuple " wmv" " video/x-ms-wmv"
71
+ , Tuple " wmx" " video/x-ms-wmx"
72
+ , Tuple " wmz" " application/x-ms-wmz"
73
+ , Tuple " wvx" " video/x-ms-wvx"
74
+ , Tuple " xbm" " image/x-xbitmap"
75
+ , Tuple " xhtml" " application/xhtml+xml"
76
+ , Tuple " xml" " text/xml"
77
+ , Tuple " zip" " application/zip"
78
+ ]
21
79
22
80
serveFile
23
81
:: forall m e req res c b
@@ -32,10 +90,13 @@ serveFile
32
90
(Conn req (res ResponseEnded ) c )
33
91
Unit
34
92
serveFile path = do
93
+ let
94
+ ext = last $ split (Pattern " ." ) path
95
+ contentType = maybe " */*" id (ext >>= flip lookup htaccess)
35
96
buf <- lift' (liftAff (readFile path))
36
97
contentLength <- liftEff (Buffer .size buf)
37
98
_ <- writeStatus statusOK
38
- _ <- headers [ Tuple " Content-Type" " */* ; charset=utf-8"
99
+ _ <- headers [ Tuple " Content-Type" (contentType <> " ; charset=utf-8" )
39
100
, Tuple " Content-Length" (show contentLength)
40
101
]
41
102
response <- toResponse buf
0 commit comments