Chapter 6. Request Bindings

Table of Contents

Extracting Bindings
Extracting Bindings from Java
Bindings and Security

Bindings associated with the request returned by the send-*/(suspend|forward) functions, or passed as parameters to procedures that are either published or the target of a dispatch, can be extracted and associated to language-level variables.

Bindings, as returned by the function get-bindings are contained in an opaque object. This object can be converted to an association list via bindings->alist, or queried in constant time using the extract-bindings or extract-single-binding functions. The object is guaranteed to be serializable, but code should not rely on its specific implementation.

Requires: (import siscweb/bindings)
Located in: siscweb.jar

This module assists developers in obtaining values of parameters passed in a request.

Bindings specified in the send-forward/* functions are assigned to request attributes. This method supercedes the previous request.getBinding*() API, which is now deprecated and will be removed in the next release.

Multi-valued bindings, as in '((messages "hello" "there")), are turned into a java.util.List and can be easily scanned using such tools as JSTL's <c:forEach>. Single-valued bindings, such as '((message . "hello")) are simply assigned to the attribute.

Multi-valued bindings originating from a Scheme list are also marked as such, so that they can be converted back to a list of values rather than to an object of type java.util.List.

A minimal amount of type conversion is performed. Scheme values are passed as SISC objects, except for Scheme strings, which are converted to Java strings. Java objects are left untouched. This also applies to the individual values of multi-valued bindings.

For instance, below is the Polyglot Hello World example using JSP/JSTL as the presentation layer. This example is not included in the distribution because of its external dependencies on the JSTL libraries.

        
;; file: hello.scm
(require-library 'siscweb/forward)

(module examples/hello-world
  (hello-world)

  (import siscweb/forward)

  (define messages '("Hello, world!" "Salve, mundo!" "Hallo, Welt!" "Salve, mondo!" "Bonjour, monde!" "Hola, mundo!"))

  (define (hello-world req)
    (let loop ()
      (for-each
       (lambda (message)
         (send-forward/suspend "/jsp/hello.jsp" `((message . ,message))))
       messages)
      (loop)))
  )


<%-- File: jsp/hello.jsp
--%><%@ page contentType="text/html" %><%--
--%><%@ page isELIgnored="false" %><%-- just for servlet v2.3 containers
--%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><%--
--%><%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml"%><%--
--%><%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%><%--
--%><%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql"%><%--
--%><%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%><%--
--%><?xml version="1.0"?>

<!DOCTYPE html
     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title><c:out value="${requestScope.message}"/></title>

    <c:url var="cssUrl" value="/css/default.css"/>
    <link href="${cssUrl}"
          rel="stylesheet"
          type="text/css"/>
  </head>

  <body>
      <h3>Polyglot hello world</h3>
      <p>${requestScope.message}</p>

    <p><a href="${requestScope["siscweb.kURL"]}">Next language &gt;</a></p>
    <p><a href="${requestScope["siscweb.kURL"]}" target="_blank">Next language in new window</a></p>
    <c:url var="homeUrl" value="/"/>
    <p><a href="${homeUrl}">^ Home</a></p>
  </body>
</html>
        
      

At the lower level, bindings are looked up in the request scope first (i.e. from request attributes) and then from request parameters. This behavior allows a more natural integration with standard J2EE components such as JSPs, but can be unsafe during forwards.

Specifically, if the application performs a server-side forward to Scheme code that relies on the absence of a binding to determine a course of action, a malicious user can inject a parameter by the same name into the request (provided they can guess the name), and upset the application's behavior. The best options in this case are: