yesod-static samples
This commit is contained in:
parent
240a61a484
commit
d7d91a486f
23
yesod-static/sample-embed.hs
Normal file
23
yesod-static/sample-embed.hs
Normal file
@ -0,0 +1,23 @@
|
||||
{-# LANGUAGE QuasiQuotes, TypeFamilies, MultiParamTypeClasses #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
import Yesod.Static
|
||||
import Yesod.Dispatch
|
||||
import Yesod.Core
|
||||
import Network.Wai.Handler.Warp (run)
|
||||
|
||||
staticFiles "."
|
||||
|
||||
data Sample = Sample
|
||||
getStatic _ = $(embed "tests")
|
||||
mkYesod "Sample" [parseRoutes|
|
||||
/ RootR GET
|
||||
/static StaticR Static getStatic
|
||||
|]
|
||||
instance Yesod Sample where approot _ = ""
|
||||
|
||||
getRootR = do
|
||||
redirectText RedirectPermanent "static"
|
||||
return ()
|
||||
|
||||
main = toWaiApp Sample >>= run 3000
|
||||
24
yesod-static/sample.hs
Normal file
24
yesod-static/sample.hs
Normal file
@ -0,0 +1,24 @@
|
||||
{-# LANGUAGE QuasiQuotes, TypeFamilies, MultiParamTypeClasses #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
import Yesod.Static
|
||||
import Yesod.Dispatch
|
||||
import Yesod.Core
|
||||
import Network.Wai.Handler.Warp (run)
|
||||
import Network.Wai.Application.Static
|
||||
|
||||
staticFiles "."
|
||||
|
||||
data Sample = Sample
|
||||
getStatic _ = Static $ defaultFileServerSettings { ssFolder = fileSystemLookup $ toFilePath "tests" }
|
||||
mkYesod "Sample" [parseRoutes|
|
||||
/ RootR GET
|
||||
/static StaticR Static getStatic
|
||||
|]
|
||||
instance Yesod Sample where approot _ = ""
|
||||
|
||||
getRootR = do
|
||||
redirectText RedirectPermanent "static"
|
||||
return ()
|
||||
|
||||
main = toWaiApp Sample >>= run 3000
|
||||
25
yesod-static/tests/unicode/LICENSE
Normal file
25
yesod-static/tests/unicode/LICENSE
Normal file
@ -0,0 +1,25 @@
|
||||
The following license covers this documentation, and the source code, except
|
||||
where otherwise indicated.
|
||||
|
||||
Copyright 2010, Michael Snoyman. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
0
yesod-static/tests/unicode/README
Normal file
0
yesod-static/tests/unicode/README
Normal file
7
yesod-static/tests/unicode/Setup.lhs
Executable file
7
yesod-static/tests/unicode/Setup.lhs
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env runhaskell
|
||||
|
||||
> module Main where
|
||||
> import Distribution.Simple
|
||||
|
||||
> main :: IO ()
|
||||
> main = defaultMain
|
||||
1
yesod-static/tests/unicode/TODO
Normal file
1
yesod-static/tests/unicode/TODO
Normal file
@ -0,0 +1 @@
|
||||
Add test for /static/* relative redirects
|
||||
19
yesod-static/tests/unicode/app.hs
Normal file
19
yesod-static/tests/unicode/app.hs
Normal file
@ -0,0 +1,19 @@
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
import Network.Wai
|
||||
import qualified Data.ByteString.Char8 as S8
|
||||
import Network.Wai.Handler.Warp (run)
|
||||
import Network.Wai.Middleware.Debug (debug)
|
||||
import Network.Wai.Application.Static
|
||||
import Web.Routes
|
||||
|
||||
main = run 3000 $ debug app
|
||||
|
||||
app req =
|
||||
case decodePathInfo $ S8.unpack $ pathInfo req of
|
||||
"static":"foo":rest -> staticAppPieces StaticSettings
|
||||
{ ssFolder = ".."
|
||||
, ssIndices = []
|
||||
, ssListing = Just defaultListing
|
||||
, ssGetMimeType = return . defaultMimeTypeByExt
|
||||
} rest req
|
||||
_ -> return $ responseLBS status404 [("Content-Type", "text/plain")] "Not found"
|
||||
11
yesod-static/tests/unicode/embedded-sample.hs
Normal file
11
yesod-static/tests/unicode/embedded-sample.hs
Normal file
@ -0,0 +1,11 @@
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
import Network.Wai.Application.Static
|
||||
import Network.Wai.Handler.Warp (run)
|
||||
import Data.FileEmbed
|
||||
|
||||
main :: IO ()
|
||||
main = run 3000 $ staticApp defaultStaticSettings
|
||||
{ ssFolder = embeddedLookup $ toEmbedded $(embedDir ".")
|
||||
, ssIndices = []
|
||||
, ssMaxAge = NoMaxAge
|
||||
}
|
||||
BIN
yesod-static/tests/unicode/folder.png
Normal file
BIN
yesod-static/tests/unicode/folder.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 891 B |
424
yesod-static/tests/unicode/folder.svg
Normal file
424
yesod-static/tests/unicode/folder.svg
Normal file
@ -0,0 +1,424 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="48.000000px"
|
||||
height="48.000000px"
|
||||
id="svg97"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.46"
|
||||
sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/places"
|
||||
sodipodi:docname="folder.svg"
|
||||
inkscape:export-filename="/home/jimmac/Desktop/horlander-style3.png"
|
||||
inkscape:export-xdpi="90.000000"
|
||||
inkscape:export-ydpi="90.000000"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape">
|
||||
<defs
|
||||
id="defs3">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 24 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="48 : 24 : 1"
|
||||
inkscape:persp3d-origin="24 : 16 : 1"
|
||||
id="perspective68" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5060"
|
||||
id="radialGradient6719"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
|
||||
cx="605.71429"
|
||||
cy="486.64789"
|
||||
fx="605.71429"
|
||||
fy="486.64789"
|
||||
r="117.14286" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient5060">
|
||||
<stop
|
||||
style="stop-color:black;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5062" />
|
||||
<stop
|
||||
style="stop-color:black;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop5064" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5060"
|
||||
id="radialGradient6717"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
|
||||
cx="605.71429"
|
||||
cy="486.64789"
|
||||
fx="605.71429"
|
||||
fy="486.64789"
|
||||
r="117.14286" />
|
||||
<linearGradient
|
||||
id="linearGradient5048">
|
||||
<stop
|
||||
style="stop-color:black;stop-opacity:0;"
|
||||
offset="0"
|
||||
id="stop5050" />
|
||||
<stop
|
||||
id="stop5056"
|
||||
offset="0.5"
|
||||
style="stop-color:black;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:black;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop5052" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5048"
|
||||
id="linearGradient6715"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
|
||||
x1="302.85715"
|
||||
y1="366.64789"
|
||||
x2="302.85715"
|
||||
y2="609.50507" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient9806">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop9808" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop9810" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient9766">
|
||||
<stop
|
||||
style="stop-color:#6194cb;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop9768" />
|
||||
<stop
|
||||
style="stop-color:#729fcf;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop9770" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3096">
|
||||
<stop
|
||||
id="stop3098"
|
||||
offset="0"
|
||||
style="stop-color:#424242;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3100"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#777777;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient319"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
id="stop320"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop321"
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient1789">
|
||||
<stop
|
||||
style="stop-color:#202020;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop1790" />
|
||||
<stop
|
||||
style="stop-color:#b9b9b9;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop1791" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1789"
|
||||
id="radialGradient238"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.055022,-2.734504e-2,0.177703,1.190929,-3.572177,-7.125301)"
|
||||
cx="20.706017"
|
||||
cy="37.517986"
|
||||
fx="20.706017"
|
||||
fy="37.517986"
|
||||
r="30.905205" />
|
||||
<linearGradient
|
||||
id="linearGradient3983">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0.87628865;"
|
||||
offset="0.0000000"
|
||||
id="stop3984" />
|
||||
<stop
|
||||
style="stop-color:#fffffe;stop-opacity:0.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop3985" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3983"
|
||||
id="linearGradient491"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.516844,0.000000,0.000000,0.708978,-0.879573,-1.318166)"
|
||||
x1="6.2297964"
|
||||
y1="13.773066"
|
||||
x2="9.8980894"
|
||||
y2="66.834053" />
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="46.689312"
|
||||
x2="12.853771"
|
||||
y1="32.567184"
|
||||
x1="13.035696"
|
||||
gradientTransform="matrix(1.317489,0.000000,0.000000,0.816256,-0.879573,-1.318166)"
|
||||
id="linearGradient322"
|
||||
xlink:href="#linearGradient319"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="6.1802502"
|
||||
x2="15.514889"
|
||||
y1="31.367750"
|
||||
x1="18.112709"
|
||||
id="linearGradient3104"
|
||||
xlink:href="#linearGradient3096"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient9766"
|
||||
id="linearGradient9772"
|
||||
x1="22.175976"
|
||||
y1="36.987999"
|
||||
x2="22.065331"
|
||||
y2="32.050499"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient9806"
|
||||
id="radialGradient9812"
|
||||
cx="24.35099"
|
||||
cy="41.591846"
|
||||
fx="24.35099"
|
||||
fy="41.591846"
|
||||
r="19.136078"
|
||||
gradientTransform="matrix(1.000000,0.000000,0.000000,0.242494,1.565588e-16,31.50606)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
fill="#729fcf"
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="0.10196078"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="4"
|
||||
inkscape:cx="54.359127"
|
||||
inkscape:cy="-13.803699"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:window-width="1026"
|
||||
inkscape:window-height="818"
|
||||
inkscape:window-x="169"
|
||||
inkscape:window-y="30"
|
||||
inkscape:showpageshadow="false"
|
||||
stroke="#3465a4" />
|
||||
<metadata
|
||||
id="metadata4">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>Folder Icon</dc:title>
|
||||
<dc:date />
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Jakub Steiner</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<cc:license
|
||||
rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
|
||||
<dc:source>http://jimmac.musichall.cz</dc:source>
|
||||
<dc:subject>
|
||||
<rdf:Bag>
|
||||
<rdf:li>folder</rdf:li>
|
||||
<rdf:li>directory</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:subject>
|
||||
</cc:Work>
|
||||
<cc:License
|
||||
rdf:about="http://creativecommons.org/licenses/publicdomain/">
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Folder"
|
||||
inkscape:groupmode="layer">
|
||||
<g
|
||||
style="display:inline"
|
||||
transform="matrix(2.262383e-2,0,0,2.086758e-2,43.38343,36.36962)"
|
||||
id="g6707">
|
||||
<rect
|
||||
style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
||||
id="rect6709"
|
||||
width="1339.6335"
|
||||
height="478.35718"
|
||||
x="-1559.2523"
|
||||
y="-150.69685" />
|
||||
<path
|
||||
style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
||||
d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
|
||||
id="path6711"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccc"
|
||||
id="path6713"
|
||||
d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
|
||||
style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
|
||||
</g>
|
||||
<path
|
||||
d="M 4.5217805,38.687417 C 4.5435766,39.103721 4.9816854,39.520026 5.3979900,39.520026 L 36.725011,39.520026 C 37.141313,39.520026 37.535823,39.103721 37.514027,38.687417 L 36.577584,11.460682 C 36.555788,11.044379 36.117687,10.628066 35.701383,10.628066 L 22.430510,10.628066 C 21.945453,10.628066 21.196037,10.312477 21.028866,9.5214338 L 20.417475,6.6283628 C 20.262006,5.8926895 19.535261,5.5904766 19.118957,5.5904766 L 4.3400975,5.5904766 C 3.9237847,5.5904766 3.5292767,6.0067807 3.5510726,6.4230849 L 4.5217805,38.687417 z "
|
||||
id="path216"
|
||||
style="fill:url(#radialGradient238);fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#linearGradient3104);stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
|
||||
sodipodi:nodetypes="ccccccssssccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
id="path9788"
|
||||
d="M 5.2265927,22.5625 L 35.492173,22.5625"
|
||||
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
id="path9784"
|
||||
d="M 5.0421736,18.5625 L 35.489104,18.5625"
|
||||
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
|
||||
<path
|
||||
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
||||
d="M 4.9806965,12.5625 L 35.488057,12.5625"
|
||||
id="path9778"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
||||
d="M 5.3861577,32.5625 L 35.494881,32.5625"
|
||||
id="path9798"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
id="path9800"
|
||||
d="M 5.5091398,34.5625 L 35.496893,34.5625"
|
||||
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
|
||||
<path
|
||||
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
||||
d="M 5.0421736,16.5625 L 35.489104,16.5625"
|
||||
id="path9782"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
id="path9780"
|
||||
d="M 5.0114345,14.5625 L 35.48858,14.5625"
|
||||
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
id="path9776"
|
||||
d="M 4.9220969,10.5625 L 20.202912,10.5625"
|
||||
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
|
||||
<path
|
||||
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.99999982;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
||||
d="M 4.8737534,8.5624999 L 19.657487,8.5624999"
|
||||
id="path9774"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
||||
d="M 5.3246666,28.5625 L 35.493876,28.5625"
|
||||
id="path9794"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
id="path9792"
|
||||
d="M 5.2880638,26.5625 L 35.493184,26.5625"
|
||||
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
|
||||
<path
|
||||
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
||||
d="M 5.2265927,24.5625 L 35.492173,24.5625"
|
||||
id="path9790"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
||||
d="M 5.1958537,20.5625 L 35.491649,20.5625"
|
||||
id="path9786"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
id="path9796"
|
||||
d="M 5.3246666,30.5625 L 35.493876,30.5625"
|
||||
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
|
||||
<path
|
||||
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
||||
d="M 5.5091398,36.5625 L 35.496893,36.5625"
|
||||
id="path9802"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="color:#000000;fill:url(#linearGradient491);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.2138050;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible;opacity:0.45142857"
|
||||
d="M 6.0683430,38.864023 C 6.0846856,39.176251 5.8874317,39.384402 5.5697582,39.280326 L 5.5697582,39.280326 C 5.2520766,39.176251 5.0330270,38.968099 5.0166756,38.655870 L 4.0689560,6.5913839 C 4.0526131,6.2791558 4.2341418,6.0906134 4.5463699,6.0906134 L 18.968420,6.0429196 C 19.280648,6.0429196 19.900363,6.3433923 20.101356,7.3651014 L 20.674845,10.180636 C 20.247791,9.7153790 20.255652,9.7010175 20.037287,9.0239299 L 19.631192,7.7647478 C 19.412142,7.0371009 18.932991,6.9328477 18.620763,6.9328477 L 5.7329889,6.9328477 C 5.4207613,6.9328477 5.2235075,7.1409999 5.2398583,7.4532364 L 6.1778636,38.968099 L 6.0683430,38.864023 z "
|
||||
id="path219"
|
||||
sodipodi:nodetypes="cccccccccscccccc" />
|
||||
<g
|
||||
style="stroke-miterlimit:4.0000000;stroke-width:0.99946535;stroke:none;fill-rule:nonzero;fill-opacity:0.75706214;fill:#ffffff"
|
||||
id="g220"
|
||||
transform="matrix(1.040764,0.000000,5.449252e-2,1.040764,-8.670199,2.670594)"
|
||||
inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/gnome-fs-directory.png"
|
||||
inkscape:export-xdpi="74.800003"
|
||||
inkscape:export-ydpi="74.800003">
|
||||
<path
|
||||
style="fill-opacity:0.50847459;fill:#ffffff"
|
||||
d="M 42.417183,8.5151772 C 42.422267,8.4180642 42.289022,8.2681890 42.182066,8.2681716 L 29.150665,8.2660527 C 29.150665,8.2660527 30.062379,8.8540072 31.352477,8.8622963 L 42.405974,8.9333167 C 42.417060,8.7215889 42.408695,8.6772845 42.417183,8.5151772 z "
|
||||
id="path221"
|
||||
sodipodi:nodetypes="cscscs" />
|
||||
</g>
|
||||
<path
|
||||
style="color:#000000;fill:url(#linearGradient9772);fill-opacity:1.0;fill-rule:nonzero;stroke:#3465a4;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1;visibility:visible;display:block"
|
||||
d="M 39.783532,39.510620 C 40.927426,39.466556 41.746608,38.414321 41.830567,37.189615 C 42.622354,25.640928 43.489927,15.957666 43.489927,15.957666 C 43.562082,15.710182 43.322016,15.462699 43.009787,15.462699 L 8.6386304,15.462699 C 8.6386304,15.462699 6.7883113,37.329591 6.7883113,37.329591 C 6.6737562,38.311657 6.3223038,39.134309 5.2384755,39.513304 L 39.783532,39.510620 z "
|
||||
id="path233"
|
||||
sodipodi:nodetypes="cscccscc"
|
||||
inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/gnome-fs-directory.png"
|
||||
inkscape:export-xdpi="74.800003"
|
||||
inkscape:export-ydpi="74.800003" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccsscsc"
|
||||
id="path304"
|
||||
d="M 9.6202444,16.463921 L 42.411343,16.528735 L 40.837297,36.530714 C 40.752975,37.602225 40.386619,37.958929 38.964641,37.958929 C 37.093139,37.958929 10.286673,37.926522 7.569899,37.926522 C 7.8034973,37.605711 7.9036547,36.937899 7.9049953,36.92191 L 9.6202444,16.463921 z "
|
||||
style="opacity:0.46590909;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient322);stroke-width:0.99999970px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1.0000000" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
id="path323"
|
||||
d="M 9.6202481,16.223182 L 8.4536014,31.866453 C 8.4536014,31.866453 16.749756,27.718375 27.119949,27.718375 C 37.490142,27.718375 42.675239,16.223182 42.675239,16.223182 L 9.6202481,16.223182 z "
|
||||
style="fill:#ffffff;fill-opacity:0.089285679;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="pattern" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 22 KiB |
BIN
yesod-static/tests/unicode/haskell.png
Normal file
BIN
yesod-static/tests/unicode/haskell.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 683 B |
9
yesod-static/tests/unicode/sample.hs
Normal file
9
yesod-static/tests/unicode/sample.hs
Normal file
@ -0,0 +1,9 @@
|
||||
import Network.Wai.Application.Static
|
||||
import Network.Wai.Handler.Warp (run)
|
||||
|
||||
main :: IO ()
|
||||
main = run 3000 $ staticApp defaultStaticSettings
|
||||
{ ssFolder = fileSystemLookup "."
|
||||
, ssMaxAge = MaxAgeForever
|
||||
, ssIndices = []
|
||||
}
|
||||
7
yesod-static/tests/unicode/test.hs
Normal file
7
yesod-static/tests/unicode/test.hs
Normal file
@ -0,0 +1,7 @@
|
||||
import Network.Wai.Application.Static
|
||||
|
||||
main = do
|
||||
checkPieces "." ["test.hs"] >>= print
|
||||
checkPieces "." ["test.hs", ""] >>= print
|
||||
checkPieces "." ["Network", ""] >>= print
|
||||
checkPieces "." ["Network"] >>= print
|
||||
0
yesod-static/tests/unicode/tests/a/b
Normal file
0
yesod-static/tests/unicode/tests/a/b
Normal file
166
yesod-static/tests/unicode/tests/runtests.hs
Normal file
166
yesod-static/tests/unicode/tests/runtests.hs
Normal file
@ -0,0 +1,166 @@
|
||||
{-# LANGUAGE OverloadedStrings, NoMonomorphismRestriction #-}
|
||||
import Network.Wai.Application.Static
|
||||
|
||||
import Test.Hspec.Monadic
|
||||
import Test.Hspec.QuickCheck
|
||||
import Test.Hspec.HUnit ()
|
||||
import Test.HUnit ((@?=), assert)
|
||||
import Distribution.Simple.Utils (isInfixOf)
|
||||
import qualified Data.ByteString.Char8 as S8
|
||||
import qualified Data.ByteString.Lazy.Char8 as L8
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Encoding as TE
|
||||
import System.PosixCompat.Files (getFileStatus, modificationTime)
|
||||
import System.IO (stderr, hPutStrLn)
|
||||
|
||||
import Network.HTTP.Date
|
||||
{-import System.Locale (defaultTimeLocale)-}
|
||||
{-import Data.Time.Format (formatTime)-}
|
||||
|
||||
import Network.Wai
|
||||
import Network.Wai.Test
|
||||
|
||||
import Network.Socket.Internal as Sock
|
||||
import qualified Network.HTTP.Types as H
|
||||
import Control.Monad.IO.Class (liftIO)
|
||||
|
||||
defRequest :: Request
|
||||
defRequest = Request {
|
||||
rawQueryString = ""
|
||||
, queryString = []
|
||||
, requestMethod = "GET"
|
||||
, rawPathInfo = ""
|
||||
, pathInfo = []
|
||||
, requestHeaders = []
|
||||
, serverName = "wai-test"
|
||||
, httpVersion = H.http11
|
||||
, serverPort = 80
|
||||
, isSecure = False
|
||||
, remoteHost = Sock.SockAddrInet 1 2
|
||||
}
|
||||
|
||||
setRawPathInfo :: Request -> S8.ByteString -> Request
|
||||
setRawPathInfo r rawPinfo =
|
||||
let pInfo = T.split (== '/') $ TE.decodeUtf8 rawPinfo
|
||||
in r { rawPathInfo = rawPinfo, pathInfo = pInfo }
|
||||
|
||||
|
||||
-- debug :: String -> m0 ()
|
||||
debug = liftIO . hPutStrLn stderr
|
||||
|
||||
main :: IO a
|
||||
main = hspecX $ do
|
||||
let must = liftIO . assert
|
||||
|
||||
let webApp = flip runSession $ staticApp defaultWebAppSettings {ssFolder = fileSystemLookup "tests"}
|
||||
let fileServerApp = flip runSession $ staticApp defaultFileServerSettings {ssFolder = fileSystemLookup "tests"}
|
||||
|
||||
let etag = "1B2M2Y8AsgTpgAmY7PhCfg=="
|
||||
let file = "a/b"
|
||||
let statFile = setRawPathInfo defRequest file
|
||||
|
||||
|
||||
describe "Pieces: pathFromPieces" $ do
|
||||
it "converts to a file path" $
|
||||
(pathFromPieces "prefix" [Piece "a" "a", Piece "bc" "bc"]) @?= "prefix/a/bc"
|
||||
|
||||
prop "each piece is in file path" $ \piecesS ->
|
||||
let pieces = map (\p -> Piece p "") piecesS
|
||||
in all (\p -> ("/" ++ p) `isInfixOf` (pathFromPieces "root" $ pieces)) piecesS
|
||||
|
||||
describe "webApp" $ do
|
||||
it "403 for unsafe paths" $ webApp $
|
||||
flip mapM_ ["..", "."] $ \path ->
|
||||
assertStatus 403 =<<
|
||||
request (setRawPathInfo defRequest path)
|
||||
|
||||
it "200 for hidden paths" $ webApp $
|
||||
flip mapM_ [".hidden/folder.png", ".hidden/haskell.png"] $ \path ->
|
||||
assertStatus 200 =<<
|
||||
request (setRawPathInfo defRequest path)
|
||||
|
||||
it "404 for non-existant files" $ webApp $
|
||||
assertStatus 404 =<<
|
||||
request (setRawPathInfo defRequest "doesNotExist")
|
||||
|
||||
it "301 redirect when multiple slashes" $ webApp $ do
|
||||
req <- request (setRawPathInfo defRequest "a//b/c")
|
||||
assertStatus 301 req
|
||||
assertHeader "Location" "../../a/b/c" req
|
||||
|
||||
let absoluteApp = flip runSession $ staticApp $ defaultWebAppSettings {
|
||||
ssFolder = fileSystemLookup "tests", ssMkRedirect = \_ u -> S8.append "http://www.example.com" u
|
||||
}
|
||||
it "301 redirect when multiple slashes" $ absoluteApp $
|
||||
flip mapM_ ["/a//b/c", "a//b/c"] $ \path -> do
|
||||
req <- request (setRawPathInfo defRequest path)
|
||||
assertStatus 301 req
|
||||
assertHeader "Location" "http://www.example.com/a/b/c" req
|
||||
|
||||
describe "webApp when requesting a static asset" $ do
|
||||
it "200 and etag when no etag query parameters" $ webApp $ do
|
||||
req <- request statFile
|
||||
assertStatus 200 req
|
||||
assertNoHeader "Cache-Control" req
|
||||
assertHeader "ETag" etag req
|
||||
assertNoHeader "Last-Modified" req
|
||||
|
||||
it "200 when no cache headers and bad cache query string" $ webApp $ do
|
||||
flip mapM_ [Just "cached", Nothing] $ \badETag -> do
|
||||
req <- request statFile { queryString = [("etag", badETag)] }
|
||||
assertStatus 301 req
|
||||
assertHeader "Location" "../a/b?etag=1B2M2Y8AsgTpgAmY7PhCfg%3D%3D" req
|
||||
assertNoHeader "Cache-Control" req
|
||||
assertNoHeader "Last-Modified" req
|
||||
|
||||
it "Cache-Control set when etag parameter is correct" $ webApp $ do
|
||||
req <- request statFile { queryString = [("etag", Just etag)] }
|
||||
assertStatus 200 req
|
||||
assertHeader "Cache-Control" "max-age=31536000" req
|
||||
assertNoHeader "Last-Modified" req
|
||||
|
||||
it "200 when invalid in-none-match sent" $ webApp $
|
||||
flip mapM_ ["cached", ""] $ \badETag -> do
|
||||
req <- request statFile { requestHeaders = [("If-None-Match", badETag)] }
|
||||
assertStatus 200 req
|
||||
assertHeader "ETag" etag req
|
||||
assertNoHeader "Last-Modified" req
|
||||
|
||||
it "304 when valid if-none-match sent" $ webApp $ do
|
||||
req <- request statFile { requestHeaders = [("If-None-Match", etag)] }
|
||||
assertStatus 304 req
|
||||
assertNoHeader "Etag" req
|
||||
assertNoHeader "Last-Modified" req
|
||||
|
||||
describe "fileServerApp" $ do
|
||||
let fileDate = do
|
||||
stat <- liftIO $ getFileStatus $ "tests/" ++ file
|
||||
return $ formatHTTPDate . epochTimeToHTTPDate $ modificationTime stat
|
||||
|
||||
it "directory listing for index" $ fileServerApp $ do
|
||||
resp <- request (setRawPathInfo defRequest "a/")
|
||||
assertStatus 200 resp
|
||||
let body = simpleBody resp
|
||||
let contains a b = isInfixOf b (L8.unpack a)
|
||||
must $ body `contains` "<img src=\"../.hidden/haskell.png\" />"
|
||||
must $ body `contains` "<img src=\"../.hidden/folder.png\" alt=\"Folder\" />"
|
||||
must $ body `contains` "<a href=\"b\">b</a>"
|
||||
|
||||
it "200 when invalid if-modified-since header" $ fileServerApp $ do
|
||||
flip mapM_ ["123", ""] $ \badDate -> do
|
||||
req <- request statFile {
|
||||
requestHeaders = [("If-Modified-Since", badDate)]
|
||||
}
|
||||
assertStatus 200 req
|
||||
assertNoHeader "Cache-Control" req
|
||||
fdate <- fileDate
|
||||
assertHeader "Last-Modified" fdate req
|
||||
|
||||
it "304 when if-modified-since matches" $ fileServerApp $ do
|
||||
fdate <- fileDate
|
||||
req <- request statFile {
|
||||
requestHeaders = [("If-Modified-Since", fdate)]
|
||||
}
|
||||
assertStatus 304 req
|
||||
assertNoHeader "Cache-Control" req
|
||||
|
||||
8
yesod-static/tests/unicode/unicode.hs
Normal file
8
yesod-static/tests/unicode/unicode.hs
Normal file
@ -0,0 +1,8 @@
|
||||
import System.Directory
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Encoding as TE
|
||||
import qualified Data.ByteString.Char8 as S8
|
||||
|
||||
main = getDirectoryContents "." >>= mapM_ putStrLn . map fix
|
||||
|
||||
fix = T.unpack . TE.decodeUtf8 . S8.pack
|
||||
71
yesod-static/tests/unicode/wai-app-static.cabal
Normal file
71
yesod-static/tests/unicode/wai-app-static.cabal
Normal file
@ -0,0 +1,71 @@
|
||||
name: wai-app-static
|
||||
version: 0.3.0
|
||||
license: BSD3
|
||||
license-file: LICENSE
|
||||
author: Michael Snoyman <michael@snoyman.com>
|
||||
maintainer: Michael Snoyman <michael@snoyman.com>
|
||||
synopsis: WAI application for static serving
|
||||
description: Also provides some helper functions and datatypes for use outside of WAI.
|
||||
category: Web, Yesod
|
||||
stability: Stable
|
||||
cabal-version: >= 1.8
|
||||
build-type: Simple
|
||||
homepage: http://www.yesodweb.com/
|
||||
Extra-source-files: folder.png, haskell.png
|
||||
|
||||
Flag print
|
||||
Description: print debug info
|
||||
Default: False
|
||||
|
||||
library
|
||||
build-depends: base >= 4 && < 5
|
||||
, wai >= 0.4 && < 0.5
|
||||
, bytestring >= 0.9.1.4 && < 0.10
|
||||
, http-types >= 0.6 && < 0.7
|
||||
, transformers >= 0.2.2 && < 0.3
|
||||
, unix-compat >= 0.2 && < 0.3
|
||||
, directory >= 1.0 && < 1.2
|
||||
, containers >= 0.2 && < 0.5
|
||||
, blaze-html >= 0.4 && < 0.5
|
||||
, time >= 1.1.4 && < 1.3
|
||||
, old-locale >= 1.0.0.2 && < 1.1
|
||||
, file-embed >= 0.0.3.1 && < 0.1
|
||||
, text >= 0.5 && < 1.0
|
||||
, blaze-builder >= 0.2.1.4 && < 0.4
|
||||
, base64-bytestring >= 0.1 && < 0.2
|
||||
, cryptohash >= 0.7 && < 0.8
|
||||
, http-date
|
||||
exposed-modules: Network.Wai.Application.Static
|
||||
ghc-options: -Wall
|
||||
extensions: CPP
|
||||
|
||||
if flag(print)
|
||||
cpp-options: -DPRINT
|
||||
|
||||
test-suite runtests
|
||||
hs-source-dirs: tests
|
||||
main-is: runtests.hs
|
||||
type: exitcode-stdio-1.0
|
||||
|
||||
build-depends: base >= 4 && < 5
|
||||
, hspec >= 0.6
|
||||
, HUnit
|
||||
, unix-compat >= 0.2 && < 0.3
|
||||
, time >= 1.1.4 && < 1.3
|
||||
, old-locale >= 1.0.0.2 && < 1.1
|
||||
, http-date
|
||||
, Cabal
|
||||
, wai-app-static >= 0.3
|
||||
, wai-test
|
||||
, wai
|
||||
, http-types
|
||||
, network
|
||||
, bytestring
|
||||
, text
|
||||
, transformers
|
||||
-- , containers
|
||||
ghc-options: -Wall
|
||||
|
||||
source-repository head
|
||||
type: git
|
||||
location: git://github.com/snoyberg/wai-app-static.git
|
||||
48
yesod-static/tests/unicode/warp.hs
Normal file
48
yesod-static/tests/unicode/warp.hs
Normal file
@ -0,0 +1,48 @@
|
||||
{-# LANGUAGE DeriveDataTypeable, RecordWildCards #-}
|
||||
import Network.Wai.Application.Static
|
||||
( StaticSettings (..), staticApp, defaultMimeType, defaultListing
|
||||
, defaultMimeTypes, mimeTypeByExt
|
||||
)
|
||||
import Network.Wai.Handler.Warp (run)
|
||||
import System.Environment (getArgs)
|
||||
import System.Console.CmdArgs
|
||||
import Text.Printf (printf)
|
||||
import System.Directory (canonicalizePath)
|
||||
import Control.Monad (unless)
|
||||
import Network.Wai.Middleware.Autohead
|
||||
import Network.Wai.Middleware.Debug
|
||||
import Network.Wai.Middleware.Gzip
|
||||
import qualified Data.Map as Map
|
||||
import qualified Data.ByteString.Char8 as S8
|
||||
import Control.Arrow (second)
|
||||
|
||||
data Args = Args
|
||||
{ docroot :: FilePath
|
||||
, index :: [FilePath]
|
||||
, port :: Int
|
||||
, noindex :: Bool
|
||||
, quiet :: Bool
|
||||
, verbose :: Bool
|
||||
, mime :: [(String, String)]
|
||||
}
|
||||
deriving (Show, Data, Typeable)
|
||||
|
||||
defaultArgs = Args "." ["index.html", "index.htm"] 3000 False False False []
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
Args {..} <- cmdArgs defaultArgs
|
||||
let mime' = map (second S8.pack) mime
|
||||
let mimeMap = Map.fromList mime' `Map.union` defaultMimeTypes
|
||||
docroot' <- canonicalizePath docroot
|
||||
args <- getArgs
|
||||
unless quiet $ printf "Serving directory %s on port %d with %s index files.\n" docroot' port (if noindex then "no" else show index)
|
||||
let middle = gzip False
|
||||
. (if verbose then debug else id)
|
||||
. autohead
|
||||
run port $ middle $ staticApp StaticSettings
|
||||
{ ssFolder = docroot
|
||||
, ssIndices = if noindex then [] else index
|
||||
, ssListing = Just defaultListing
|
||||
, ssGetMimeType = return . mimeTypeByExt mimeMap defaultMimeType
|
||||
}
|
||||
1
yesod-static/tests/unicode/קרררר.html
Normal file
1
yesod-static/tests/unicode/קרררר.html
Normal file
@ -0,0 +1 @@
|
||||
<h1>HELLO WORLD</h1>
|
||||
0
yesod-static/tests/unicode/שלום
Normal file
0
yesod-static/tests/unicode/שלום
Normal file
0
yesod-static/tests/unicode/ששש/DUMMY.txt
Normal file
0
yesod-static/tests/unicode/ששש/DUMMY.txt
Normal file
Loading…
Reference in New Issue
Block a user