This looks really cool. I've actually been experimenting with exactly
the same thing. One thing I thought about (but didn't implement), was
using some kind of lazy hash map, for the request, so that it only
calls the methods (like getServerPort) if you need them. I don't
really know how hard or easy that would be though.

cheers,
Kees

On Jan 13, 6:19 am, Paul Barry <pauljbar...@gmail.com> wrote:
> To answer my own question:
>   [#^HttpServletRequest request]
>   {:server-port (.getServerPort request)
>    :server-name (.getServerName request)
>    :remote-addr (.getRemoteAddr request)
>    :uri (.getRequestURI request)
>    :query-string (.getQueryString request)
>    :scheme (keyword (.getScheme request))
>    :request-method (keyword (.toLowerCase (.getMethod request)))
>    :headers (reduce
>                           (fn [header-map #^String header-name]
>                             (assoc header-map
>                               (.toLowerCase header-name)
>                               (.getHeader request header-name)))
>                           {}
>                           (enumeration-seq (.getHeaderNames request)))
>    :content-type (.getContentType request)
>    :content-length (let [len (.getContentLength request)]
>                          (if (>= len 0) len))
>    :character-encoding (.getCharacterEncoding request)
>    :body (.getInputStream request)})
>
> Which by the way is awesome, because you function takes a map, which doesn't
> have to be created from an HttpServletRequest object.  For the purposes of
> testing, you can just construct a map with the parts you want and pass that
> to your function.  Great Work!
>
> On Tue, Jan 13, 2009 at 1:13 AM, Paul Barry <pauljbar...@gmail.com> wrote:
> > What's does the req object that is passed into the function have in it?
>
> > On Mon, Jan 12, 2009 at 11:45 PM, Mark McGranaghan 
> > <mmcgr...@gmail.com>wrote:
>
> >> Hi All,
>
> >> I'm happy to announce the alpha release of 'Ring', a library inspired
> >> by Python's WSGI and Ruby's Rack for developing web applications in
> >> Clojure.
>
> >> I've made it as easy as humanly possible for you to try it out:
>
> >>    git clone git://github.com/mmcgrana/ring.git
> >>    cd ring
> >>    java -Djava.ext.dirs=jars clojure.main src/ring/examples/
> >> hello_world.clj
>
> >> And your up and running with your first Ring web app, which you can
> >> see athttp://localhost:8080/in your browser.
>
> >> The basic idea of Ring is that web apps are just Clojure functions
> >> that take a standardized request as a single argument and return and
> >> standardized response. For example, the hello_world.clj script from
> >> above is:
>
> >>   (ns ring.examples.hello-world
> >>     (:require ring.jetty)
> >>     (:import java.util.Date java.text.SimpleDateFormat))
>
> >>   (def formatter (SimpleDateFormat. "HH:mm:ss"));
>
> >>   (defn app
> >>     [req]
> >>     {:status  200
> >>      :headers {"Content-Type" "text/html"}
> >>      :body    (str "<h3>Hello World from Ring</h3>"
> >>                    "<p>The current time is "
> >>                    (.format formatter (Date.)) ".</p>")})
>
> >>   (ring.jetty/run {:port 8080} app)
>
> >> Its nice to be able to get to "Hello World" so quickly, but the real
> >> power of Ring is that apps are just functions - hence we can combine,
> >> wrap, curry, and generally manipulate them as first class values.
>
> >> For example, someone asked in #clojure today how they could make their
> >> web app provide a cleaned backtrace as an HTML response when it raised
> >> exceptions. To add such exception handling to our Hello World Ring app
> >> we would just use the ring.backtrace middleware:
>
> >>    (ring.jetty/run {:port 8080} app)
>
> >>    becomes
>
> >>    (ring.jetty/run {:port 8080}
> >>      (ring.backtrace/wrap
> >>        app))
>
> >> Similarly, one might want to have changes to a web app's code be
> >> reflected in real time in the development environment, so as to avoid
> >> constantly having to reboot the webserver. The ring.reload middleware
> >> accomplishes exactly that:
>
> >>    (ring.jetty/run {:port 8080}
> >>      (ring.backtrace/wrap
> >>        (ring.reload/wrap '(ring.examples.hello-world)
> >>          app)
>
> >> These are some of the features that originally motivated me to develop
> >> Ring, but the complete list of functionality available to Ring apps is
> >> larger and continues to grow:
>
> >> * ring.jetty: Handler for the Jetty webserver.
> >> * ring.file: Middleware that serves static files out of a public
> >> directory.
> >> * ring.file-info: Middleware that augments response headers with info
> >> about File responses.
> >> * ring.dump: Endpoint that dumps the Ring requests as HTML responses
> >> for debugging.
> >> * ring.show-exceptions: Middleware that catches exceptions and
> >> displays readable backtraces for debugging.
> >> * ring.reload: Middleware to automatically reload selected libs before
> >> each requests, minimizing server restarts.
> >> * ring.builder: Helpers for combining Ring endpoints and middleware
> >> into Ring apps.
> >> * ring.lint: Linter for the Ring interface, ensures compliance with
> >> the Ring spec.
> >> * ring.examples.*: Various example Ring apps.
>
> >> You can find more details about Ring at its project page on GitHub,
> >> including a README file for new users and a draft SPEC file that
> >> documents the Ring interface:
>
> >>http://github.com/mmcgrana/ring
>
> >> I've built an open source web app on Ring:http://cljre.com. The
> >> source for this simple app, available at
> >>http://github.com/mmcgrana/cljre.com,
> >> could serve as a good introduction to how apps can consume Ring
> >> requests and to the use of modular Ring middleware; see in particular
> >> the src/cljre/app.clj file, where most of that application is defined.
>
> >> Also, I think I should mention how I see Ring relating to the Java
> >> Servlet abstraction and to existing and new Clojure web frameworks.
> >> Ring heavily leverages the Servlet API internally, as I strongly
> >> believe in not reinventing wheels such as basic HTTP parsing.
> >> Furthermore, I think that the interface that Ring presents to Clojure
> >> web application developers by pre-processing the servlet requests is
> >> dramatically more useful than that of the raw servlet. Ring uses
> >> Servlets for what they are really good at - implementing HTTP - and
> >> presents a simple API against which additional logic can be defined in
> >> the application layer.
>
> >> In terms of Clojure web frameworks, I think that there is a lot to be
> >> gained by leveraging the Ring interface, especially from the modular
> >> functionality provided by Ring middleware. I'd like in particular to
> >> be able to run Compojure apps in Ring - if the users and authors of
> >> Compojure are interested I'd be happy to work with them to see what we
> >> can do.
>
> >> If you've made it this far, thanks a lot for reading! I welcome any
> >> comments or suggestions that you have about Ring, the draft SPEC
> >> document, or the Clojure web app space in general.
>
> >> Thanks again,
> >> - Mark
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to