atom feed16 messages in net.java.dev.jersey.usersRe: [Jersey] modifying jersey client ...
FromSent OnAttachments
Zoltan Arnold NAGYOct 7, 2009 8:05 am 
Felipe GauchoOct 7, 2009 8:36 am 
Paul SandozOct 7, 2009 8:46 am 
Zoltan Arnold NAGYOct 8, 2009 1:34 pm 
Craig McClanahanOct 8, 2009 2:55 pm 
Zoltan Arnold NAGYOct 9, 2009 1:13 am 
Paul SandozOct 9, 2009 1:18 am 
Zoltan Arnold NAGYOct 9, 2009 1:27 am 
Paul SandozOct 9, 2009 1:40 am 
Zoltan Arnold NAGYOct 13, 2009 7:30 am 
Paul SandozOct 13, 2009 10:52 am 
Zoltan Arnold NAGYOct 13, 2009 2:08 pm 
Paul SandozOct 14, 2009 1:58 am 
Zoltan Arnold NAGYOct 14, 2009 5:37 am 
Paul SandozOct 14, 2009 5:46 am 
Zoltan Arnold NAGYOct 14, 2009 5:55 am 
Subject:Re: [Jersey] modifying jersey client requests
From:Paul Sandoz (Paul@Sun.COM)
Date:Oct 9, 2009 1:40:05 am
List:net.java.dev.jersey.users

On Oct 9, 2009, at 10:27 AM, Zoltan Arnold NAGY wrote:

Paul Sandoz wrote:

On Oct 9, 2009, at 10:13 AM, Zoltan Arnold NAGY wrote:

Zoltan Arnold NAGY wrote:

On Oct 7, 2009, at 5:36 PM, Felipe Gaucho wrote:

A filter?

Yes, see ClientFilter and the source code for the LoggingFilter (see below because java.net is so damn slow).

You need to return an output stream in the implementation of AbstractClientRequestAdapter .adapt that buffers the bytes then on the close calculates the hash, sets the header and writes out the bytes of the buffered output stream to the actual output stream.

Thanks, it seems to be working. :)

Spoken too soon. In the message to be hashed I need to add the method, the date, and other data as well.

It seems to me that if I do a simple .get() (no entity present) and I do attach an adapter with request.setAdapter(new Adapter(request.getAdapter(), b)); then it's adapt() method wont even get called (at least I've put logging there, and never saw it's output).

In all the examples I've seen one only attaches such an adapter if there's an entity present, so I'm thinking that maybe these request adaptert are only used to modify the entity's serialized form?

Yes, because it is adapting a *request* entity. If there is no request entity present then no adaption will occur because there is nothing to adapt.

Do you want to hash a request entity or a response entity?

It's a bit more complicated than that :)

from Amazon's docs:
(http://docs.amazonwebservices.com/AmazonS3/2006-03-01/dev/index.html?RESTAuthentication.html ):

StringToSign = HTTP-Verb + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedAmzHeaders + CanonicalizedResource;

For example, let's say Jersey would send this request: GET /testresource HTTP/1.1 Content-type: application/json Host: test.something.com

then I'd still need to alter it and calculate the hash from various input fields as seen above, and add the header to it. Of course, if there _is_ an entity, I'd need to include it's serialized (xml/json/whatever) form in the calculations.

Is there a way to catch the output stream before it gets written at all to the server?

Yes, that is what a filter is for, you can modify the request headers.

You just need to work out if there is an entity present or not to decide where the creation of the signed string and header addition occurs. See ClientRequest.getEntity(). If it returns null then adaption will not occur, unless another filter further along in the filter chain adds one (a security filter should really be the last one in the chain).

@Override public ClientResponse handle(ClientRequest request) throws ClientHandlerException { if (request.getEntity() != null) { // Adapt request and do signing with adaption request.setAdapter(new Adapter(request.getAdapter())); } else { // Do signing here } ClientResponse response = getNext().handle(request); return response; }

I agree it is a little inconsistent. Perhaps it would have been better to have start, and finish methods on ClientRequestAdapter which are always called whether an entity is present or not.

Paul.