You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cocoon.apache.org by Andre Juffer <aj...@sun3.oulu.fi> on 2010/09/18 19:52:18 UTC

RESTful applications

Hi,

I am building a RESTful application with cocoon 2.2. I need to be able 
to identify the request method. It appears that in the sitemap, 
{request:method}, or in flow, cocoon.request.getMethod(), the HTTP 
method value always is GET. I need to be able to distinguish between 
GET, PUT, OPTIONS, etc in order to handle the request accordingly. If 
the method value is always GET, then I won't be able to do so. I've 
tested this all with a tool called RESTClient from WizTools at 
http://rest-client.googlecode.com/.

Could one of you (not) confirm my observation? What to do if indeed the 
request method is always set to GET?

Thanks,
-- 
Andre H. Juffer              | Phone: +358-8-553 1161
Biocenter Oulu and           | Fax: +358-8-553-1141
Department of Biochemistry   | Email: andre.juffer@oulu.fi
University of Oulu, Finland  | WWW: www.biochem.oulu.fi/Biocomputing/
StruBioCat                   | WWW: www.strubiocat.oulu.fi
NordProt                     | WWW: www.nordprot.org
Triacle Biocomputing         | WWW: www.triacle-bc.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org


Re: RESTful applications

Posted by Andre Juffer <an...@oulu.fi>.
On 09/20/2010 11:38 PM, Christopher Schultz wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Andre,
>
> On 9/20/2010 3:06 PM, Andre Juffer wrote:
>    
>> The source of my problem is therefore clear.
>>      
> Absolutely.
>    

I've checked Tomcat 7.0.2. Same issue, as expected.

With jetty 7.1.6, I'll get an exception:

2010-09-20 22:32:49.362:WARN::Failed startup of context 
WebAppContext@55eb1db2@55eb1db2/eap,[file:/tmp/Jetty_0_0_0_0_8080_eap.war__eap__hlptaf/webinf/, 
jar:f
ile:/home/juffer/jetty-distribution-7.1.6.v20100715/webapps/eap.war!/],/home/juffer/jetty-distribution-7.1.6.v20100715/webapps/eap.war
org.springframework.beans.factory.BeanCreationException: Error creating 
bean with name 'org.apache.cocoon.Processor': Initialization of bean 
failed; nested e
xception is org.springframework.beans.factory.BeanCreationException: 
Unable to initialize Avalon component with role 
org.apache.cocoon.Processor; nested exce
ption is 
org.apache.avalon.framework.configuration.ConfigurationException: Cannot 
resolve context://sitemap.xmap

This is probably just a configuration issue as jetty 6 works fine with 
my application. So, I cannot confirm that jetty 7 actually parses a PUT 
request for making parameters available through getParameter(). Jetty 6 
does not seem to do this either as I get exactly the same result as with 
Tomcat 6 and 7. But all of this could as well be caused by cocoon internals.


>    
>> PUT and POST have somewhat different meanings to RESTful applications
>> and I intend to stick to that. On the tomcat list, it was indeed also
>> suggested to change a PUT request into a POST request using a Filter. I
>> prefer to keep things compatible with standards and specifications.
>>      
> So, does that mean that you'd be more amenable to switching from PUT to
> POST, or are you interested in getting PUT to work in one way or another?
>    
> Note that adding a Filter to make PUT work for you doesn't violate any
> standards at all: it implements behavior your application requires. The
> only thing you could say is that is does something /other/ than what the
> servlet specification requires. Also note that parsing PUT bodies does
> not violate the servlet spec: it's simply not required by it, and
> therefore Tomcat doesn't implement it.

> Based upon this thread and the others you've probably read, I've filed
>    

> an enhancement request against Tomcat:
>
> https://issues.apache.org/bugzilla/show_bug.cgi?id=49964
>
> Feel free to comment on this bug if you'd like.
>    
Great!

I would not like to convert a PUT into a POST request. This would 
obscure the meaning of and differences between PUT and POST in context 
of RESTful applications. My opinion is that in the case of a PUT 
request, the servlet should simply pars the request and make the 
parameters available through the getParameters() family. As you said, 
this does not violate any specification. Therefore, I am in full support 
of this feature request (no sure whether you should call this a bug).

For now, I will assume a POST instead of a PUT request and decide inside 
equipmentHandler() what to do. This keeps maintenance of the code 
simple. I will make some modifications this evening to see how this is 
going. But if the request method is still GET, then this would not solve 
anything.
>    
>> [The DefaultServlet has a] readonly parameter in web.xml to change this behavior,
>> but indeed this would not have any impact since the request is handled
>> by my cocoon2.2-based servlet.
>>      
> Exactly: DefaultServlet was written to implement PUT as specified in the
> HTTP specification, and knows nothing about your REST stuff.
>
>    
>>> All Tomcat versions should behave this way, as the servlet specification
>>> has been (relatively) consistent across the versions covered by Tomcat
>>> implementations.
>>>        
>> Yes, I got to the same conclusion, again from the Tomcat list. That list
>> was in fact extremely helpful to understand what is going on.
>>      
> Good. We try to be helpful :)
>    

