For example, I have the java code below:
URL u = new URL("http://google.com");
URLConnection c = u.openConnection();
InputStream s = c.getInputStream();
int i;
while ((i = s.read()) != -1) {
//do something here
}
And I cant understand, in which moment (after which method call) java sends the actual request to the server?
THe openConnection() method of the URL class, just returns you a new instance of HttpUrlConnection(because your protocol is http).
The actual connection doesent happen until you call the getInputStream() or getOutputStream() methods. It's on the call of these methods that connect() is called and the google server receives the connection. And because the protocol is http, the server would return you the google home page, which you are reading using s.read(). (it should give you the html page of google home page)
It happens during the openConnection() method. You can tell this by reading its documentation
A new connection is opened every time by calling the openConnection method of the protocol handler for this URL.
When you call openConnection it is actually trying to create connection with specified url and in case it fails then throws IOException.
openConnection - new connection is opened every time by calling the openConnection method of the protocol handler for this URL.
Related
I want to use HttpURLConnection to connect to my webservice, POST an XML and get a result. I am using the following code:
URL url = new URL(urlString);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
Problem is, when I call the setRequestProperty method, it fails with an IllegalStateException saying I am "already connected". Apparently, openConnection in fact opens the connection to the URL (in my debugger, I can see the connected boolean set to true). According to the URL documentation of Oracle though, it shouldn't. The Android docs are unclear about it.
How do I prevent openConnection to connect, so I can set extra properties?
Update it looks like the connection is in some pool and doesn't get disconnected, not even after calling connection.disconnect(), or even killing the server.
I do not think this is a duplicate of this question as it gives no real answer. Also, the documentation seems to be unclear.
openConnection() does not connect, and the code you have posted does not behave as yu have described. What opens the TCP connection is any of the following:
getInputStream()
getErrorStream()
getResponseCode()
Ergo you must have called one of those before trying to set a request property.
Our application need to send some request to SOAP service. We use wsimport command to generate class for our client. But sometime when service down or some network problem, our request hang until timeout and that is rather too long. We want to control timeout value so we try serveral method.
For calling service method, after reading from other post, we set something like this:
((BindingProvider) port).getRequestContext().put("sun.net.client.defaultReadTimeout", 3000);
((BindingProvider) port).getRequestContext().put("sun.net.client.defaultConnectTimeout", 10000);
But before that,we have to call get port which will read wsdl file. We try to create URL like this:
url = new URL(null, "http://theirsite/WS?WSDL", new URLStreamHandler() {
#Override
protected URLConnection openConnection(URL url) throws IOException {
logger.info("URLStreamHandler got call!");
URL clone_url = new URL(url.toString());
HttpURLConnection clone_connection
= (HttpURLConnection) clone_url.openConnection();
clone_connection.setConnectTimeout(5000);
clone_connection.setReadTimeout(3000);
return (clone_connection);
}
});
And then we use this url as parameter when create Service object. But our URLStreamHandler never got call.
We even try to set system property like this:
System.setProperty("sun.net.client.defaultReadTimeout", "" + 3000);
System.setProperty("sun.net.client.defaultConnectTimeout", "" + 5000);
But so far nothing work for us.
So any1 can help me with this case? Or is there a better approach ? Need to mention that we don't want to read wsdl file from local.
Maybe the properties you are using are not the right ones.
Try these ones:
((javax.xml.ws.BindingProvider) port).getRequestContext().put("com.sun.xml.internal.ws.connect.timeout",
Integer.valueOf(timeout));
((javax.xml.ws.BindingProvider) port).getRequestContext().put("com.sun.xml.internal.ws.request.timeout",
Integer.valueOf(timeout));
Also, take care, there is a difference between com.sun.xml.ws.request.timeout and com.sun.xml.internal.ws.request.timeout. You should use internal when you are working with JDK JAX-WS implementation.
I want to read the second line of the text at this URL: "http://vuln2014.picoctf.com:51818/" (this is a capture-the-flag competition but only asking for flags or direction to flags breaks the competition rules). I am attempting to open an input stream from the URL but I get an Invalid HTTP Response exception. Any help is appreciated, and I recognize that my error is likely quite foolish.
Code:
URL url = new URL("http://vuln2014.picoctf.com:51818");
URLConnection con = url.openConnection();
InputStream is = con.getInputStream()
The error occurs at the third line.
java.io.IOException: Invalid Http response at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1342) at name.main(name.java:41)
curl happily gets the text from the page, and it is perfectly accessible from a web browser.
When you do this:
URL url = new URL("http://vuln2014.picoctf.com:51818");
URLConnection con = url.openConnection();
You are entering into a contract that says that this URL uses the http protocol. When you call openConnection it expects to get http responses because you used http:// in the URL as the protocol. The Java Documentation says:
If for the URL's protocol (such as HTTP or JAR), there exists a public, specialized URLConnection subclass belonging to one of the following packages or one of their subpackages: java.lang, java.io, java.util, java.net, the connection returned will be of that subclass. For example, for HTTP an HttpURLConnection will be returned, and for JAR a JarURLConnection will be returned.
The server you are connecting to just returns a couple lines of data. I retrieved them with the command nc vuln2014.picoctf.com 51818. There is no http response code like HTTP/1.1 200 OK:
Welcome to the Daedalus Corp Spies RSA Key Generation Service. The public modulus you should use to send your updates is below. Remember to use exponent 65537.
b4ab920c4772c5247e7d89ec7570af7295f92e3b584fc1a1a5624d19ca07cd72ab4ab9c8ec58a63c09f382aa319fa5a714a46ffafcb6529026bbc058fc49fb1c29ae9f414db4aa609a5cab6ff5c7b4c4cfc7c18844f048e3899934999510b2fe25fcf8c572514dd2e14c6e19c4668d9ad82fe647cf9e700dcf6dc23496be30bb
In this case I would use java.net.Socket to establish a connection and then read the lines. This is a simplistic approach that assumes there are 2 lines of data:
Socket theSocket;
try {
theSocket = new Socket("vuln2014.picoctf.com", 51818);
BufferedReader inFile = new BufferedReader(new InputStreamReader(theSocket.getInputStream()));
String strGreet = inFile.readLine();
String strData = inFile.readLine();
} catch (IOException e) {
e.printStackTrace();
}
As for why curl and browsers may render it properly? They are likely more lenient about the data they read and will just dump what is read from the port even if it doesn't conform to the specified protocol (like http)
I use URL connection to download stream in the Internet. But after i reset the modem, i can't continue download this stream caz it error: Connection reset. How i solve it?
Here is my code:
URL url = new URL(_URL);
HttpURLConnection hUC = (HttpURLConnection) url.openConnection();
hUC.connect();
while (true) {
if ((_data.num = is.read(_data.b)) == -1) {
break;
}
//write to file
fos.write(_data.b, 0, _data.num);
}
You can't - at least, not how you may be expecting.
Instead, you need to handle your exception, and determine how much data you've already read. Once your Internet connection is re-established - assuming that the HTTP server you're downloading from supports requestable byte ranges - you can then set custom HTTP Headers on the request and re-download the remaining portions. (This will require a new HttpURLConnection.)
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35 shows the related HTTP specifications involved to make this work.
This is a bit more complicated if you're looking for a "resume" type feature.
You would need to reissue the request once the internet comes back after a disconnect, and add a header to the request in order to resume the download at the byte number where you left off.
You need to set the Range property in the request header in order to specify how far in you're resuming. Then you would just continue to write to the "fos" object from there.
Check out this url: Java: resume Download in URLConnection
I am having an issue with this error:
**Server returned HTTP response code: 501 for URL: http://dev1:8080/data/xml/01423_01.xml**
See this code:
private static Map sendRequest(String hostName, String serviceName) throws Exception {
Map assets = null;
HttpURLConnection connection = null;
Authenticator.setDefault(new Authenticator());
URL serviceURL = new URL(hostName + "/" + serviceName);
connection = (HttpURLConnection)serviceURL.openConnection();
connection.setRequestMethod("GET");
ClientHttpRequest postRequest = new ClientHttpRequest(connection);
InputStream input = null;
/*
At line input = postRequest.post(); I get the following error
Server returned HTTP response code: 501 for URL: http://dev1:8080/data/xml/01423_01.xml
Yet if I enter that url in my browser it opens up fine.
Is this a common problem? Is there some type of content type I need to set?
*/
input = postRequest.post();
connection.disconnect();
return assets;
}
A 501 response means "not implemented", and is usually taken to mean that the server didn't understand the HTTP method that you used (e.g. get, post, etc).
I don't recognise ClientHttpRequest , but you have a line that says
connection.setRequestMethod("GET");
and then a line that says
input = postRequest.post();
I'm not sure what post() actually does, but does that mean send a POST request? If so, then that contradicts the GET specified in the first line.
Either way, the server is saying that it doesn't under the GET or the POST method, whichever one your code is actually sending. You need to find out what method the server does support for that URL, and use that.
Perhaps you should check your port settings:
new URL(hostName + "/" + serviceName);
Looks like the port number ":8080" is missing.
Some server expect additional information from the client in the request like a user agent or some form data. Even cookies could be expected by the application running on the server. You should also check the complete response and not only the response code.
I would recommend you to use a library like httpclient that is more convenient:
https://hc.apache.org/httpcomponents-client-ga/index.html
Here is simple usage example:
https://github.com/apache/httpcomponents-client/blob/master/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientWithResponseHandler.java