# [Magic 2](http://magic.xmog.com) By Ed Watkeys, edw@xmog.com. ## License Unless a source file specifies otherwise, all code in Magic is provided under a BSD-style license described in the LICENSE file. ## What's new? * If insufficient arguments are provided to an RPC request, a JSON error object is returned. It is a list containing three elements: the string "ERROR", a description of the error, and a list of expected arguments. THIS IS NOT AN ACCEPTABLE ERROR HANDLING MECHANISM, BUT IT'S ACCEPTABLE ENOUGH FOR NOW. * Added a `stack` package. * Conditions raised by application code are now trapped and an internal error page is displayed -- if the `debugging?` flag is set to `#f` in the server package. (`debugging?` is `#f` by default.) Otherwise, a condition is raised in the REPL. You can see the condition stack by going into the server package and looking at the `request-errors` stack e.g. `(peek request-errors)`. * JSON support now respects RFC 4627. * Moved `pages` directory into `demo` directory. Everything for the demo app should be in the `demo` directory. * Added `start-demo` procedure, so I no longer need to constantly tell Darcs that I don't want to commit the real database password to the public source repository. * Renamed `framework-packages.scm` to `packages.scm`, since there's no longer a need to distinguish between two packages files in the top-level directory. * For source control and general organizational reasons, moved `app-packages.scm` to `demo/packages.scm`. By adopting this convention, all files for an application reside in a directory, which will allow them to be managed independently for version control purposes. This is motivated by the development of our corporate web site, which is the application that drives development of Magic. Until now, it hasn't had its own darcs repository, making synchronization between the corporate site and the Magic repository tedious. * I'm working on removing code from Magic that is already implemented in Scheme48. Much of the string-utilities package has been gutted, as the exported procedures were similar to procedures available from SRFIs 13 and 14. * `Current-request`, `current-response`, and `exit-registered-procedure` have been removed, because their motivation is no longer relevant. With `register-plain-proc!`, there's an easy way to get at the request and response objects. * The demo application files have been moved into a new `demo` sub-directory. * The framework packages are now in `framework-packages.scm`, while application-specific packages are in `app-packages.scm`. This is a good thing, but it was done mostly to make version control easier to deal with when modifying the Magic core while working on applications other than the demonstration code. * The bidirectional pipes package no longer leaves zombie processes lying around. * Some additional comments may be in order regarding the removal of condition trapping code. If you really want to protect against conditions bringing your Magic instance to a screeching halt, you should trap conditions that might occur in your code. I've turned condition trapping off in large part to smoke out any bugs in the Magic core. * The code that contains conditions (errors, warnings, etc.) in `handle-request` has been removed, so that debugging using the SLIME or Scheme48 debuggers is practical. This change was made because the preferred method of deploying Magic applications is now via SLIME. * `Start-server` takes a second argument, the server name. This value is available in the `CONNECTOR_NAME` request key. The port number of the Magic SCGI listener is also now available in a request's `CONNECTOR_PORT_NUMBER` key. Additionally, multiple servers can be started and stopped independently. The `stop-server` procedure now requires a port number. Some additional error checking is now done so a server can't be started on the same port more than once, which would trash important data. * A demo, "Supertrain", is available at /redwood.html. It's an example of using the Safari (and Firefox) canvas object and retrieves regular status updates from the server using JSON. * `register-proc!` and `register-procs!` have been renamed to `register-rpc-proc!` and `register-rpc-procs!`. Two new procedures, `register-plain-proc!` and `register-plain-procs!`, allow you to register procedures that take two arguments, a request and a response object. (Moe Aboulkheir) * The `response` package contains a new procedure `set-response-html!` that takes two arguments, a response object and a chunk of text. It sets the content type of the response to "text/html". * The `session` package brings support for the automatic generation of unique session identifiers, stored under the "SESSION" key in request objects. Session identifier are references to the primary key of the `magic_session` PostgreSQL table, which you must create in order for session support to function. Create the table with this chunk of SQL: `CREATE TABLE magic_session (magic_session_id serial primary key, hash text not null, created_ts timestamp not null default now(), seen_ts timestamp not null default now(), originating_referrer text not null, request_count integer not null default 0)`. The session mechanism is designed around the assumption that all data that outlives the current request will be stored in PostgreSQL, and the session identifier is the primary key for storing such data. Design your tables using foreign keys to make your life as easy as possible. * The `string-utilities` package now has `path-ref` a procedure of two arguments, a string and an integer. It breaks the slash-delimited string into its components and returns the nth component, or the empty string, if the nth component does not exist. The returned components is run through the `url-decode` procedure. ## What is Magic? Magic is a platform for developing web applications. At this time, I am focusing on a style of web application development where Javascript code construct pages from the JSON objects produced by procedures published to a web server. Magic supports the PostgreSQL database via the C PostgreSQL library. Magic supports simple connection pooling and of procedures that make using the database very simple. Positional parameters are supported, which protect against SQL injection attacks -- if you use them. ## Running the sample application Run Scheme48 with the current working directory set to the base Magic directory. In Scheme48, load `packages.scm` into the configuration package by typing ",config ,load framework-packages.scm". Similarly, load `demo/packages.scm` into the configuration package. Next, go into the `application` structure by typing ",in application". Finally, start the SCGI server using the `start-demo` procedure with the desired port number and your database password as arguments, e.g. `(start-demo 9990 "password")`. You can test the server without using Lighttpd or Apache by using netcat to pipe the test/scgi-request.txt file to the port on which your started the server. ## PostgreSQL support Note that you must build the PostgreSQL library in `c/` by typing `make -f Makefile.` and have PostgreSQL running with a user/role of "xmog" with a database named "xmog" for the sample application to function properly. (You can of course change the connection information in `main.scm`.) Sample data is provided for the resource repository in the `test/database.sql` file. If you don't have PostgreSQL installed, you will not be able to build the PostgreSQL library. In order to run the sample without PostgreSQL, follow these steps: * In `packages.scm`, remove the reference to the `postgresql` structure in the `open` clause of the structure definition for `application` and `session`. Session support requires PostgreSQL. * In `main.scm`, comment out the `set-connection-information!` expression and the `current-time` procedure. ## Web server configuration An example Lighttpd configuration file is provided in etc/lighttpd.conf. ## Warning This is pre-release software. Interfaces may change. There is no documentation. ## Patch submissions Please submit patches to edw@xmog.com. ## Contacting the author I am often signed onto #scheme on the Freenode chat network with the nick 'edw'. You can also send me an e-mail message at edw@xmog.com.