Thanks!
>    
>> I use the sitemap that was generated during block creation with Maven,
>> as documented on the cocoon website.
>>
>> [snip]
>>
>> The pipeline that handles the request is really extremely simple:
>>
>> <map:match pattern="*">
>>    <map:call function="equipmentHandler">
>>      <map:parameter name="method" value="{request:method}" />
>>    </map:call>
>> </map:match>
>>      
> Hmm... I've never worked with functions as you have above, but I
> definitely use the "request" matcher. Here's what I have in one of my
> pipelines, and it definitely works when nested inside<map:transform>:
>    

You don't have to. My function is communicating among other with a 
database to get things done. But in certain cases, one can also 
accomplish this with XSLT stylesheets. Javascript (or actually 
Flowscrip) is very convenient to handle client requests and making the 
right call to the domain layer.

>   <map:parameter name="requestScheme" value="{request:scheme}" />
>   <map:parameter name="requestServerName" value="{request:serverName}" />
>   <map:parameter name="requestServerPort" value="{request:serverPort}" />
>
> It's possible that whatever<map:call>  does isn't a real request and is
> always modeled as a GET. Someone much more familiar with Cocoon will
> have to comment on this.
>    

Which version of cocoon are you using? Could you test the value of 
request:method for a PUT request (in fact for any other request than GET)?

>    
>> The equipmentHandler() function is basically implemented as (stripped
>> version)
>>
>> function equipmentHandler()
>> {
>>      var request = cocoon.request;
>>      
> Is cocoon.request how you get information from Cocoon? If you can get
> the request from "cocoon.request", then why do you need the "method"
> parameter to your function call? Why not just do "cocoon.request.method"
> or "request.getMethod()"?
>    

That's right. I actually do not need the map:parameter line of code, as 
I can directly access parameters with 
cocoon.request.getParameter("..."). Using map:parameter copies the value 
of request:method into cocoon.parameters.method, which I subsequently 
can access in equipmentHandler(). I just wanted to check the value of 
request:method in the sitemap to see if the call to equipmentHandler() 
was causing the problem of not having anymore the correct request method 
and parameters in that function.

> Something doesn't seem right, here, though I'll admit that I know
> absolutely nothing about how to use Javascript functions inside Cocoon.
> Just make sure you are using the right syntax to get your function
> parameter from the Cocoon pipeline, or that you are using the right
> syntax to grab the request method from the request. It's also possible
> that the implementation of<map:call>  does something that makes
> everything look like GET, as I theorized above.
>    

I think I can safely say that the request method is already incorrect 
before the call is made to equipmentHandler(). Thus, my conclusion is 
that there is a some bug or communication problem between cocoon and the 
actual request. That is, cocoon is possibly 'changing' the actual 
request, or creates a new requests, losing somewhere the actual request 
method value. This would very frustrating if this indeed would be the 
case, rendering the current version of cocoon virtually useless for use 
in RESTful web applications applications. I would not like to switch to 
official RESTful tools like RESTlet and so forth. They seem more 
complicated from my vantage point.

>    
>> The code is pretty much standard and as far as I can see is not
>> interfering at all with the actual request. The only thing that is not
>> yet clear to me why the request method is always GET. I am wondering now
>> if Jetty or Tomcat are converting a PUT request simply into a GET request.
>>      
> Tomcat certainly doesn't do such a thing, and I'd be surprised if Jetty
> does it. But, Cocoon might be doing it.
>    

Yeah, it did not seem logical to me either. As indicated above, more 
likely cocoon is somehow interfering with the request. I can clearly see 
from the log files of Tomcat 6 (7) and Jetty 6 that the servlets receive 
the request as a PUT request. Any alteration of the request is committed 
by cocoon, before the request reaches the sitemap. I will dig into the 
code, if possible, if this is really the case.

I wish that somebody of the cocoon community would comment on this 
thread and hopefully correct me in this matter.

Thanks,
André.

> - -chris
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.10 (MingW32)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
>
> iEYEARECAAYFAkyXxk8ACgkQ9CaO5/Lv0PCoYACdFU3QSyAv7DIgru4agBY5kKbP
> TD8AnR98/mgxelI3Hzt2Jg4tVMYepebi
> =XBsh
> -----END PGP SIGNATURE-----
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
> For additional commands, e-mail: users-help@cocoon.apache.org
>
>    


-- 
Andre H. Juffer              | Phone: +358-8-553 1161
Biocenter Oulu and           | Fax: +358-8-553-1141
Department of Biochemistry   | Email: andre.juffer@oulu.fi
University of Oulu, Finland  | WWW: www.biochem.oulu.fi/Biocomputing/
StruBioCat                   | WWW: www.strubiocat.oulu.fi
NordProt                     | WWW: www.nordprot.org
Triacle Biocomputing         | WWW: www.triacle-bc.com


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org


Re: RESTful applications

Posted by Andre Juffer <aj...@sun3.oulu.fi>.
On 09/21/2010 07:41 PM, Christopher Schultz wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Andre,
>
> On 9/21/2010 6:22 AM, Andre Juffer wrote:
>> I found this (for Tomcat 5)
>>
>> http://webcache.googleusercontent.com/search?q=cache:lJ-4J6f0GPQJ:old.nabble.com/How-to-configure-Toncat-to-accept-HTTP-PUT-requests--td18652489.html+%22HTTP+PUT%22+Tomcat&hl=en&strip=1
>>
>> Seems to indicate that one can apply this to the individual wepapps
>> as well.
>
> Correct: you can configure the DefaultServlet specifically for an
> individual webapp if you choose. Otherwise, you inherit the "global"
> configuration that gets applied to all webapps.
>
>> I thought that the readOnly configuration parameter could be employed
>> only for the default webapp (DefaultServlet).
>
> I think you're confusing webapps (represented by a ServletContext
> object) with servlets, of which the DefaultServlet is one. Each webapp
> gets a copy of a DefaultServlet deployed into it to handle requests not
> otherwise mapped.

