We have a legacy SOAP web service, implemented using Apache Axis 1. At the client environment, the response data sometimes gets truncated on certain API calls causing error. But when tested using SOAP UI client, it returns full data as expected. This behavior can't be locally replicated in our dev environment and happens only at client office. They do have front end proxies and stuff in place to route the request.
We are still using HTTP 1.0. Will that be causing any issues with a big payload? How much effort will it take to upgrade to HTTP 1.1? Will it be a simple header upgrade stating HTTP/1.1?
We are already encoding the data using utf-8 on request and response.
Sample SOAP request:
[POST /apixyzCall HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/1.1beta
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: "http://abc/SoapManager"
Content-Length: 983
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
PAYLOAD
</soapenv:Body>
</soapenv:Envelope>
]
Any tips?
Turned out the issue was with SSL. The API returns complete data using HTTP, but it truncates response once SSL is enabled. It was closing the connection before the client receives the full response.
Related
My team and I have a Tomcat server running a Restfull webservice, implemented using RestEasy:
#POST
#GZIP
#Path("/capture")
#Consumes(MediaType.APPLICATION_JSON)
Response RecieveData(#GZIP RecievingData recievingData);
We need to make compressed post to this service. The problem is we are not finding an implementation that works.
We tried using interceptors:
https://hc.apache.org/httpcomponents-client-4.2.x/httpclient/examples/org/apache/http/examples/client/ClientGZipContentCompression.java. But we were unable to capture the POST request Body and compress it.
We tried using the RestEasy client but it doesn´t seems to be compreesing the body of the Post Request: www.posttestserver.com/data/2016/01/06/15.33.391016591335
Finally we tried a customized class: https://gist.github.com/takumakei/913067. But we got a 400 error on the request:
HTTP/1.1 400 Bad Request [Content-Encoding: gzip, Content-Type:
text/html; charset=UTF-8, Date: Thu, 07 Jan 2016 10:07:05 GMT, Server:
Apache-Coyote/1.1, Content-Length: 66, Connection: keep-alive]
We are out of ideas and this supose to be a simple function for an HTTP Client. Any ideas?
OBS: Here is the RestEasy Proxy:
#POST
#GZIP
#Consumes(MediaType.APPLICATION_JSON)
public Response saveData(#GZIP RecievingData customer);
EDIT: Got some changes in the Firewall and the 3rd method changed to an error 400.
If using Tomcat why not add a RequestFilter that will pre-process received requests that contain header Content-Encoding: gzip and decompress it before the rest of the filter chain handles it?
EDIT:
I'm guessing your third option may actually have worked (snoop the network to verify), the issue was you got 403 - Forbidden response from the server. That's a problem with authorization not with the URL, request encoding, or anything else. The GZIP might actually be working for you right now.
EDIT:
Your latest output for HTTP response code 400 - Bad Request shows Content-Type: text/html. The Controller is expecting Content-Type: application/json, so the client did not set the ContentType as required by the Controller. Recheck your usage and config of the client code.
In the end I used the Resteasy framework for server and client to implement the GZIP compression.
Server side:
https://docs.jboss.org/resteasy/docs/2.3.0.GA/userguide/html/gzip.html
Client Side:
https://docs.jboss.org/resteasy/docs/2.2.1.GA/userguide/html/RESTEasy_Client_Framework.html
That worked for me.
I am consuming a web service. I wrote a client with axis 1.4 using eclipse. I have access to webservices over ssl vpn. My axis client code works fine. However, code must be run on android device. I can not use axis code on android, because java rmi is not supported on android. I am trying to consume service with making httppost with apache httpclient library. In order to see axis request values, I used tcpmon. It helped me to write httppost code easily. The problem is that when I run code directly without using tcpmon it gives me the error below:
Exception in thread "main" java.net.SocketException: Invalid argument: setsockopt
at java.net.DualStackPlainSocketImpl.setIntOption(Native Method)
at java.net.DualStackPlainSocketImpl.socketSetOption(Unknown Source)
at java.net.AbstractPlainSocketImpl.setOption(Unknown Source)
at java.net.PlainSocketImpl.setOption(Unknown Source)
at java.net.Socket.setTcpNoDelay(Unknown Source)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.prepareSocket(DefaultClientConnectionOperator.java:254)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:185)
at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:643)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:479)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)
at TTIncidentClient.main(TTIncidentClient.java:56)
If I send request over tcpmon it works. I get the response. I give you tcpmon output below:
REQUEST:
POST http://localhost:3333/SM/7/ws HTTP/1.1
SOAPAction: RetrieveList
Accept: application/soap+xml, application/dime, multipart/related, text/*
Pragma: no-cache
Cache-Control: no-cache
Authorization: Basic bW9iaXNlbTpPeXAlPzIwMTM=
Content-Length: 456
Content-Type: text/xml; charset=ISO-8859-1
Host: 10.6.105.132:3333
Proxy-Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.2.5 (java 1.5)
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><RetrieveIncidentListRequest xmlns="http://schemas.hp.com/SM/7"><keys query="flag=true and category="incident" and assignee.name="xx.yy""/></RetrieveIncidentListRequest></soapenv:Body></soapenv:Envelope>
RESPONSE:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=AF8B0B75ED768852E44D7CB49DB5DD88; Path=/SM
Keep-Alive: timeout=1200000, max=1000
Connection: Keep-Alive
Content-Type: text/xml;charset=utf-8
Content-Length: 2009
Date: Sun, 11 Aug 2013 22:12:17 GMT
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><RetrieveIncidentListResponse message="Success" returnCode="0" schemaRevisionDate="2012-11-12" schemaRevisionLevel="0" status="SUCCESS" xmlns="http://schemas.hp.com/SM/7" xmlns:cmn="http://schemas.hp.com/SM/7/Common" xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.hp.com/SM/7 http://testsc:3333/SM/7/Incident.xsd">......</SOAP-ENV:Body></SOAP-ENV:Envelope>
Normally I expect tcpmon behaviour must be same with my local but tcpmon changes the result. What can be the reason ?
Very interestingly, instead of using apache httpclient or java urlconnection libraries , I wrote socket programming code for soap as in this example it worked. :)
I am trying to send a gziped multipart POST to a Tomcat server from a Java application using Jersey. When the multipart request is not compressed, it works perfectly fine. Other types of compressed POSTS work fine, such as sending a single entity XML. I (believe) posting compressed data isn't an HTTP standard, but it does seem Tomcat supports it to some degree.
a working uncompressed multipart post:
POST /myApp/rest/data HTTP/1.1
Content-Type: multipart/mixed; boundary=Boundary_1_23237284_1331130438482
Cookie: JSESSIONID=XXXXXXXXXXXXXXXXXXXXXXXXX;Version=1;Path=/myApp/
MIME-Version: 1.0
User-Agent: Java/1.6.0_26
Host: localhost:8080
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Transfer-Encoding: chunked
d3
--Boundary_1_23237284_1331130438482
Content-Type: application/octet-stream
Content-Disposition: form-data; filename="uploadFile.war"; modification-date="Wed, 29 Feb 2012 18:01:38 GMT"; size=25343899; name="file"
{binary data here}
--Boundary_1_25179713_1331128929019
Content-Type: application/xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><myXMLEntity>stuff</myXMLEntity>
--Boundary_1_25179713_1331128929019--
When I compress it using the Jersey GZIPContentEncodingFilter() the following headers are sent, and I get back an HTTP 400 with a description of "incorrect syntax"
POST /myApp/rest/data HTTP/1.1
Content-Type: multipart/mixed
Cookie: JSESSIONID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX;Version=1;Path=/myApp/
Accept-Encoding: gzip
Content-Encoding: gzip
User-Agent: Java/1.6.0_26
Host: localhost:8080
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Transfer-Encoding: chunked
{binary data here}
Is what I'm trying to do possible? Should the Content-Type actually read multipart/x-gzip? I notice that when it gets compressed, the boundary text gets left off of the Content-Type header - is this also a problem?
I ran into this same issue (or something very similar) and tracked it down to the Content-Type header missing the boundary parameter when using GZIPContentEncodingFilter. I was able to work around it by using MultiPartMediaTypes.createFormData() when setting the type of the entity I was POSTing from the Jersey client. Doing so makes sure the boundary parameter is set earlier than Jersey would automatically set it, which seems to be too late when using the GZIPContentEncodingFilter for compressing the request entity. There is an equivalent method for multipart/mixed.
I don't have an IDE handy but something similar to this:
// client is a Jersey Client object
client.resource(uri).entity(multipartFormData, MultiPartMediaTypes.createFormData()).post(ClientResponse.class);
All that said, this will still only work if your server is able to handle GZIP compressed requests.
IMO you can't do this that way, because the server and the client need to agree on how to communicate (e.g. zip compression). HTTP is designed as request/response and server can return what the client can support.
The client sends request to the saying, "Hey server, I need this resource and I support gzip, so you can return gzip if you can". :)
Imagine a situation that your client sends to the server a few megabytes in gzip, but the server doesn't support this.
I make very simple HTTP server in Java. The response sent to the browser is
HTTP 1.1 200 OK
Server: OneFile 1.0
Content-Type: text/html; charset=utf-8
Content-Length: 202
Transfer-Encoding: chunked
<HTML><HEAD><TITLE>My website</TITLE></HEAD>
<BODY><H1>Document </H1>
</BODY></HTML>
mozilla firefox displays it as text/plain although it should be text/html Why?
I suspect the Setup info is ignored...is it any difference for browser if I make connection on port 8080?
Thanks for any help
The browser will honor your headers. Unfortunately, your response is malformed for several reasons:
the response should start HTTP/1.1, not HTTP 1.1
you specify Transfer-Encoding: chunked, but your response does not follow the chunked format.
It appears that Firefox, quite sensibly, refuses to interpret such malformed response and just shows it unchanged.
I noticed my home router has some configuration field "TR-069 CLIENT CONFIGURATION" and some obscure address that I noticed gets resolved quite often each day. (Yes obviously to config the router remotely.. or something) But I want to see what is being sent. So wrote a very simple "web server" in Java to read in HTTP requests (the field in the router was with a normal http:// address) and print them out. (i set that field to point to my computer where the little server is running)
And im getting these:
Host: 192.168.1.2
User-Agent: Allegro-Software-WebClient/4.07
Accept: */*
Content-Type: text/xml; charset=utf-8
Content-Length: 2767
SOAPAction:
Was kind of hoping SOAPAction: wouldnt be empty but what does this mean, is it some deprecated feature of the router that just happens to keep going? (its a d-link ADSL Router)
There would be multiple soap envelopes in HTTP Request.
TR-069 spec says
When there is more than one envelope
in a single HTTP Request, the
SOAPAction header in the HTTP Request
MUST have no value (with no quotes),
indicating that this header provides
no information as to the intent of the
message. That is, it should appear as
follows:
SOAPAction: