Hi,

> > Since all the building bricks already exist in Cocoon, I wonder if 
> > this has been done already. There must be an even simpler solution, 
> > but I could not figure it. Any hints would be welcome.
> 
> I'm not aware of a usage of that source (factory) in Cocoon. 
> But there is a proxy block which might help you. From a short 
> look the generators use HttpClient directly, not that source. 
> I don't know if and how they handle request headers. How do 
> you plan to get the map filled with the actual request 
> headers? Are they configurable?

here's how it works: Any component should go through the SourceResolver
when, well, resolving source URIs. The source resolver is configurable via
the <source-factories> tag in cocoon.xconf. Given my custom resolver, here
is the relevant entry:

  <source-factories>
    <!-- rhttp: is an alias for http: which allows to set arbitrary request
         headers via parameters in the query string with the prefix
"request:".
         Any parameter with this prefix in its name is removed from the
         resulting URI and the remaining name and value are set as request
         headers in the GET request. E.g.
 
"rhttp://www.destination.com/?name=value&request:referer=http://www.origin.c
om/"
         resolves to "http://www.destination.com/?name=value"; where the GET
         request has the "referer" parameter set to
"http://www.origin.com/";.
      -->
    <component-instance
class="com.acme.source.RequestHTTPClientSourceFactory" name="rhttp"/>
    <!-- ... -->
  </source-factories>

The relevant source code in the class is really simple:

public class RequestHTTPClientSourceFactory
        extends HTTPClientSourceFactory {

    /* ... */

    public Source getSource(String uri, Map params)
    throws MalformedURLException, IOException {
        if (params == null)
            params = new HashMap();
        
        builder.setURI(uri); // URIBuilder
        builder.setScheme("http"); // replace custom scheme (e.g. "rhttp")
        for (String name : builder.getParameterNames()) {
            if (!name.startsWith(PARAMETER_PREFIX))
                continue;
            Collection<String> values = builder.getParameterValues(name);
            name = name.substring(PARAMETER_PREFIX.length());
            for (String value : values)
                params.put(name, value);
            values.clear(); // remove all parameter name=value pairs for the
current name
        }
        uri = builder.toString(); // retrieve updated URI

        return super.getSource(uri, params);
    }
}

The tricky part is the URIBuilder class, which provides synchronized views
for parameter name=value pairs and their components in the query string, but
that's a different story.

The benefit of this approach is that it works everwhere in the site map. I
use it with the nekohtml generator to parse data from another web site for a
mashup.

Kind regards,
Christian


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to