OK, got it. Thanks for pointing this out. I learn these things on the 
fly and get sometimes the terminology wrong.

>
> - -chris
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.10 (MingW32)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
>
> iEYEARECAAYFAkyY4FAACgkQ9CaO5/Lv0PCv/gCfaO/R2awXV7MXwq7vRkzsrrpU
> 4FcAniEuYEh92U/XXGFbB7JStJfY++JO
> =Mori
> -----END PGP SIGNATURE-----
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
> For additional commands, e-mail: users-help@cocoon.apache.org
>


-- 
Andre H. Juffer              | Phone: +358-8-553 1161
Biocenter Oulu and           | Fax: +358-8-553-1141
Department of Biochemistry   | Email: andre.juffer@oulu.fi
University of Oulu, Finland  | WWW: www.biochem.oulu.fi/Biocomputing/
StruBioCat                   | WWW: www.strubiocat.oulu.fi
NordProt                     | WWW: www.nordprot.org
Triacle Biocomputing         | WWW: www.triacle-bc.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org


Re: RESTful applications

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Andre,

On 9/21/2010 6:22 AM, Andre Juffer wrote:
> I found this (for Tomcat 5)
> 
> http://webcache.googleusercontent.com/search?q=cache:lJ-4J6f0GPQJ:old.nabble.com/How-to-configure-Toncat-to-accept-HTTP-PUT-requests--td18652489.html+%22HTTP+PUT%22+Tomcat&hl=en&strip=1
>
> Seems to indicate that one can apply this to the individual wepapps
> as well.

Correct: you can configure the DefaultServlet specifically for an
individual webapp if you choose. Otherwise, you inherit the "global"
configuration that gets applied to all webapps.

> I thought that the readOnly configuration parameter could be employed
> only for the default webapp (DefaultServlet).

I think you're confusing webapps (represented by a ServletContext
object) with servlets, of which the DefaultServlet is one. Each webapp
gets a copy of a DefaultServlet deployed into it to handle requests not
otherwise mapped.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkyY4FAACgkQ9CaO5/Lv0PCv/gCfaO/R2awXV7MXwq7vRkzsrrpU
4FcAniEuYEh92U/XXGFbB7JStJfY++JO
=Mori
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org


Re: RESTful applications

Posted by Andre Juffer <an...@oulu.fi>.
Christopher,

On 09/20/2010 11:38 PM, Christopher Schultz wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>    
>
>> [The DefaultServlet has a] readonly parameter in web.xml to change this behavior,
>> but indeed this would not have any impact since the request is handled
>> by my cocoon2.2-based servlet.
>>      
> Exactly: DefaultServlet was written to implement PUT as specified in the
> HTTP specification, and knows nothing about your REST stuff.
>    

I found this (for Tomcat 5)

http://webcache.googleusercontent.com/search?q=cache:lJ-4J6f0GPQJ:old.nabble.com/How-to-configure-Toncat-to-accept-HTTP-PUT-requests--td18652489.html+%22HTTP+PUT%22+Tomcat&hl=en&strip=1

Seems to indicate that one can apply this to the individual wepapps as 
well. I thought that the readOnly configuration parameter could be 
employed only for the default webapp (DefaultServlet).

-- 
Andre H. Juffer              | Phone: +358-8-553 1161
Biocenter Oulu and           | Fax: +358-8-553-1141
Department of Biochemistry   | Email: andre.juffer@oulu.fi
University of Oulu, Finland  | WWW: www.biochem.oulu.fi/Biocomputing/
StruBioCat                   | WWW: www.strubiocat.oulu.fi
NordProt                     | WWW: www.nordprot.org
Triacle Biocomputing         | WWW: www.triacle-bc.com


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org


Re: RESTful applications

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Andre,

On 9/20/2010 3:06 PM, Andre Juffer wrote:
> The source of my problem is therefore clear.

