catch all for static files ?

Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

catch all for static files ?

Andreas Reuleaux-2
Hi,

I can successfully server static files, e.g. in directorty static, as in

  <link href="./static/main.css" media="screen" type="text/css" rel="stylesheet" />

with

    type API = ...
               :<|> "static" :> Raw


    api :: Proxy API
    api = Proxy


    srv :: Server API
    srv = ...
          :<|> (serveDirectoryFileServer "static")



Now I wonder, if it would be possible to serve

  <link href="./main.css" media="screen" type="text/css" rel="stylesheet" />


as well, with some kind of catch all rule (not working, but you get the idea, hopefully):



    type API = ...
               :<|> "." :> Raw


    api :: Proxy API
    api = Proxy


    srv :: Server API
    srv = ...
          :<|> (serveDirectoryFileServer ".")



Is that possible ? Thanks.

- Andreas


--





Reply | Threaded
Open this post in threaded view
|

Re: catch all for static files ?

Alp Mestanogullari
By "as well", do you mean that you would like to serve the actual main.css file under both /main.css and /static/main.css, something along those lines? 

On Sat, Aug 11, 2018 at 4:44 AM Andreas Reuleaux <[hidden email]> wrote:
Hi,

I can successfully server static files, e.g. in directorty static, as in

  <link href="./static/main.css" media="screen" type="text/css" rel="stylesheet" />

with

    type API = ...
               :<|> "static" :> Raw


    api :: Proxy API
    api = Proxy


    srv :: Server API
    srv = ...
          :<|> (serveDirectoryFileServer "static")



Now I wonder, if it would be possible to serve

  <link href="./main.css" media="screen" type="text/css" rel="stylesheet" />


as well, with some kind of catch all rule (not working, but you get the idea, hopefully):



    type API = ...
               :<|> "." :> Raw


    api :: Proxy API
    api = Proxy


    srv :: Server API
    srv = ...
          :<|> (serveDirectoryFileServer ".")



Is that possible ? Thanks.

- Andreas


--


--
Alp Mestanogullari

--
Reply | Threaded
Open this post in threaded view
|

Re: catch all for static files ?

Andreas Reuleaux-2
Well, thanks for getting back to me.

I have just very few static files (for the purpose of this
discussion, say just one: main.css), and would like to serve
them, without having to put them in a directory static,
from my current directory ie.

I would then reference "main.css" with

  <link href="./main.css" media="screen" type="text/css" rel="stylesheet" />

for example, not with

  <link href="./static/main.css" media="screen" type="text/css" rel="stylesheet" />

Thus you may read my question as: "serve a single static file from the current
directory?". - If I have more than one static file to serve (say three), then
it doesn't really matter to me, if I have three lines of code to add (pseudo code):

   serve file1.css
   serve file2.pdf
   serve file3.txt

or (preferrably) just one line to add: serve current directory

  serve "."

I do not want to get into a discussion, whether it's a good idea to do so, or not
(I can well see the advantage of having a directory "static" for a production system),
I just want the system to behave my preferred way (...href="./main.css"), not the other
way around: having to adapt to the system's limitations (...href="./static/main.css").

For what it's worth: I have meanwhile found a solution, albeit terribly
complicated (see below), thus I wonder if there is simpler way:

Thanks again,
  Andreas

--------------------

