HttpURLConnection connect method fails to connect - java

SocketAddress proxy = new InetSocketAddress("127.0.0.1", 8080);
URL url = new URL("http://192.168.1.1/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection(new Proxy(Proxy.Type.HTTP, proxy));
connection.setDoOutput(true);
String body = "This is a body example";
OutputStreamWriter writer = new OutputStreamWriter(new BufferedOutputStream(connection.getOutputStream()), "8859_1");
writer.write(body);
writer.flush();
writer.close();
connection.connect();
The problem is that when I run this code no requests are "catched" by my proxy (it is well configured). I know connect() is an abstract method in URLConnection but given that HttpURLConnection is extending URLConnection it is suppose to override it. This is what javadoc say about connect() : "Opens a communications link to the resource referenced by this URL, if such a connection has not already been established." So the request should have been sent. Anyone know what causes the problem?
NOTE : If I replace connection.connect() with connection.getResponseHeader() I catch a request. As I have read in javadoc if the connection is not set yet a call to getResponseHeader() will call implicitly the connect() method.

This is what javadoc say about connect() : "Opens a communications link to the resource referenced by this URL, if such a connection has not already been established."
Correct.
So the request should have been sent.
Non sequitur. Thwre is nothing in your quotation about sending the request.
As you have observed, the request is buffered until you perform some input step.

Related

java.net.ProtocolException: where is input being read?

I've looked at multiple posts with this issue, and most/all of them have code that tries to create an inputstream before an outputstream. I get that. I didn't think I was doing that here. Where is my inputstream being created before the error?
URL url = new URL(myURL);
HttpURLConnection conn=(HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
conn.setDoOutput(true);
// Grab, configure json input as myInput
// ...
byte[] input = myInput.getBytes();
conn.connect();
// Write as post body
try(OutputStream os = conn.getOutputStream()) {
os.write(input); // <-- java.net.ProtocolException Error "Cannot write output after reading input" here
}
// Attempt to read response using InputStream
// ...
From the documentation of URLConnection::connect()
Opens a communications link to the resource referenced by this URL, if such a connection has not already been established.
If the connect method is called when the connection has already been opened (indicated by the connected field having the value true), the call is ignored.
URLConnection objects go through two phases: first they are created, then they are connected. After being created, and before being connected, various options can be specified (e.g., doInput and UseCaches). After connecting, it is an error to try to set them. Operations that depend on being connected, like getContentLength, will implicitly perform the connection, if necessary
So basically you're requiring to write in the OutputStream after you have manually opened the connection to the resource, without taking care of which flags or settings are set on that process. That won't work.
Actually, you shouldn't even call the method connect() by yourself, since the methods that depend on being connected, like getInputStream() and getOutputStream() already will perform the connection if they need to.
Remove the line conn.connect().

HttpURLConnection connect() , getInputStream() , getContent() , HttpGet

I use the class HttpURLConnection , but Iam confused with some methods
assume the HttpURLConnection object name is "c"
removing c.connect() will result in a success connection and it will retrieve the connection result without any problem
the output of c.getInputStream() and (InputStream) c.grtContent() are identical , so what is the difference betqween them
using HttpGet will reach the same approach as HttpURLConnection , so what is the difference between the two methods
what are the extra benefits for HttpURLConnection on URLConnection
c = (HttpURLConnection) (URL).openConnection();
c.connect(); //adding or removing makes the same result , so what is the usage of this method
InputStream stream= c.getInputStream();
InputStream stream2 = (InputStream) c.getContent();
//stream and stream2 are identical , so what is the differece between getInputStream() and getContent()
//============================
HttpGet c= new HttpGet(url);
HttpResponse response = c.execute(httpGet)
InputStream stream3 = response.getEntity().getContent();
//also stream3 is the same as stream & stream2 ; so how dose it different between HttpGet & HttpURLConnection
From Android documentation:
[HttpURLConnection is] A URLConnection with support for HTTP-specific features.
For instance, from an HttpURLConnection you can retrieve the HTTP method or the HTTP status code, which are HTTP-specific.
The URLConnection class, instead, is:
The abstract class URLConnection is the superclass of all classes that represent a communications link between the application and a URL
The normal usage is:
Create a URL object
Get a URLConnection by calling url.openConnection(). The returned object can be casted to an HttpURLConnection
get an InputStream by calling the connection.getInputStream() method
Close the connection (disconnect() method) (see #EJP comments)
Concerning the connect() method, from the Oracle documentation:
You are not always required to explicitly call the connect method to initiate the connection. Operations that depend on being connected, like getInputStream, getOutputStream, etc, will implicitly perform the connection, if necessary.
The difference between the HttpGet and HttpURLConnection is that they belong to 2 different libraries, but functionally they are more or less the same (now HttpGet has been deprecated and removed, so you won't find it in the standard Android APIs)

Java Jodd Http Client with proxy

I used Jodd Http library to connect with the proxy:
ProxyInfo proxyInfoObj = new ProxyInfo(ProxyType.HTTP, "10.30.56.70", 8080, "", "");
SocketHttpConnectionProvider provider = new SocketHttpConnectionProvider();
provider.useProxy(proxyInfoObj);
HttpRequest request = HttpRequest.get(url);
request.method("GET");
request.charset("UTF-8");
HttpResponse response = request.open(provider).send();
result = response.bodyText();
But i got this error:
jodd.http.HttpException: HTTP: Invalid code
at jodd.http.net.HTTPProxySocketFactory.createHttpProxySocket(HTTPProxySocketFactory.java:113)
at jodd.http.net.HTTPProxySocketFactory.createSocket(HTTPProxySocketFactory.java:32)
If I use SOCKS4 type, the program hang and don't return anything. Can anyone help me?
But I can connect via proxy using following code:
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("10.30.56.70", 8080));
HttpURLConnection connection =(HttpURLConnection)new URL("http://tvl.csmtalk.vn/api/sms/receive").openConnection(proxy);
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestProperty("Content-type", "text/xml");
connection.setRequestProperty("Accept", "text/xml, application/xml");
connection.setRequestMethod("GET");
connection.connect();
For me both codes hangs. When I try Jodd, it hangs because it can not open proxy socket to 10.30.56.70:8080. When I try to
telnet 10.30.56.70 8080
from command line it hangs as well. It looks like proxy is not responding. (You can contact Jodd support if you need more details, or if you want to send some private data regarding the connectivity.)
btw, you don't need to:
request.method("GET");
request.charset("UTF-8");
as method is already set to GET by method get() and charset is not used for requests, but response (to set one if not set by server).

After which methods call java send real request to server?

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.

Connect to site through https

I have some application that should connect to https Site, and receive some.
With connection all is ok, but when i what getInputStream() comes Exception:
java.io.IOException: Server returned HTTP response code: 403 for URL:
Here is the part of code:
String query = siteURL.toExternalForm();
URL queryURL = new URL(query);
String data = "username="+login+"&password="+password;
URLConnection connection = queryURL.openConnection();
connection.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(connection
.getOutputStream());
writer.write(data);
writer.flush();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
Looks like you're not allowed to do what you're trying to do, you're getting an HTTP 403: Forbidden.
Can you open the same URL in your browser?
I think the site have a custom authentication mechanism, in wich you have to supply our username and password as GET parameters. So your url should look like this:
URL url = new URL("http://somesite.org/page?username=<username>&password=password");
... = url.openConnection();
...
If you use url.openConnection, a HTTP GET request is done. If you want to send data with a request, you must use a HTTP POST request. In this case, you can use a third party library, like Apache Commons HttpClient.
BTW: why are u creating a new URL object, if you already have one?

Categories

Resources