Absolutely.

> PUT and POST have somewhat different meanings to RESTful applications
> and I intend to stick to that. On the tomcat list, it was indeed also
> suggested to change a PUT request into a POST request using a Filter. I
> prefer to keep things compatible with standards and specifications.

So, does that mean that you'd be more amenable to switching from PUT to
POST, or are you interested in getting PUT to work in one way or another?

Note that adding a Filter to make PUT work for you doesn't violate any
standards at all: it implements behavior your application requires. The
only thing you could say is that is does something /other/ than what the
servlet specification requires. Also note that parsing PUT bodies does
not violate the servlet spec: it's simply not required by it, and
therefore Tomcat doesn't implement it.

Based upon this thread and the others you've probably read, I've filed
an enhancement request against Tomcat:

https://issues.apache.org/bugzilla/show_bug.cgi?id=49964

Feel free to comment on this bug if you'd like.

> [The DefaultServlet has a] readonly parameter in web.xml to change this behavior,
> but indeed this would not have any impact since the request is handled
> by my cocoon2.2-based servlet.

Exactly: DefaultServlet was written to implement PUT as specified in the
HTTP specification, and knows nothing about your REST stuff.

>> All Tomcat versions should behave this way, as the servlet specification
>> has been (relatively) consistent across the versions covered by Tomcat
>> implementations.
> 
> Yes, I got to the same conclusion, again from the Tomcat list. That list
> was in fact extremely helpful to understand what is going on.

Good. We try to be helpful :)

> I use the sitemap that was generated during block creation with Maven,
> as documented on the cocoon website.
>
> [snip]
> 
> The pipeline that handles the request is really extremely simple:
> 
> <map:match pattern="*">
>   <map:call function="equipmentHandler">
>     <map:parameter name="method" value="{request:method}" />
>   </map:call>
> </map:match>

Hmm... I've never worked with functions as you have above, but I
definitely use the "request" matcher. Here's what I have in one of my
pipelines, and it definitely works when nested inside <map:transform>:

 <map:parameter name="requestScheme" value="{request:scheme}" />
 <map:parameter name="requestServerName" value="{request:serverName}" />
 <map:parameter name="requestServerPort" value="{request:serverPort}" />

It's possible that whatever <map:call> does isn't a real request and is
always modeled as a GET. Someone much more familiar with Cocoon will
have to comment on this.

