I have logged an issue (505) for the ClassCastException. Here is the request debug snip from HttpClient, I do see the whitespace, and it may very well be the case here:
2010/04/13 10:54:51:893 MDT [DEBUG] content - >> "Content-Disposition: form-data; name="
2010/04/13 10:54:51:893 MDT [DEBUG] content - >> """
2010/04/13 10:54:51:893 MDT [DEBUG] content - >> "file"
2010/04/13 10:54:51:893 MDT [DEBUG] content - >> """
2010/04/13 10:54:51:893 MDT [DEBUG] content - >> "; filename="
2010/04/13 10:54:51:893 MDT [DEBUG] content - >> """
2010/04/13 10:54:51:893 MDT [DEBUG] content - >> "customer.bin"
2010/04/13 10:54:51:893 MDT [DEBUG] content - >> """
2010/04/13 10:54:51:893 MDT [DEBUG] content - >> "[\r][\n]"
2010/04/13 10:54:51:893 MDT [DEBUG] content - >> "Content-Type: "
2010/04/13 10:54:51:893 MDT [DEBUG] content - >> "application/octet-stream"
2010/04/13 10:54:51:894 MDT [DEBUG] content - >> "; charset="
2010/04/13 10:54:51:894 MDT [DEBUG] content - >> "ISO-8859-1"
2010/04/13 10:54:51:894 MDT [DEBUG] content - >> "[\r][\n]"
2010/04/13 10:54:51:894 MDT [DEBUG] content - >> "Content-Transfer-Encoding: "
2010/04/13 10:54:51:894 MDT [DEBUG] content - >> "binary"
2010/04/13 10:54:51:894 MDT [DEBUG] content - >> "[\r][\n]"
2010/04/13 10:54:51:894 MDT [DEBUG] content - >> "[\r][\n]"
I will try to get access to the server side logs, I am not positive though :-(
Thanks for your help again.
Arul.
On Apr 13, 2010, at 3:08 AM, Paul Sandoz wrote:
> Hi Arul,
>
> There is a silly bug in the multipart module. Can you log an issue.
>
> However, i think this is orthogonal to the problem you are encountering. HTTP headers are case insensitive, and Jersey will anyway re-write the Content-Type header value to include the boundary string parameter that declared the delimitation string between body parts.
>
> My suspicion is the CGI script cannot parse the value of the Content-Type or Content-Disposition headers. But it would help if you could get access to some sort of server-side information.
>
> Developers have reported cases of services consume multipart/form-data being sensitive to white space characters between parameters of media types and content disposition types. Jersey does not use white space.
>
> From Jersey:
>
> Content-Disposition: form-data;name="file"
>
> From Apache HTTP client:
>
> Content-Disposition: form-data; name="file"
>
> Paul.
>
>
> On Apr 12, 2010, at 6:35 PM, Arul Dhesiaseelan wrote:
>
>> Hi Paul,
>>
>> I noticed other thing in the requests, the header is set to "Content-type: multipart/form-data" in case of HttpClient and "Content-Type: multipart/form-data" in case of JerseyClient, note the case change in Type. I am not sure if this is causing any of these problems. I thought of checking this by manually setting the header using the Jersey Client, but I get a ClassCastException when performing the POST in the following code:
>>
>> ClientResponse response = resource.header("Content-type", "multipart/form-data").post(ClientResponse.class, multiPart);
>>
>> Here is the exception trace (I am using version 1.1.5.1):
>>
>> 1 * Out-bound request
>> 1 > POST https://test.com/cgi-bin/submit.cgi
>> 1 > Content-type: multipart/form-data
>> 1 >
>> Exception in thread "main" com.sun.jersey.api.client.ClientHandlerException: java.lang.ClassCastException: java.lang.String
>> at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:128)
>> at com.sun.jersey.api.client.filter.LoggingFilter.handle(LoggingFilter.java:152)
>> at com.sun.jersey.api.client.Client.handle(Client.java:435)
>> at com.sun.jersey.api.client.WebResource.handle(WebResource.java:557)
>> at com.sun.jersey.api.client.WebResource.access$300(WebResource.java:69)
>> at com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:499)
>> at coderyte.flux.poc.JerseyClientTest.main(JerseyClientTest.java:77)
>> Caused by: java.lang.ClassCastException: java.lang.String
>> at com.sun.jersey.multipart.impl.MultiPartWriter.writeTo(MultiPartWriter.java:129)
>> at com.sun.jersey.multipart.impl.MultiPartWriter.writeTo(MultiPartWriter.java:68)
>> at com.sun.jersey.api.client.TerminatingClientHandler.writeRequestEntity(TerminatingClientHandler.java:317)
>> at com.sun.jersey.client.urlconnection.URLConnectionClientHandler._invoke(URLConnectionClientHandler.java:179)
>> at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:126)
>> ... 6 more
>>
>> Any clues?
>>
>> -Arul
>>
>>
>> On Mon, Apr 12, 2010 at 8:00 AM, Arul Dhesiaseelan <aruld.info_at_gmail.com> wrote:
>> Hi Paul,
>>
>> I removed the below line from the Apache HTTP Client code and it still works. So, it looks like auth in not enabled on the CGI script.
>> filePost.setDoAuthentication(true);
>>
>> Unfortunately, I do not have access to the server side.
>>
>> Thanks,
>> Arul
>>
>>
>> On Mon, Apr 12, 2010 at 3:16 AM, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
>> Hi,
>>
>> The odd thing is in your Apache HTTP client code you have not specified any credentials. So are you sure authentication on the CGI script is enabled?
>>
>> Can you send the full HTTP request response exchange when using both clients and any logging information from the CGI script?
>>
>>
>> Paul.
>>
>> On Apr 12, 2010, at 5:12 AM, Arul Dhesiaseelan wrote:
>>
>>> Hi,
>>>
>>> I am trying to use Jersey client to do a multipart form submit to a CGI script. But, the service returns the HTML form instead of the actual response. I have the code which works on Apache HttpClient. I am not sure what I am missing here. Can someone help?
>>>
>>> POST using Apache HttpClient (this code works):
>>>
>>> HttpClient client = new HttpClient();
>>> PostMethod filePost = new PostMethod("https://test.com/cgi-bin/submit.cgi");
>>> filePost.setDoAuthentication(true);//process authentication challenges authomatically
>>> File targetFile = new File("customer.bin");
>>> Part[] parts = { new FilePart("file", targetFile),
>>> new StringPart("user", "username"),
>>> new StringPart("password", "password"),
>>> new StringPart("type", "X32") };
>>> filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams()));
>>> filePost.setRequestHeader("Content-type","multipart/form-data");
>>> int status = client.executeMethod(filePost);
>>>
>>> Log output:
>>>
>>> 2010/04/11 17:20:21:594 MDT [DEBUG] header - >> "POST /cgi-bin/submit.cgi HTTP/1.1[\r][\n]"
>>> 2010/04/11 17:20:21:595 MDT [DEBUG] HttpMethodBase - Adding Host request header
>>> 2010/04/11 17:20:21:620 MDT [DEBUG] header - >> "Content-type: multipart/form-data[\r][\n]"
>>> 2010/04/11 17:20:21:621 MDT [DEBUG] header - >> "User-Agent: Jakarta Commons-HttpClient/3.1[\r][\n]"
>>> 2010/04/11 17:20:21:621 MDT [DEBUG] header - >> "Host: test.com[\r][\n]"
>>> 2010/04/11 17:20:21:621 MDT [DEBUG] header - >> "Content-Length: 117417[\r][\n]"
>>> 2010/04/11 17:20:21:621 MDT [DEBUG] header - >> "[\r][\n]"
>>> 2010/04/11 17:20:21:622 MDT [DEBUG] content - >> "--"
>>> 2010/04/11 17:20:21:622 MDT [DEBUG] content - >> "giTfSy0R4Zrd7j4lruBwymHkrZRJdNLD5kV4zcM"
>>> 2010/04/11 17:20:21:622 MDT [DEBUG] content - >> "[\r][\n]"
>>> 2010/04/11 17:20:21:622 MDT [DEBUG] content - >> "Content-Disposition: form-data; name="
>>> 2010/04/11 17:20:21:623 MDT [DEBUG] content - >> """
>>> 2010/04/11 17:20:21:623 MDT [DEBUG] content - >> "file"
>>> 2010/04/11 17:20:21:623 MDT [DEBUG] content - >> """
>>> 2010/04/11 17:20:21:623 MDT [DEBUG] content - >> "; filename="
>>> 2010/04/11 17:20:21:623 MDT [DEBUG] content - >> """
>>> 2010/04/11 17:20:21:623 MDT [DEBUG] content - >> "customer.bin"
>>> 2010/04/11 17:20:21:623 MDT [DEBUG] content - >> """
>>> 2010/04/11 17:20:21:623 MDT [DEBUG] content - >> "[\r][\n]"
>>> 2010/04/11 17:20:21:623 MDT [DEBUG] content - >> "Content-Type: "
>>> 2010/04/11 17:20:21:623 MDT [DEBUG] content - >> "application/octet-stream"
>>> 2010/04/11 17:20:21:624 MDT [DEBUG] content - >> "; charset="
>>> 2010/04/11 17:20:21:624 MDT [DEBUG] content - >> "ISO-8859-1"
>>> 2010/04/11 17:20:21:624 MDT [DEBUG] content - >> "[\r][\n]"
>>> 2010/04/11 17:20:21:624 MDT [DEBUG] content - >> "Content-Transfer-Encoding: "
>>> 2010/04/11 17:20:21:624 MDT [DEBUG] content - >> "binary"
>>> 2010/04/11 17:20:21:624 MDT [DEBUG] content - >> "[\r][\n]"
>>> 2010/04/11 17:20:21:624 MDT [DEBUG] content - >> "[\r][\n]"
>>> ...............
>>>
>>> POST using Jersey Client (this does not work) :
>>>
>>> MultiPart multiPart = new MultiPart();
>>> WebResource.Builder builder = resource.getRequestBuilder();
>>> File targetFile = new File("customer.bin");
>>> FileDataBodyPart fileDataBodyPart = new FileDataBodyPart("file", targetFile, MediaType.APPLICATION_OCTET_STREAM_TYPE);
>>> multiPart.bodyPart(fileDataBodyPart);
>>> FormDataBodyPart formDataBodyPart = new FormDataBodyPart("user", "username);
>>> multiPart.bodyPart(formDataBodyPart);
>>> formDataBodyPart = new FormDataBodyPart("password", "password");
>>> multiPart.bodyPart(formDataBodyPart);
>>> formDataBodyPart = new FormDataBodyPart("tyoe", "X32");
>>> multiPart.bodyPart(formDataBodyPart);
>>> ClientResponse response = builder.type("multipart/form-data").post(ClientResponse.class, multiPart);
>>>
>>> Log output:
>>>
>>> INFO: 1 * Client out-bound request
>>> 1 > POST https://test.com/cgi-bin/submit.cgi
>>> 1 > Content-Type: multipart/form-data
>>> 1 >
>>>
>>> --Boundary_1_1839257702_1271040995070
>>> Content-Type: application/octet-stream
>>> Content-Disposition: form-data;name="file"
>>>
>>> ........
>>>
>>> I tried using FormDataMultiPart, but no luck. I am not sure what translates to setDoAuthentication() API in Jersey Client.
>>>
>>> I also tried something like using the ApacheHttpClient API in Jersey Client, but same result:
>>>
>>> DefaultApacheHttpClientConfig config = new DefaultApacheHttpClientConfig();
>>> config.getState().setCredentials(null, null, -1, "username", "password");
>>> config.getProperties().put(ApacheHttpClientConfig.PROPERTY_PREEMPTIVE_AUTHENTICATION, true);
>>>
>>> ApacheHttpClient client = ApacheHttpClient.create(config);
>>>
>>> I must be missing something fundamental here. Appreciate any suggestions.
>>>
>>> -Arul
>>
>>
>>
>