zaach / jack forked from 280north/jack
- Source
- Commits
- Network (3)
- Issues (0)
- Downloads (0)
- Wiki (1)
- Graphs
-
Branch:
binary
commit 9f13eb7504e247622ce1d0918d5011b059571336
tree 342fa61faa5768f4ed4d2c5be51514206142757e
parent dd219306d8708a338c99eca525687bcf66209f55
tree 342fa61faa5768f4ed4d2c5be51514206142757e
parent dd219306d8708a338c99eca525687bcf66209f55
jack /
README
Jack: Rack for JavaScript
"Rack provides an minimal interface between webservers supporting Ruby and Ruby
frameworks".replace("Rack","Jack").replace("Ruby","JavaScript")
Indeed, Jack is heavily inspired by Rack (http://rack.rubyforge.org/), as well as Python's WSGI
(http://www.wsgi.org/), with adjustments to suit JavaScript where necessary.
It provides a common interface between web servers and web applications or frameworks written in JavaScript. At it's
core, Jack is simply a protocol that defines an interface, but it is also an implementation of a set of handlers (to
connect to web servers), adapters (to connect to JavaScript frameworks and applications), middleware (to intercept
and manipulate requests or responses), and utilities (to make using Jack easier) implemented in JavaScript.
Homepage: http://jackjs.org/
Source & Download: http://github.com/tlrobinson/jack/
Mailing list: http://groups.google.com/group/jack-js
IRC: #jack-js on irc.freenode.net
== Getting Started:
Jack currently supports the Jetty (and other servlet containers) and Simple webservers using Rhino, and it should be
easy to integrate with other JavaScript interpreters and web servers. It also has preliminary support for v8cgi.
To start working with Jack, ensure you have the Rhino ("js.jar") and Jetty ("jetty", "jetty-util", "servlet-api") or
Simple ("simple") jars in your CLASSPATH environment variable. From the Jack project directory execute "bin/jackup"
with the path to a Jackup configuration file:
./bin/jackup example/hello.js
or (this one specifies a path to an extra library that needs to be included, "lib/jack/lobster.js"):
./bin/jackup -r lib/jack/lobster.js example/example.js
Jackup configuration files simply contain JavaScript with the last statement being a reference to a Jack application
(or middleware)
To see other options of Jackup, use the "-h" option:
./bin/jackup -h
If you want to install and run Jackup from a different directory you can edit the following line at the top of the
jackup (and roundup) scripts to be an absolute path to the "lib" directory:
require.paths.push("lib");
== Writing Jack Applications:
A Jack application is simply a JavaScript function. It should return an array containing three elements: the status
code (an integer), the headers values (a hash), and a body object (anything that responds to the "forEach" method).
We have extended JavaScript Array and String objects to respond to "forEach" (so they are valid "body" responses),
thus the following is a valid Jack application:
function(env) {
return [200, {"Content-Type":"text/plain"}, "Hello world!"];
}
If you need something more complex with extra state, you can provide use a "constructor" in the form of a function
MyApp = function(something) {
return function(env) {
return [200, {"Content-Type":"text/plain"}, "Hello " + this.something + "!"];
}
}
app = MyApp("Fred");
Be careful to ensure you application is threadsafe if you plan to use a multithreaded server.
The first (and only) argument to the application method is the "environment", which contains a number of properties.
Many of the common CGI environment variables are included, as well as some Jack specific properties which are
prefixed with "jack.".
The Request and Response objects aren't required, but may be helpful in parsing request parameters, and building a
valid response. They are used as follows:
var req = new Jack.Request(env);
var name = req.GET("name");
var resp = new Jack.Response();
resp.setHeader("Content-Type", "text/plain");
resp.write("hello ");
resp.write(name);
resp.write("!");
return resp.finish(); // equivalent to returning [200, {"Content-Type" : "text/plain"}, "hello "+name+"!"]
These objects are currently partially implemented.
== Roundabout
Roundabout is a Rack compatible application / middleware that works similarly to the Ruby Sinatra framework.
One major difference is that Roundabout can be used as middleware to map other Rack components to specific URL
patterns, like a more powerful version of the URLMap middleware.
More documentation forthcoming. Run the roundup script with a Roundabout app:
./bin/roundup example/roundup/example.js
== Writing Jack Middleware:
Jack middleware performs some sort of pre or post processing on requests, such as logging, authentication, etc. Most
Jack middleware, by convention (and required for use with the Builder DSL, etc), is a function that takes in one
argument, "app" (which will be a Jack application) and creates a Jack application (i.e. another function that takes
in an "env" argument and returns a three element array). In the returned Jack application it will typically
optionally do some preprocessing on the request, followed by calling the "app" that was provided, optionally
followed by some post processing.
For example, the "Head" middleware calls the "app", then checks to see if the request HTTP method was "HEAD". If so,
it clears the body of response before returning it, since HEAD requests shouldn't have a response body.
A more complicated middleware might need to peform postprocessing on the body contents. A common pattern is to call
the app, then store the body as a property of a "context" and return the context *as* the body instead. It also
defines an "forEach" method on the context, which proxies to the stored body property. It is important to proxy the
response body rather than buffer the entire response when dealing with streaming type applications. A good example
of this pattern is the CommonLogger middleware, which does this in order to calculate the body length for logging.
== Caveats
Thread safety:
Jack is simply a protocol, which is inherently thread safe. Additionally, all these components should be
threadsafe. If you find one that is not, please report it.
Completeness:
The basic functionality of the handlers and middleware is complete. Some things are missing though.
API stability:
The Jack protocol will likely not change significantly, but some of the details may. Keep up to date on the
mailing list mentioned above.
Misc:
Jack depends on a small library currently named "core.js" which contains a basic Ruby-style "require" method as
well as some additions to the built in JavaScript objects, etc. Eventually this will be replaced by a
standardized general purpose API: http://groups.google.com/group/serverjs/
== Differences between Jack and Rack:
Jack applications are simply functions, rather than objects that respond to the "call" method.
== Component Status:
Component Status
--------- ------
Core:
Request: incomplete
Response: incomplete
Utilities:
Jackup: complete (?)
Handlers:
Servlet: complete (?), for use with Jetty on Rhino, or other servlet container.
Jetty: complete (?), simple wrapper for Jetty using Servlet handler (http://www.mortbay.org/jetty/)
Simple: complete (?), for use with the Simple webserver (http://www.simpleframework.org/)
V8CGI: complete (?), for use with the v8cgi project (http://code.google.com/p/v8cgi/)
Middleware:
Cascade: complete
CommonLogger: complete
ContentLength: complete
Deflater: missing
Directory: missing
File: complete
Head: complete
JSONP: complete
Lint: mostly complete (needs stream wrappers)
MethodOverride: complete
Mock: missing
Recursive: missing
ShowExceptions: simple version complete, needs better HTML output
ShowStatus: missing
Static: complete
URLMap: complete
== Acknowledgments
This software was influenced by Rack, written by Christian Neukirchen.
http://rack.rubyforge.org/
== License:
Copyright (c) 2009 Thomas Robinson <tlrobinson.net>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