> The equipmentHandler() function is basically implemented as (stripped
> version)
> 
> function equipmentHandler()
> {
>     var request = cocoon.request;

Is cocoon.request how you get information from Cocoon? If you can get
the request from "cocoon.request", then why do you need the "method"
parameter to your function call? Why not just do "cocoon.request.method"
or "request.getMethod()"?

Something doesn't seem right, here, though I'll admit that I know
absolutely nothing about how to use Javascript functions inside Cocoon.
Just make sure you are using the right syntax to get your function
parameter from the Cocoon pipeline, or that you are using the right
syntax to grab the request method from the request. It's also possible
that the implementation of <map:call> does something that makes
everything look like GET, as I theorized above.

> The code is pretty much standard and as far as I can see is not
> interfering at all with the actual request. The only thing that is not
> yet clear to me why the request method is always GET. I am wondering now
> if Jetty or Tomcat are converting a PUT request simply into a GET request.

Tomcat certainly doesn't do such a thing, and I'd be surprised if Jetty
does it. But, Cocoon might be doing it.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkyXxk8ACgkQ9CaO5/Lv0PCoYACdFU3QSyAv7DIgru4agBY5kKbP
TD8AnR98/mgxelI3Hzt2Jg4tVMYepebi
=XBsh
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org


Re: RESTful applications

Posted by Andre Juffer <aj...@sun3.oulu.fi>.
On 09/20/2010 08:25 PM, Christopher Schultz wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Andre,
>
> On 9/20/2010 6:34 AM, Andre Juffer wrote:
>> Could it be true that Jetty (the one that comes with cocoon is 6.1.7, a
>> rather old one) is actually not supporting the getParameters() family
>> of methods when the HTTP request method is PUT?
>
> This almost certainly the case: the servlet specification only requires
> that getParameter handle request-body data under certain conditions.
> - From the 2.5 version of the spec, section SRV.3.1.1:
>
> "
> The following are the conditions that must be met before post form data
> will
> be populated to the parameter set:
> 1. The request is an HTTP or HTTPS request.
> 2. The HTTP method is POST.
> 3. The content type is application/x-www-form-urlencoded.
> 4. The servlet has made an initial call of any of the getParameter
> family of methods on the request object.
> "
>
> So, when you use PUT, you don't get parameters in the usual way: you'll
> have to parse them yourself in some way.

Yes, this is exactly right. The discussion you refer to is the one that 
I also have read. The source of my problem is therefore clear.

>
> You might want to refer to this thread on the Tomcat-User mailing list
> for an extended discussion: http://markmail.org/thread/kinlccrweiaesqoh
>
> Note that parameters placed into the URL are always available via
> request.getParameter*

Also correct. I've experimented with this already.

>
> There are several ways you could get your server to extract request-body
> PUT parameters and make them available via the getParameter* family of
> methods. One such way (which would avoid having to do anything nasty
> within Cocoon itself) would be to write a request Filter that overrides
> getParameter* and parses a request body if it is a PUT request.
>
> I have philosophical issues against doing such a thing because I feel
> that PUT was designed to put a copy of the entire request body into the
> URL used to access it, not to pass some complex set of "parameters" in
> the body itself to do something else. But, that's not really for me to
> decide on your behalf: if you want POST behavior from PUT, you'll likely
> have to code it yourself in some way. I can give you some suggestions if
> you would like to take this route.

PUT and POST have somewhat different meanings to RESTful applications 
and I intend to stick to that. On the tomcat list, it was indeed also 
suggested to change a PUT request into a POST request using a Filter. I 
prefer to keep things compatible with standards and specifications.

>
>> I came across some comments that Tomcat (did not mention which version
>> of Tomcat) is also not supporting the getParameters() famility of
>> methods [1]. Tomcat can actually handle PUT, POST etc requests, but
>> blocks them by default [2].
>>
>> Anyone can confirm this?
>
> I can: Tomcat's DefaultServlet (the servlet that responds to all request
> that aren't otherwise handled by other servlets) rejects PUT (and POST)
> requests, but you don't want the DefaultServlet to accept them anyway:
> you want your REST-processing code to handle them. Tomcat will not
> interfere with any servlet that expects to accept a PUT request.

The is indeed the readonly parameter in web.xml to change this behavior, 
but indeed this would not have any impact since the request is handled 
by my cocoon2.2-based servlet.
>
> All Tomcat versions should behave this way, as the servlet specification
> has been (relatively) consistent across the versions covered by Tomcat
> implementations.

Yes, I got to the same conclusion, again from the Tomcat list. That list 
was in fact extremely helpful to understand what is going on.

>
> Your first problem, though, was that request.getMethod was always
> returning "GET" even when the method should be "PUT", right?

Correct.

>
> Can you show us how you have configured your pipepine (including how you
> extract the "method" from the request) and also how you are declaring
> and then using the method in your XSLT?

I use the sitemap that was generated during block creation with Maven, 
as documented on the cocoon website. I've added the following:

<map:serializers>
   <map:serializer name="json" mime-type="application/json; 
charset=UTF-8" src="org.apache.cocoon.serialization.TextSerializer">
     <encoding>UTF-8</encoding>
   </map:serializer>
   <map:serializer name="xml" mime-type="text/xml"
                   src="org.apache.cocoon.serialization.XMLSerializer">
     <encoding>UTF-8</encoding>
   </map:serializer>
</map:serializers>

The pipeline that handles the request is really extremely simple:

<map:match pattern="*">
   <map:call function="equipmentHandler">
     <map:parameter name="method" value="{request:method}" />
   </map:call>
</map:match>

So, all requests are forwarded to a single function (for now). The 
map:parameter is just there to test the value of the request method, as 
I did not get the expected response. I actually do not use it in any 
XSLT. I will remove this line as soon as I get the right request method 
value in the equipmentHandler() function.

The equipmentHandler() function is basically implemented as (stripped 
version)

function equipmentHandler()
{
     var request = cocoon.request;
     var method = request.getMethod();
     // var method = cocoon.parameters.method;
     if ( method == "GET" )
     {
       var id = ....  // From request.
       // get equipment from database.
       var equipment = ...;
     } else if (method == "PUT")
     {
       // Extract all parameters like:
       var name = request.getParameter("name");
       ...
       // Store in database.
       equipment = ...
     } else
	// Illegal request.
     ...
     // Create response.
     var format = request.getParameter("format");  // Only JSON or XML.
     var response = cocoon.response;
     response.setStatus(...);
     cocoon.sendPage("equipments." + format,
     {
       "equipment" : equipment
     });
}

This function communicates with a Facade to manage equipment resources 
stored in a postgres database. Equipment is returned as DTO objects, 
which that is/are then converted to XML or JSON. This all works without 
any problem, except of course that the request method is always GET 
instead PUT or some other value.

The code is pretty much standard and as far as I can see is not 
interfering at all with the actual request. The only thing that is not 
yet clear to me why the request method is always GET. I am wondering now 
if Jetty or Tomcat are converting a PUT request simply into a GET request.

>
> - -chris
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.10 (MingW32)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
>
> iEYEARECAAYFAkyXmPgACgkQ9CaO5/Lv0PD58ACguAHmp+VXpHeSwCHmdjGDz/95
> 4FwAoLkyYpHW3gxn0alEdEeNEtjYyFEz
> =j9hU
> -----END PGP SIGNATURE-----
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
> For additional commands, e-mail: users-help@cocoon.apache.org
>


-- 
Andre H. Juffer              | Phone: +358-8-553 1161
Biocenter Oulu and           | Fax: +358-8-553-1141
Department of Biochemistry   | Email: andre.juffer@oulu.fi
University of Oulu, Finland  | WWW: www.biochem.oulu.fi/Biocomputing/
StruBioCat                   | WWW: www.strubiocat.oulu.fi
NordProt                     | WWW: www.nordprot.org
Triacle Biocomputing         | WWW: www.triacle-bc.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org


Re: RESTful applications

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Andre,

On 9/20/2010 6:34 AM, Andre Juffer wrote:
> Could it be true that Jetty (the one that comes with cocoon is 6.1.7, a
> rather old one) is actually not supporting the getParameters() family
> of methods when the HTTP request method is PUT?

This almost certainly the case: the servlet specification only requires
that getParameter handle request-body data under certain conditions.
- From the 2.5 version of the spec, section SRV.3.1.1:

"
The following are the conditions that must be met before post form data
will
be populated to the parameter set:
1. The request is an HTTP or HTTPS request.
2. The HTTP method is POST.
3. The content type is application/x-www-form-urlencoded.
4. The servlet has made an initial call of any of the getParameter
family of methods on the request object.
"

So, when you use PUT, you don't get parameters in the usual way: you'll
have to parse them yourself in some way.

You might want to refer to this thread on the Tomcat-User mailing list
for an extended discussion: http://markmail.org/thread/kinlccrweiaesqoh

Note that parameters placed into the URL are always available via
request.getParameter*

There are several ways you could get your server to extract request-body
PUT parameters and make them available via the getParameter* family of
methods. One such way (which would avoid having to do anything nasty
within Cocoon itself) would be to write a request Filter that overrides
getParameter* and parses a request body if it is a PUT request.

I have philosophical issues against doing such a thing because I feel
that PUT was designed to put a copy of the entire request body into the
URL used to access it, not to pass some complex set of "parameters" in
the body itself to do something else. But, that's not really for me to
decide on your behalf: if you want POST behavior from PUT, you'll likely
have to code it yourself in some way. I can give you some suggestions if
you would like to take this route.

> I came across some comments that Tomcat (did not mention which version
> of Tomcat) is also not supporting the getParameters() famility of
> methods [1]. Tomcat can actually handle PUT, POST etc requests, but
> blocks them by default [2].
> 
> Anyone can confirm this?

I can: Tomcat's DefaultServlet (the servlet that responds to all request
that aren't otherwise handled by other servlets) rejects PUT (and POST)
requests, but you don't want the DefaultServlet to accept them anyway:
you want your REST-processing code to handle them. Tomcat will not
interfere with any servlet that expects to accept a PUT request.

All Tomcat versions should behave this way, as the servlet specification
has been (relatively) consistent across the versions covered by Tomcat
implementations.

Your first problem, though, was that request.getMethod was always
returning "GET" even when the method should be "PUT", right?

Can you show us how you have configured your pipepine (including how you
extract the "method" from the request) and also how you are declaring
and then using the method in your XSLT?

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkyXmPgACgkQ9CaO5/Lv0PD58ACguAHmp+VXpHeSwCHmdjGDz/95
4FwAoLkyYpHW3gxn0alEdEeNEtjYyFEz
=j9hU
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org


Re: RESTful applications

Posted by Andre Juffer <an...@oulu.fi>.
Just a another follow up.

It appears that the whole issue is indeed caused by the servlet engine. 
According to the sevlet specification, a PUT request will not necessary 
be parsed for extracting request parameters to make them available 
through the getParameters() family of methods. It is actually up to the 
servlet engine whether or not it will do so. In contract, a POST request 
should (if certain conditions are met). For a PUT request, it seems that 
Tomcat 6 is -not- parsing the request for extracting parameters [1], 
while I found some vague statements that Jetty (version unclear) will 
extract the parameters even for a PUT request. I will try to confirm 
this all later today.

I would appreciate some response in this matter...

[1] http://marc.info/?l=tomcat-user&m=127005757912988&w=2


On 09/20/2010 01:34 PM, Andre Juffer wrote:
> Could it be true that Jetty (the one that comes with cocoon is 6.1.7, 
> a rather old one) is actually not supporting the getParameters() 
> famility of methods when the HTTP request method is PUT? It just 
> supports GET and HEAD (is required to support these methods). If so, 
> the problem is Jetty, not cocoon.
>
> I came across some comments that Tomcat (did not mention which version 
> of Tomcat) is also not supporting the getParameters() famility of 
> methods [1]. Tomcat can actually handle PUT, POST etc requests, but 
> blocks them by default [2].
>
> Anyone can confirm this?
>
> [1] http://osdir.com/ml/users-tomcat.apache.org/2010-03/msg01410.html
> [2] http://marc.info/?l=tomcat-user&m=127382305322732&w=2
>
> On 09/19/2010 05:42 PM, Andre Juffer wrote:
>> Let me just add some additional information.
>>
>> I use Dojo 1.5 (www.dojotoolkit.org) on the client (browser). No dojo 
>> on the server. I've created a few blocks (one of them is called 
>> 'equipment' and another one is called 'webapp') according to the 
>> cocoon 2.2 documentation. No extra configuration was done. I do not 
>> use CForms at all.
>>
>> At some point, on the client (firefox) a form is processed that 
>> results in a HTTP PUT request. The request is assembled with 
>> dojo.xhrPut(), a Dojo function. With Firebug 1.5.4, I see that the 
>> following request is submitted (cut and pasted from the Firebug 
>> console):
>>
>> PUT http://localhost:8888/equipment
>>
>> Parameters (application/x-www-form-urlencoded)
>>
>> category    Test
>> description    Testing purposes
>> manufacturer    Tester Ltd.
>> name            Test
>> ownerId            3375104
>> task            Testing
>>
>> So far, so good. There is nothing special about this request. Jetty 
>> receives the request (jetty was started with mvn jetty:run from the 
>> webapp block).
>>
>> The sitemap in the equipment block contains:
>>
>> <map:match pattern="*">
>> <map:call function="equipmentHandler">
>> </map:match>
>>
>> So, all requests are handled by the function 'equipmentHandler()' 
>> (for now at least). This function subsequently calls upon 
>> cocoon.request.getMethod() to find out what the HTTP request method 
>> is and proceeds accordingly. The cocoon.request.getMethod() always 
>> returns GET. I tested this with 
>> java.lang.System.out.println(cocoon.request.getMethod()). As a matter 
>> of fact, none of the parameters listed above ever reach the 
>> equipmentHandler() function. Each cocoon.request.getParameter(..) 
>> calls returns null.
>>
>> Could this be an encoding issue? I went through 
>> http://cocoon.apache.org/2.2/1366_1_1.html.
>>
>> Thanks for your help,
>> André
>>
>>
>> On 09/18/2010 08:52 PM, Andre Juffer wrote:
>>> Hi,
>>>
>>> I am building a RESTful application with cocoon 2.2. I need to be able
>>> to identify the request method. It appears that in the sitemap,
>>> {request:method}, or in flow, cocoon.request.getMethod(), the HTTP
>>> method value always is GET. I need to be able to distinguish between
>>> GET, PUT, OPTIONS, etc in order to handle the request accordingly. If
>>> the method value is always GET, then I won't be able to do so. I've
>>> tested this all with a tool called RESTClient from WizTools at
>>> http://rest-client.googlecode.com/.
>>>
>>> Could one of you (not) confirm my observation? What to do if indeed the
>>> request method is always set to GET?
>>>
>>> Thanks,
>>
>>
>
>