import GHC.Generics
import Network.HTTP.Media ((//))
import Network.Wai.Handler.Warp
import Servant
import Data.Typeable (Typeable)
import qualified Data.ByteString.Lazy as L
import Network.HTTP.Media ((/:))


data Css deriving Typeable

instance Accept Css where
   contentType _ = "text" // "css" /: ("charset", "utf-8")

newtype RawFile = RawFile { unRawFile :: L.ByteString }


instance MimeRender Css RawFile where
    mimeRender _ =  unRawFile


      -- It can be anywhere in your API except the last line.
type API = ...
           :<|> "main.css" :> Get '[Css] RawFile

 
api :: Proxy API
api = Proxy


-- srv :: Handler RawHtml
srv :: Server API
srv
  = ...
    :<|> ( fmap RawFile (liftIO $ do L.readFile "/home/rx/work/site/main.css" ) )


 





Alp Mestanogullari <[hidden email]> writes:

> By "as well", do you mean that you would like to serve the actual main.css
> file under both /main.css and /static/main.css, something along those
> lines?
>
> On Sat, Aug 11, 2018 at 4:44 AM Andreas Reuleaux <[hidden email]> wrote:
>
>> Hi,
>>
>> I can successfully server static files, e.g. in directorty static, as in
>>
>>   <link href="./static/main.css" media="screen" type="text/css"
>> rel="stylesheet" />
>>
>> with
>>
>>     type API = ...
>>                :<|> "static" :> Raw
>>
>>
>>     api :: Proxy API
>>     api = Proxy
>>
>>
>>     srv :: Server API
>>     srv = ...
>>           :<|> (serveDirectoryFileServer "static")
>>
>>
>>
>> Now I wonder, if it would be possible to serve
>>
>>   <link href="./main.css" media="screen" type="text/css" rel="stylesheet"
>> />
>>
>>
>> as well, with some kind of catch all rule (not working, but you get the
>> idea, hopefully):
>>
>>
>>
>>     type API = ...
>>                :<|> "." :> Raw
>>
>>
>>     api :: Proxy API
>>     api = Proxy
>>
>>
>>     srv :: Server API
>>     srv = ...
>>           :<|> (serveDirectoryFileServer ".")
>>
>>
>>
>> Is that possible ? Thanks.
>>
>> - Andreas
>>
>>
>> --
>>
>> "haskell-servant" group.
>>
>> email to [hidden email].
>>
>>
>> https://groups.google.com/d/msgid/haskell-servant/87tvo1d3lp.fsf%40a-rx.info
>> .
>>
>>
>
>
> --
> Alp Mestanogullari

--





Reply | Threaded
Open this post in threaded view
|

Re: catch all for static files ?

Alp Mestanogullari
Well, one option would be to just have

type API = ... :<|> Raw
server = ... :<|> serveDirectory "."

but this may expose files that are not meant to be served.

Another reasonable option is the one you came up with. Somewhere in between you'd have a close cousin of serveDirectory that would just serve a given list of files and nothing else. You'd have to implement it but just once.

Finally, I think I have seen a servant-static-th package that uses TH to embed static files to be served directly into the executable. This may or may not be a satisfactory solution for youbut it certainly is relevant.

I think this is all my brain has in store for your problem at the moment.

Le dim. 12 août 2018 00:24, Andreas Reuleaux <[hidden email]> a écrit :
Well, thanks for getting back to me.

I have just very few static files (for the purpose of this
discussion, say just one: main.css), and would like to serve
them, without having to put them in a directory static,
from my current directory ie.

I would then reference "main.css" with

  <link href="./main.css" media="screen" type="text/css" rel="stylesheet" />

for example, not with

  <link href="./static/main.css" media="screen" type="text/css" rel="stylesheet" />

Thus you may read my question as: "serve a single static file from the current
directory?". - If I have more than one static file to serve (say three), then
it doesn't really matter to me, if I have three lines of code to add (pseudo code):

   serve file1.css
   serve file2.pdf
   serve file3.txt

or (preferrably) just one line to add: serve current directory

  serve "."

I do not want to get into a discussion, whether it's a good idea to do so, or not
(I can well see the advantage of having a directory "static" for a production system),
I just want the system to behave my preferred way (...href="./main.css"), not the other
way around: having to adapt to the system's limitations (...href="./static/main.css").

For what it's worth: I have meanwhile found a solution, albeit terribly
complicated (see below), thus I wonder if there is simpler way:

Thanks again,
  Andreas

--------------------

import GHC.Generics
import Network.HTTP.Media ((//))
import Network.Wai.Handler.Warp
import Servant
import Data.Typeable (Typeable)
import qualified Data.ByteString.Lazy as L
import Network.HTTP.Media ((/:))


data Css deriving Typeable

instance Accept Css where
   contentType _ = "text" // "css" /: ("charset", "utf-8")

newtype RawFile = RawFile { unRawFile :: L.ByteString }


instance MimeRender Css RawFile where
    mimeRender _ =  unRawFile


      -- It can be anywhere in your API except the last line.
type API = ...
           :<|> "main.css" :> Get '[Css] RawFile


api :: Proxy API
api = Proxy


-- srv :: Handler RawHtml
srv :: Server API
srv
  = ...
    :<|> ( fmap RawFile (liftIO $ do L.readFile "/home/rx/work/site/main.css" ) )








Alp Mestanogullari <[hidden email]> writes:

> By "as well", do you mean that you would like to serve the actual main.css
> file under both /main.css and /static/main.css, something along those
> lines?
>
> On Sat, Aug 11, 2018 at 4:44 AM Andreas Reuleaux <[hidden email]> wrote:
>
>> Hi,
>>
>> I can successfully server static files, e.g. in directorty static, as in
>>
>>   <link href="./static/main.css" media="screen" type="text/css"
>> rel="stylesheet" />
>>
>> with
>>
>>     type API = ...
>>                :<|> "static" :> Raw
>>
>>
>>     api :: Proxy API
>>     api = Proxy
>>
>>
>>     srv :: Server API
>>     srv = ...
>>           :<|> (serveDirectoryFileServer "static")
>>
>>
>>
>> Now I wonder, if it would be possible to serve
>>
>>   <link href="./main.css" media="screen" type="text/css" rel="stylesheet"
>> />
>>
>>
>> as well, with some kind of catch all rule (not working, but you get the
>> idea, hopefully):
>>
>>
>>
>>     type API = ...
>>                :<|> "." :> Raw
>>
>>
>>     api :: Proxy API
>>     api = Proxy
>>
>>
>>     srv :: Server API
>>     srv = ...
>>           :<|> (serveDirectoryFileServer ".")
>>
>>
>>
>> Is that possible ? Thanks.
>>
>> - Andreas
>>
>>
>> --
>> >> "haskell-servant" group.
>> >> email to [hidden email].
>> >> >> https://groups.google.com/d/msgid/haskell-servant/87tvo1d3lp.fsf%40a-rx.info
>> .
>> >>
>
>
> --
> Alp Mestanogullari

--

--
Reply | Threaded
Open this post in threaded view
|

Re: catch all for static files ?

Andreas Reuleaux-2
Alp Mestanogullari <[hidden email]> writes:

> Well, one option would be to just have
>
> type API = ... :<|> Raw
> server = ... :<|> serveDirectory "."
>
> but this may expose files that are not meant to be served.


Ah, OK, I see: just

  type API = ... :<|> Raw
  server = ... :<|> serveDirectory "."

I thought, I had tried that before, with no luck but now
I can see that it is working fine - my bad.

Thanks a lot. I will try your other suggestions in the next days
as time permits.

-A



>
> Another reasonable option is the one you came up with. Somewhere in between
> you'd have a close cousin of serveDirectory that would just serve a given
> list of files and nothing else. You'd have to implement it but just once.
>
> Finally, I think I have seen a servant-static-th package that uses TH to
> embed static files to be served directly into the executable. This may or
> may not be a satisfactory solution for youbut it certainly is relevant.
>
> I think this is all my brain has in store for your problem at the moment.
>
> Le dim. 12 août 2018 00:24, Andreas Reuleaux <[hidden email]> a écrit :
>


--