I have a Vanguard webservice which I can call (using basic authentication) using a custom java class. The java wsimport tool was used to generate the java proxy stubs and this all works perfectly.
The java code (All classes below are generated by wsimport given a url + authentication info):
Authenticator.setDefault(new SimpleAuth(username,pass));
MyWSObject obj = new MyWSObject(url); -> triggers the exception
ServicePortType port = obj.getServicePort();
OutputType result = port.MyWSMethod(params);
OutputData data = result.getOutputData();
When I run the exact same java function (containing the above code) from matlab the webservice call fails with an obscure error:
??? Java exception occurred:
com.sun.xml.internal.ws.streaming.XMLStreamReaderException: XML reader error: com.ctc.wstx.exc.WstxUnexpectedCharException:
Unexpected character '"' (code 34) in DOCTYPE declaration; expected a space between public and system identifiers
at [row,col,system-id]:
[1,63,"<my webservice url>"]
at com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil.wrapException(XMLStreamReaderUtil.java:256)
at com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil.next(XMLStreamReaderUtil.java:84)
at com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil.nextContent(XMLStreamReaderUtil.java:99)
at com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil.nextElementContent(XMLStreamReaderUtil.java:89)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.hasWSDLDefinitions(RuntimeWSDLParser.java:209)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:119)
at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:254)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:217)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:165)
at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:93)
at javax.xml.ws.Service.<init>(Service.java:56)
at edu.soton.decode.activities.vanguardws.MyWSObject.<init>(MyWSObject.java:42)
at edu.soton.decode.activities.VanguardActivity.execute(VanguardActivity.java:80)
If I use wireshark to monitor the requests/reponses in both cases I see:
== Java function called directly ==
All the calls/reponses below happen automatically by the JAX-WS code generated by wsimport. My code just calls the webservice method on the generated service proxy, nothing fancy.
GET /bin/ws.dsb?wsdl/mywebservice HTTP/1.1
User-Agent: Java/1.6.0_22
Host: myhost
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
...
HTTP/1.1 401 Authorization Required
Server: Vanguard Server/5.1.10
Connection: close
Content-Length: 608
Date: Mon, 01 Nov 2010 15:04:17 GMT
Last-Modified: Mon, 01 Nov 2010 15:04:17 GMT
Expires: Mon, 01 Nov 2010 15:04:17 GMT
Cache-Control: no-cache
WWW-Authenticate: Basic realm="Local Library"
Auto-Studio-Login: 0
Content-Type: text/html
...
GET /bin/ws.dsb?wsdl/mywebservice HTTP/1.1
User-Agent: Java/1.6.0_22
Host: myhost
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Authorization: Basic Z29yaXNzZW46ZGlyaw==
...
HTTP/1.1 200 OK
Server: Vanguard Server/5.1.10
Connection: close
Content-Length: 5408
Date: Mon, 01 Nov 2010 15:04:17 GMT
Last-Modified: Mon, 01 Nov 2010 15:04:17 GMT
Expires: Mon, 01 Nov 2010 15:04:17 GMT
Cache-Control: no-cache
Set-Cookie: KillIDws=lpvovmb3oa9; path=/
Content-Type:text/xml
...
POST /bin/ws.dsb?soap/mywebservice HTTP/1.1
Content-type: text/xml;charset="utf-8"
Soapaction: ""
Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
User-Agent: JAX-WS RI 2.1.6 in JDK 6
Host: myhost
Connection: keep-alive
Authorization: Basic Z29yaXNzZW46ZGlyaw==
Content-Length: 214
...
HTTP/1.1 200 OK
Server: Vanguard Server/5.1.10
Connection: close
Content-Length: 851
Date: Mon, 01 Nov 2010 15:04:18 GMT
Last-Modified: Mon, 01 Nov 2010 15:04:18 GMT
Expires: Mon, 01 Nov 2010 15:04:18 GMT
Cache-Control: no-cache
Set-Cookie: KillIDws=lpvovmb3oi2; path=/
Content-Type:text/xml; charset=utf-8
...
-> the last response is where the results are returned
== Exactly the same Java function called from inside Matlab ==
GET /bin/ws.dsb?wsdl/mywebservice HTTP/1.1
Accept: */*
Accept-Encoding: gzip
Accept-Language: en
User-Agent: Mozilla/5.0 (Java 1.6.0_22; Windows XP 5.2 amd64; en_GB) ICEbrowser/v6_0_2
Host: myhost
Connection: Keep-Alive
...
HTTP/1.1 401 Authorization Required
Server: Vanguard Server/5.1.10
Connection: close
Content-Length: 608
Date: Mon, 01 Nov 2010 15:02:42 GMT
Last-Modified: Mon, 01 Nov 2010 15:02:42 GMT
Expires: Mon, 01 Nov 2010 15:02:42 GMT
Cache-Control: no-cache
WWW-Authenticate: Basic realm="Local Library"
Auto-Studio-Login: 0
Content-Type: text/html
...
-> everything stops here with the exception shown above. So when running inside Matlab, it seems Matlab is doing something to the JVM environment that stops the generated proxy from making a second, authenticated call. It simply bails out after the 401 instead of authenticating like in the pure java case.
I have set MATLAB_JAVA environment variable so that the same JVM (sun 1.6) is used in both cases. I have also noticed that Matlab does not respect the http.agent property when sending requests.
It turns out that the problem only seems to occur on 64bit versions of Matlab on non-linux platforms. It works fine if I install a 32bit version of Matlab. I am going to mark this question as answered since this seems to be a problem with Matlab and Mathworks are investigating the issue (thread id: 1-DUMQQZ]).
If proxy settings are responsible for the issue, the following static methods can be used for configuration.
% configure
java.lang.System.getProperties().put('http.proxyHost', 'your.proxy');
java.lang.System.getProperties().put('http.proxyPort', 'port number');
java.lang.System.getProperties().put('http.proxyUser', 'name');
java.lang.System.getProperties().put('http.proxyPassword', 'password');
java.lang.System.getProperties().put('http.proxySet', 'true');
% verify
java.lang.System.getProperty('http.proxyHost')
java.lang.System.getProperty('http.proxyPort')
java.lang.System.getProperty('http.proxyUser')
java.lang.System.getProperty('http.proxyPassword')
% test
urlread('http://www.yahoo.com/')
ICEbrowser, which MATLAB still uses on some platforms for HTML rendering, inserts some of its own classes into global VM settings. This may work for you if you never open the Help Browser in the current session.
Related
I am using a SOAP webservice that is supposed to work with Java, PHP and a lot of technologies. However, it is only working correctly with PHP.
I used the SOAPClient class in PHP to implement the client. When I printed the request and response headers, I got something like this:
REQUEST HEADERS:
POST /ws/something.php HTTP/1.1
Host: xxx.com
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.5.30
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://example.com/ws/something.php/someMethod"
Content-Length: 417
Authorization: Basic <username:password here>
RESPONSE HEADERS:
HTTP/1.1 200 OK
Date: Thu, 03 Mar 2016 18:03:48 GMT
Server: Apache
Strict-Transport-Security: max-age=63072000; includeSubdomains; preload
Content-Length: 512049
Vary: Accept-Encoding,User-Agent
Content-Type: text/xml; charset=utf-8
Set-Cookie: BALANCEID=balancer.<someIP>; path=/; HTTPOnly; Secure
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Then, I used SAAJ in Java to write the exact same request like how PHP does it. I edited even the user-agent to make it exact, but I have no luck. The response is always the SOAP service's wsdl. For some reason, the web service does not execute anything if I use Java.
These are the request headers for Java:
Authorization Basic <username:password here>
SOAPAction http://example.com/ws/something.php/someMethod
POST /ws/something.php HTTP/1.1
Host xxx.com
Connection Keep-Alive
User-Agent PHP-SOAP/5.5.30
Content-Type text/xml; charset=utf-8
Content-Length 417
This is the response header:
Date Thu
Date 03 Mar 2016 18:24:35 GMT
Server Apache
Strict-Transport-Security max-age=63072000; includeSubdomains; preload
Accept-Ranges none
Vary Accept-Encoding
Vary User-Agent
Content-Type text/xml; charset=UTF-8
Set-Cookie BALANCEID=balancer.<some IP>; path=/; HTTPOnly; Secure
Keep-Alive timeout=2
Keep-Alive max=100
Connection Keep-Alive
Transfer-Encoding chunked
Content-Length 8444
SOAPAction ""
Note how the response header is completely different.
I have no idea why the web service won't execute the exact same request from Java. It just returns the wsdl. Does that mean something is wrong with my request or does the web service magically work only with PHP soapClient?
I need to use the "Range" header to continue downloading a partially downloaded file with my android app.
conn.setRequestProperty("Range", "bytes=" + this.downloadedBytes + "-");
And when I log it to logcat I see only what I've
conn.getRequestProperties().toString()
{Range=[bytes=3129-]}
My server is responding with a HTTP 416, range cannot be satisfied. I see this response in the apache access log. I get an IOException (java.io.FileNotFoundException), which is my guess as to how it deals with a 416, just like it would a 404. And that is a totally normal response, except that curl works perfectly to that same file!
curl -I --header "Range: bytes=3129-` ...
I get the expected HTTP 200 response:
Last-Modified: Fri, 27 Mar 2015 15:26:59 GMT
Accept-Ranges: bytes
Content-Length: 1915
Cache-Control: max-age=0
Expires: Fri, 27 Mar 2015 19:17:33 GMT
Vary: Accept-Encoding
Content-Range: bytes 3129-5043/5044
Content-Type: text/html
What am I missing on the android/java side here? What about the request is making apache serve back a 416 when curl works just fine?
I connect a nginx http service by socket,i use java Language:
url:api.weibo.com/2/users/show.json
GET /2/users/show.json HTTP/1.1
Host: api.weibo.com
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
Cookie: PHPSESSID=uc67dtcb5r3orchgv0dgdd0f57; think_template=default
but it return:
HTTP/1.1 400 Bad Request
Server: Weibo
Date: Sat, 24 Jan 2015 10:07:33 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Api-Server-IP: 10.75.0.174
Vary: Accept-Encoding
60
{"error":"source paramter(appkey) is missing","error_code":10006,"request":"/2/users/show.json"}
0
i don't know what is the '60' and '0'
if i use HTTP/1.0 instand of HTTP/1.1,it return:
HTTP/1.1 400 Bad Request
Server: Weibo
Date: Sat, 24 Jan 2015 10:22:09 GMT
Content-Type: application/json;charset=UTF-8
Connection: close
Api-Server-IP: 10.75.5.92
Vary: Accept-Encoding
{"error":"source paramter(appkey) is missing","error_code":10006,"request":"/2/users/show.json"}
if i use socket connect iis or apache,all ok to use HTTP/1.1
Anybody can tell me why,and how to Solve?
The webservice returns the content in chunks, by first sending the length of the next chunk. It is using Chunked Transfer Encoding.
You are saying you can speak HTTP/1.1 with GET /2/users/show.json HTTP/1.1 and
All HTTP/1.1 applications MUST be able to receive and decode the
"chunked" transfer-coding....
You could use something like the Apache HttpClient or some other Java HTTP client library to avoid implementing HTTP on your own.
I'm using the Google App Engine Java SDK 1.7.2 to serve some static files. When combining multiple <include... elements under <static-files> in appengine-web.xml, I am unsure which rules will take precedence.
For example, I have the following:
<static-files>
<include path="/**.swf" expiration="365d"></include>
<include path="/**.jpg" expiration="365d"></include>
<include path="/**"></include>
<exclude path="/**.php"></exclude>
</static-files>
I believe this specifies that everything should be included in static storage, except .php files, and that .swf and .jpg files should have "cache-control" and "expires" http headers set 365 days in the future.
However, when using the Live HTTP Headers tool for Firefox, I could not see the expected headers for static files with the long expiration:
http://localhost:8888/swf/Logo.20120927.swf
GET /swf/Logo.20120927.swf HTTP/1.1
Host: localhost:8888
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:15.0) Gecko/20100101 Firefox/15.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Referer: http://localhost:8888/
If-Modified-Since: Thu, 27 Sep 2012 15:49:03 GMT
Cache-Control: max-age=0
HTTP/1.1 304 Not Modified
Server: Jetty(6.1.x)
----------------------------------------------------------
http://localhost:8888/images/logo-and-buttons.20120927.jpg
GET /images/logo-and-buttons.20120927.jpg HTTP/1.1
Host: localhost:8888
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:15.0) Gecko/20100101 Firefox/15.0.1
Accept: image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: en-gb,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Referer: http://localhost:8888/
If-Modified-Since: Thu, 27 Sep 2012 15:49:03 GMT
Cache-Control: max-age=0
HTTP/1.1 304 Not Modified
Server: Jetty(6.1.x)
My question is, if this is not operating as expected, then how do I configure my <static-files> element to achieve the desired effect?
Cheers,
Jeff.
I have answered my own question: The reason I was getting "cache-control: max-age" values of 0, and no "expires" values in my HTTP headers, was because I was just reloading the page in Firefox. Upon starting a new Private Browsing session (resetting the cache in the process), and loading the page for the first time, I received the expected headers.
If I run a webapp under the uri /myapp then as soon as the app is accessed via http://example.com/myapp, the URL changes to http://example.com/myapp/. Is there any way to prevent this?
When you have such a behaviour your web (or application) server returns a
301 Moved Permanently
when the URL without slash is requested.
You can see a similar example when getting http://www.google.es/services
HTTP/1.1 301 Moved Permanently
Location: http://www.google.es/services/
Content-Type: text/html; charset=UTF-8
X-Content-Type-Options: nosniff
Date: Wed, 11 May 2011 15:24:06 GMT
Expires: Fri, 10 Jun 2011 15:24:06 GMT
Cache-Control: public, max-age=2592000
Server: sffe
Content-Length: 227
X-XSS-Protection: 1; mode=block
After this first HTTP get to http://www.google.es/services
(without slash), the browser makes a second HTTP get to http://www.google.es/services/ (with slash). You can trace the HTTP requests with Network tab in Firebug, for example.
You can check your web/application server configuration, and maybe you can change this behaviour.