-- 
Andre H. Juffer              | Phone: +358-8-553 1161
Biocenter Oulu and           | Fax: +358-8-553-1141
Department of Biochemistry   | Email: andre.juffer@oulu.fi
University of Oulu, Finland  | WWW: www.biochem.oulu.fi/Biocomputing/
StruBioCat                   | WWW: www.strubiocat.oulu.fi
NordProt                     | WWW: www.nordprot.org
Triacle Biocomputing         | WWW: www.triacle-bc.com


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org


Re: RESTful applications

Posted by Andre Juffer <an...@oulu.fi>.
Could it be true that Jetty (the one that comes with cocoon is 6.1.7, a 
rather old one) is actually not supporting the getParameters() famility 
of methods when the HTTP request method is PUT? It just supports GET and 
HEAD (is required to support these methods). If so, the problem is 
Jetty, not cocoon.

I came across some comments that Tomcat (did not mention which version 
of Tomcat) is also not supporting the getParameters() famility of 
methods [1]. Tomcat can actually handle PUT, POST etc requests, but 
blocks them by default [2].

Anyone can confirm this?

[1] http://osdir.com/ml/users-tomcat.apache.org/2010-03/msg01410.html
[2] http://marc.info/?l=tomcat-user&m=127382305322732&w=2

On 09/19/2010 05:42 PM, Andre Juffer wrote:
> Let me just add some additional information.
>
> I use Dojo 1.5 (www.dojotoolkit.org) on the client (browser). No dojo 
> on the server. I've created a few blocks (one of them is called 
> 'equipment' and another one is called 'webapp') according to the 
> cocoon 2.2 documentation. No extra configuration was done. I do not 
> use CForms at all.
>
> At some point, on the client (firefox) a form is processed that 
> results in a HTTP PUT request. The request is assembled with 
> dojo.xhrPut(), a Dojo function. With Firebug 1.5.4, I see that the 
> following request is submitted (cut and pasted from the Firebug console):
>
> PUT http://localhost:8888/equipment
>
> Parameters (application/x-www-form-urlencoded)
>
> category    Test
> description    Testing purposes
> manufacturer    Tester Ltd.
> name            Test
> ownerId            3375104
> task            Testing
>
> So far, so good. There is nothing special about this request. Jetty 
> receives the request (jetty was started with mvn jetty:run from the 
> webapp block).
>
> The sitemap in the equipment block contains:
>
> <map:match pattern="*">
> <map:call function="equipmentHandler">
> </map:match>
>
> So, all requests are handled by the function 'equipmentHandler()' (for 
> now at least). This function subsequently calls upon 
> cocoon.request.getMethod() to find out what the HTTP request method is 
> and proceeds accordingly. The cocoon.request.getMethod() always 
> returns GET. I tested this with 
> java.lang.System.out.println(cocoon.request.getMethod()). As a matter 
> of fact, none of the parameters listed above ever reach the 
> equipmentHandler() function. Each cocoon.request.getParameter(..) 
> calls returns null.
>
> Could this be an encoding issue? I went through 
> http://cocoon.apache.org/2.2/1366_1_1.html.
>
> Thanks for your help,
> André
>
>
> On 09/18/2010 08:52 PM, Andre Juffer wrote:
>> Hi,
>>
>> I am building a RESTful application with cocoon 2.2. I need to be able
>> to identify the request method. It appears that in the sitemap,
>> {request:method}, or in flow, cocoon.request.getMethod(), the HTTP
>> method value always is GET. I need to be able to distinguish between
>> GET, PUT, OPTIONS, etc in order to handle the request accordingly. If
>> the method value is always GET, then I won't be able to do so. I've
>> tested this all with a tool called RESTClient from WizTools at
>> http://rest-client.googlecode.com/.
>>
>> Could one of you (not) confirm my observation? What to do if indeed the
>> request method is always set to GET?
>>
>> Thanks,
>
>


