pandeiro / boot-http

A simple HTTP serve task for the Boot build tool
62 stars 34 forks source link

Add option for providing a custom 404 handler #35

Closed briandunn closed 8 years ago

briandunn commented 8 years ago

This is for issue #23. It allows the specification of a custom 404 handler.

Here is an example:

(deftask dev []
  (comp
    (serve :not-found 'history-app :dir "target" :reload true)
    ...
   ))

And a handler that returns the main document on 404:

(defn history-app [request]
  (assoc-in
    (file-response "target/index.html")
    [:headers "Content-Type"]
    "text/html;charset=utf8"))
pandeiro commented 8 years ago

Thanks for the contribution, @briandunn. Similarly to my comment here, I'm kind of wondering if something like this couldn't be either published as a separate handler or be factored into one's app logic, instead of adding an additional option to boot-http, whose options list has been growing to the point where testing is getting difficult.

Can you tell me how significant a difference it makes for your use case for this to be included in boot-http proper vs. either as a library or in your app's source code? My thinking at this point is that I prefer the latter option unless it greatly complicates this use-case.

briandunn commented 8 years ago

I totally get that perspective. It honestly makes little difference in my use case. I only implemented it to satisfy your suggestion here: https://github.com/pandeiro/boot-http/issues/23#issuecomment-145364500 and in an attempt to be useful to this project. Feel free to close and no offense will be taken. :smile:

pandeiro commented 8 years ago

Hey Brian, just letting you know that I've seen some other users request this and I'm now thinking it does belong. I'll just need to resolve some conflicts with other changes but as soon as I have time, I'll do that. Thanks again for the contribution!

briandunn commented 8 years ago

Cool! Thanks for the update and I'm happy to be useful.

Sent from my iPhone

On Feb 5, 2016, at 6:47 AM, Murphy McMahon notifications@github.com wrote:

Hey Brian, just letting you know that I've seen some other users request this and I'm now thinking it does belong. I'll just need to resolve some conflicts with other changes but as soon as I have time, I'll do that. Thanks again for the contribution!

— Reply to this email directly or view it on GitHub.

theronic commented 8 years ago

Any idea when, and if, this functionality could be added or merged in? Would love to be able to refresh my dev window again with pushState and not get 404 on missing paths :).

theronic commented 8 years ago

Anything I can do to help?

pandeiro commented 8 years ago

Released as 0.7.3

theronic commented 8 years ago

Thanks, @pandeiro. Love seeing this in, but I'm struggling to get this to work. Still getting the plain Jetty 404 message. Here is my code from build.boot:

(defn my-not-found-handler [request]
  (assoc-in
    (file-response "target/index.html")
    [:headers "Content-Type"]
    "text/html;charset=utf8"))

(deftask run []
  (comp (serve :not-found 'my-not-found-handler)
        (watch)
        (cljs-repl)
        (reload)
        (build)))

Am I doing something wrong?

Then I moved my handler to a namespace and ran this:

boot -d pandeiro/boot-http serve -d "target" -N reps.server/not-found-handler wait

where reps.server is my namespace. This seems to work, but intercept other files too, e.g. /js/app.js. Maybe I need to set a :root somewhere?

pandeiro commented 8 years ago

Hey @pate, so yeah, you definitely need to fully reference the var of your function, and that namespace has to be within one of your :source-paths: that's why it won't work defining it in build.boot.

About the other problem: I would just check that the paths are really correct relative to target, ie, is that file at target/js/app.js? You could also try not using the -d option and serving resources from the classpath, in which case you may need to change :resource-root to descend into the subdirectory where you want to place your compiled javascript, etc.

theronic commented 8 years ago

I still can't get this to work as part of my task chain, only via boot -d pandeiro/boot-http serve -d ... as above :(. Is anyone else successfully using this? Can anyone else post their code or document how to get it working as part of a dev task?

briandunn commented 8 years ago

@pate can you share your code?

theronic commented 8 years ago

@briandunn, here you go: https://gist.github.com/pate/012aa87329eeadbba3ee

In server.clj:

(defn not-found-handler [request]
  (assoc-in
    (file-response "target/index.html")
    [:headers "Content-Type"]
    "text/html;charset=utf8"))

And here is how I use it:

(deftask run []
  (comp (serve :not-found 'not-found-handler) ;; refer'ed not-found-handler
        (watch)
        (cljs-repl)
        (reload)
        (build)))

(deftask development []
  (task-options! cljs {:optimizations :none :source-map true}
                 reload {:on-jsload 'web.app/mount})

(deftask dev
  "Simple alias to run application in development mode"
  []
  (comp (development)
        (run)))

I do dev by running:

boot dev
briandunn commented 8 years ago

@pate looks like you'll need to change this

(serve :not-found 'not-found-handler)

to this

(serve :not-found 'reps.server/not-found-handler)

Note that this is the same type of fully qualified reference used here: https://gist.github.com/pate/012aa87329eeadbba3ee#file-build-boot-L51

Once you add the namespace, and as long as server.clj is in your src/clj path, the function name should resolve.

theronic commented 8 years ago

@briandunn, I tried that - doesn't work. Here is an empty tenzing project with everything stripped away to reproduce it not working as instructed. Assuming the not-found handler symbol cannot be resolved, then boot-http should probably error out?

briandunn commented 8 years ago

Hi @pate, I just want to confirm that this is definitely not working as I expected. Thanks for digging into this and i'll follow up shortly.

briandunn commented 8 years ago

Ok @pate, You must also specify the directory option for the not-found handler to work. This is clearly not ideal. Making it work with the default resources handler shouldn't be too tricky. For now you can specify :dir like this: https://github.com/briandunn/boot-http-not-found-test/commit/d8cd0760dfc18ac40a0db66b0a99056f58ef0581#diff-0a1425bd66240468daf4c256a411ce75L26

So either it should be implemented for all handlers, or it should print an error message when specified but not applicable.

dimitertodorov commented 8 years ago

So I have a problem now, my HTML is loading fine when I go to a Sub-Route like

http://localhost:3000/test/potato

However, this is messing up the relative JS and CSS loading when I go there. It is trying to load the app.js and other JS/CSS files from the /test subdirectory Is there a simple way to fix this.

binarykitchen commented 8 years ago

Hmmm, it is possible to have the not found handler defined in build.boot itself?

Tried for example:

(defn- not-found-handler [_]
  (println "heeelllooo" _)
  (assoc-in
    (file-response "target/index.html")
    [:headers "Content-Type"]
    "text/html;charset=utf8"))

(deftask run []
  (comp (serve :port 1112 :not-found 'not-found-handler)
    (watch)
    (cljs-devtools)
    (reload)
    (build)))

But no luck. When I open i.E. http://10.0.0.129:1112/sdfsdf.html, Jetty returns it's default 404 page. And the "heeelllooo" output is never printed to the console. Which means, that not found handler isn't really run.

Any clues? Using latest versions here.

JaHIY commented 8 years ago

@dimitertodorov please checkout https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base