Giter Site home page Giter Site logo

Comments (20)

jeregrine avatar jeregrine commented on May 8, 2024

Were you thinking of handling this within Phoenix or handing it off to cowboy?

from phoenix.

chrismccord avatar chrismccord commented on May 8, 2024

Phoenix is leveraging plug (https://github.com/elixir-lang/plug) behind the scenes. The plan for Plug is to have a middleware like support and include some basic middlewares like static file handling (that would just proxy to cowboy). I'd like to explore using a middlware like approach where each "plug" does some transformations and returns {:ok, conn} for the next middleware consumption. It might be worth prototype out within phoenix and then extracting into a PR to the plug repo.

from phoenix.

chrismccord avatar chrismccord commented on May 8, 2024

@jeregrine Do you have anything pieced together for file handling that we can use as a base?

from phoenix.

jeregrine avatar jeregrine commented on May 8, 2024

Right now it just adds the cowboy static handler to the plug configuration.
I think this could be done in elixir better though.

On Sat, Jan 25, 2014 at 5:22 PM, Chris McCord [email protected]:

@jeregrine https://github.com/jeregrine Do you have anything pieced
together for file handling that we can use as a base?


Reply to this email directly or view it on GitHubhttps://github.com//issues/5#issuecomment-33303877
.

from phoenix.

chrismccord avatar chrismccord commented on May 8, 2024

Do you have an example on GH somewhere?

from phoenix.

jeregrine avatar jeregrine commented on May 8, 2024

Not yet but the basic setup (with no changes to phoenix) looks like:

defmodule Router do
  use Phoenix.Router,
    port: System.get_env("PORT") || 5000,
    dispatch: [{ :_, [{"/static/[...]", :cowboy_static, {:dir,
"priv/static"}}{:_, Plug.Adapters.Cowboy.Handler, { __MODULE__, [] }}]}]

end

That works.

What isn't working is are my macros in phoenix for static "/public", "/static" it doesn't work and its ugly cause I've been futsing with it.
Also because I'm still learning Elixir.
https://github.com/jeregrine/phoenix/tree/websockets_static

All of the stuff is in router.ex, I was looking at atlas fields for
inspiration on adding dispatch configuration to options before adding
options to start.

For the websocket stuff it handler is just a cowboyhandler. But its not as
expressive as your syntax.

On Sat, Jan 25, 2014 at 7:05 PM, Chris McCord [email protected]:

Do you have an example on GH somewhere?


Reply to this email directly or view it on GitHubhttps://github.com//issues/5#issuecomment-33305867
.

from phoenix.

jeregrine avatar jeregrine commented on May 8, 2024

Oh and I stole that dispatch setting from plug's cowboy handler for the
defaults.

On Sat, Jan 25, 2014 at 7:16 PM, Jason S [email protected] wrote:

Not yet but the basic setup (with no changes to phoenix) looks like:

defmodule Router do
  use Phoenix.Router,
    port: System.get_env("PORT") || 5000,
    dispatch: [{ :_, [{"/static/[...]", :cowboy_static, {:dir,
"priv/static"}}{:_, Plug.Adapters.Cowboy.Handler, { __MODULE__, [] }}]}]

end

That works.

What isn't working is are my macros in phoenix for static "/public", "/static" it doesn't work and its ugly cause I've been futsing with it.
Also because I'm still learning Elixir.
https://github.com/jeregrine/phoenix/tree/websockets_static

All of the stuff is in router.ex, I was looking at atlas fields for
inspiration on adding dispatch configuration to options before adding
options to start.

For the websocket stuff it handler is just a cowboyhandler. But its not as
expressive as your syntax.

On Sat, Jan 25, 2014 at 7:05 PM, Chris McCord [email protected]:

Do you have an example on GH somewhere?


Reply to this email directly or view it on GitHubhttps://github.com//issues/5#issuecomment-33305867
.

from phoenix.

jeregrine avatar jeregrine commented on May 8, 2024

I looked into the cowboy static_file_handler and it does a bunch of weird
OS specific stuff :/, so I'm not sure if we want to reimplement it all, use
it or just kind of steal the good parts.

On Sat, Jan 25, 2014 at 7:18 PM, Jason S [email protected] wrote:

Oh and I stole that dispatch setting from plug's cowboy handler for the
defaults.

On Sat, Jan 25, 2014 at 7:16 PM, Jason S [email protected] wrote:

Not yet but the basic setup (with no changes to phoenix) looks like:

defmodule Router do
  use Phoenix.Router,
    port: System.get_env("PORT") || 5000,
    dispatch: [{ :_, [{"/static/[...]", :cowboy_static, {:dir,
"priv/static"}}{:_, Plug.Adapters.Cowboy.Handler, { __MODULE__, [] }}]}]

end

That works.

What isn't working is are my macros in phoenix for static "/public", "/static" it doesn't work and its ugly cause I've been futsing with it.
Also because I'm still learning Elixir.
https://github.com/jeregrine/phoenix/tree/websockets_static

All of the stuff is in router.ex, I was looking at atlas fields for
inspiration on adding dispatch configuration to options before adding
options to start.

For the websocket stuff it handler is just a cowboyhandler. But its not
as expressive as your syntax.

On Sat, Jan 25, 2014 at 7:05 PM, Chris McCord [email protected]:

Do you have an example on GH somewhere?


Reply to this email directly or view it on GitHubhttps://github.com//issues/5#issuecomment-33305867
.

from phoenix.

chrismccord avatar chrismccord commented on May 8, 2024

We should just be able to wrap it and hand the request off to cowboy.

from phoenix.

jeregrine avatar jeregrine commented on May 8, 2024

Well yea thats the easiest way :P I was under the impression you wanted to
make a Plug middleware thats adapter agnostic.

On Mon, Jan 27, 2014 at 1:42 PM, Chris McCord [email protected]:

We should just be able to wrap it and hand the request off to cowboy.


Reply to this email directly or view it on GitHubhttps://github.com//issues/5#issuecomment-33412634
.

from phoenix.

chrismccord avatar chrismccord commented on May 8, 2024

Each plug adapter can implement the details of handing things off to the underlying server. So ideally we could tear out what we come up with and implement it as a Plug middleware (cowboy specific). Once other Plug adapters become available they would be able to follow the same static file plug interface. That said, the Plug middleware spec is still being written, so I'm ok hooking directly into cowboy until we have a clear spec to follow.

from phoenix.

guilleiguaran avatar guilleiguaran commented on May 8, 2024

I think is possible create an adapter agnostic Plug and use Connection.send_file that delegates the file sending to the adapter. File sending is already implemented in the Cowboy adapter and in the Elli adapter that is ready for a pull request.

I'll try to develop the Plug today and post the results here.

from phoenix.

josevalim avatar josevalim commented on May 8, 2024

Also please look at the Dynamo static one:

https://github.com/dynamo/dynamo/blob/master/lib/dynamo/filters/static.ex

As it already has all considerations regarding security too (to avoid filesystem access). The only issue is this line:

https://github.com/dynamo/dynamo/blob/master/lib/dynamo/filters/static.ex#L42

Which accessed the Dynamo but we don't have such concept in Plug. That said, the static plug should probably receive three arguments:

  1. The route to serve static assets from
  2. The otp application the assets will be placed (usually in the priv directory of the given application)
  3. And the path inside the priv directory to use (usually static inside priv) (this one could default to "static" though)

Also note that Dynamo filters allowed work to be done on creation, in that case, in the new function. That was mostly an optimization that does not exist in Plug yet. This will probably be addressed when we make some sort of middIeware stack official.

from phoenix.

jeregrine avatar jeregrine commented on May 8, 2024

Will do. I think I also want to implement actual last modified or etags for at least production

On Wed, Jan 29, 2014 at 3:32 AM, José Valim [email protected]
wrote:

Also please look at the Dynamo static one:
https://github.com/dynamo/dynamo/blob/master/lib/dynamo/filters/static.ex
As it already has all considerations regarding security too (to avoid filesystem access). The only issue is this line:
https://github.com/dynamo/dynamo/blob/master/lib/dynamo/filters/static.ex#L42
Which accessed the Dynamo but we don't have such concept in Plug. That said, the static plug should probably receive three arguments:

  1. The route to serve static assets from
  2. The otp application the assets will be placed (usually in the priv directory of the given application)
  3. And the path inside the priv directory to use (usually static inside priv) (this one could default to "static" though)

Also note that Dynamo filters allowed work to be done on creation, in that case, in the new function. That was mostly an optimization that does not exist in Plug yet. This will probably be addressed when we make some sort of middIeware stack official.

Reply to this email directly or view it on GitHub:
#5 (comment)

from phoenix.

josevalim avatar josevalim commented on May 8, 2024

@jeregrine we could make it configurable. For static assets though it is often more efficient to just set a high expires value, as done in Dynamo. This way you don't have unnecessary requests coming to the web server. The issue is that you then need to generate unique uri paths to your assets. For Dynamo we had the query string approach, by appending the timestamp to the asset path image.jpg?8329837212. We used this to help:

https://github.com/dynamo/dynamo/blob/master/lib/dynamo/static.ex#L12

from phoenix.

jeregrine avatar jeregrine commented on May 8, 2024

Thanks I'll look into that. My plan is to emulate cowboys static file handler. 

I know the assists trick always works but I've got to believe browsers have matured enough to properly handle etags and last modified...

On Wed, Jan 29, 2014 at 8:10 AM, José Valim [email protected]
wrote:

@jeregrine we could make it configurable. For static assets though it is often more efficient to just set a high expires value, as done in Dynamo. This way you don't have unnecessary requests coming to the web server. The issue is that you then need to generate unique uri paths to your assets. For Dynamo we had the query string approach, by appending the timestamp to the asset path image.jpg?8329837212. We used this to help:

https://github.com/dynamo/dynamo/blob/master/lib/dynamo/static.ex#L12

Reply to this email directly or view it on GitHub:
#5 (comment)

from phoenix.

josevalim avatar josevalim commented on May 8, 2024

Well, browsers will still send requests so we can do the request validation. With Expires, browsers don't even bother.

from phoenix.

chrismccord avatar chrismccord commented on May 8, 2024

@guilleiguaran Any luck with a Plug based setup? I have a branch that abstracts Cowboy's static file options into a friendlier approach. Depending on how far off we are from nailing down plug middleware, I may include it as a stop-gap until we can get static file plug middleware in place:

relavant files are here:
https://github.com/phoenixframework/phoenix/blob/cm-static-files/lib/phoenix/router/adapters/cowboy.ex

https://github.com/phoenixframework/phoenix/blob/cm-static-files/lib/phoenix/router/router.ex#L13

Allowing:

defmodule Router do
  use Phoenix.Router, port: 4000,
                      static: [mount: "/assets", priv_dir: "assets"]
  ...
end

from phoenix.

guilleiguaran avatar guilleiguaran commented on May 8, 2024

@josevalim did this already!!

elixir-plug/plug@86c39cd

from phoenix.

chrismccord avatar chrismccord commented on May 8, 2024

Perfect!

from phoenix.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.