-- 
Andre H. Juffer              | Phone: +358-8-553 1161
Biocenter Oulu and           | Fax: +358-8-553-1141
Department of Biochemistry   | Email: andre.juffer@oulu.fi
University of Oulu, Finland  | WWW: www.biochem.oulu.fi/Biocomputing/
StruBioCat                   | WWW: www.strubiocat.oulu.fi
NordProt                     | WWW: www.nordprot.org
Triacle Biocomputing         | WWW: www.triacle-bc.com


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org


Re: RESTful applications

Posted by Andre Juffer <aj...@sun3.oulu.fi>.
Let me just add some additional information.

I use Dojo 1.5 (www.dojotoolkit.org) on the client (browser). No dojo on 
the server. I've created a few blocks (one of them is called 'equipment' 
and another one is called 'webapp') according to the cocoon 2.2 
documentation. No extra configuration was done. I do not use CForms at all.

At some point, on the client (firefox) a form is processed that results 
in a HTTP PUT request. The request is assembled with dojo.xhrPut(), a 
Dojo function. With Firebug 1.5.4, I see that the following request is 
submitted (cut and pasted from the Firebug console):

PUT http://localhost:8888/equipment

Parameters (application/x-www-form-urlencoded)

category	Test
description	Testing purposes
manufacturer	Tester Ltd.
name	        Test
ownerId	        3375104
task	        Testing

So far, so good. There is nothing special about this request. Jetty 
receives the request (jetty was started with mvn jetty:run from the 
webapp block).

The sitemap in the equipment block contains:

<map:match pattern="*">
   <map:call function="equipmentHandler">
</map:match>

So, all requests are handled by the function 'equipmentHandler()' (for 
now at least). This function subsequently calls upon 
cocoon.request.getMethod() to find out what the HTTP request method is 
and proceeds accordingly. The cocoon.request.getMethod() always returns 
GET. I tested this with 
java.lang.System.out.println(cocoon.request.getMethod()). As a matter of 
fact, none of the parameters listed above ever reach the 
equipmentHandler() function. Each cocoon.request.getParameter(..) calls 
returns null.

Could this be an encoding issue? I went through 
http://cocoon.apache.org/2.2/1366_1_1.html.

Thanks for your help,
André


On 09/18/2010 08:52 PM, Andre Juffer wrote:
> Hi,
>
> I am building a RESTful application with cocoon 2.2. I need to be able
> to identify the request method. It appears that in the sitemap,
> {request:method}, or in flow, cocoon.request.getMethod(), the HTTP
> method value always is GET. I need to be able to distinguish between
> GET, PUT, OPTIONS, etc in order to handle the request accordingly. If
> the method value is always GET, then I won't be able to do so. I've
> tested this all with a tool called RESTClient from WizTools at
> http://rest-client.googlecode.com/.
>
> Could one of you (not) confirm my observation? What to do if indeed the
> request method is always set to GET?
>
> Thanks,


-- 
Andre H. Juffer              | Phone: +358-8-553 1161
Biocenter Oulu and           | Fax: +358-8-553-1141
Department of Biochemistry   | Email: andre.juffer@oulu.fi
University of Oulu, Finland  | WWW: www.biochem.oulu.fi/Biocomputing/
StruBioCat                   | WWW: www.strubiocat.oulu.fi
NordProt                     | WWW: www.nordprot.org
Triacle Biocomputing         | WWW: www.triacle-bc.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org