I want to send 2 kinds of request via proxy: http and https. Here's how I'm doing an HTTP request:
HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);
and HTTPS:
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(proxy);
The rest of the code is identical:
//..................
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("ip", 1234));
//..................
conn.setRequestProperty("Proxy-Connection", "Keep-Alive");
conn.setRequestProperty("Proxy-Authorization", auth);
conn.setDoInput(true);
System.out.println("Response Code : " + conn.getResponseCode());
System.out.println("\n");
In case of HTTP it returns 200 and the body of the response which means everything is working fine. However, for HTTPS requests it returns:
Unable to tunnel through proxy. Proxy returns "HTTP/1.0 407 Proxy Authentication Required
How come?
I don't consider using the class Authenticator or System.setProperty. I want to figure out why my code isn't working correctly for https and is for http.
You use Basic authentication schema.
According Oracle update # 8u111
In some environments, certain authentication schemes may be
undesirable when proxying HTTPS. Accordingly, the Basic authentication
scheme has been deactivated, by default, in the Oracle Java Runtime,
by adding Basic to the jdk.http.auth.tunneling.disabledSchemes
networking property.
Thus you need clear list of disabledSchemes by
- or invoke at main static method System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
- or add JVM parameter -Djdk.http.auth.tunneling.disabledSchemes=
- or use Apache Common HttpClient
Related
I am facing this HTTP 403 Forbidden response from a https REST service when I am trying to call it from my java code. Can you kindly let me know if I am missing something here?
Please note that the server returns the expected data when I trigger the request from any browser / SOAPUI/ Chrome Postman clients.
2 peer certificates are used - as shown in the ssl info from soapui after the request is sent.
The code snippet is attached. [The headers I set in the code are taken from the request header I found from the successful requests]
HttpsURLConnection connection = (HttpsURLConnection)new URL("https://server address").openConnection();
connection.setRequestProperty("Authorization", "Basic " + authStringEnc);
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
connection.setRequestProperty("Accept-Encoding","gzip, deflate, br");
connection.setRequestProperty("User-Agent", "Apache-HttpClient/4.1.1");
connection.addRequestProperty("Connection", "Keep-Alive");
connection.addRequestProperty("Cache-Control","no-cache");
connection.setRequestMethod("GET");
connection.connect();
System.out.println("Response Code : " + connection.getResponseCode()+" "+connection.getResponseMessage());
Response Code : 403 Forbidden
Can you please check the Server URL if it is in the Java Acceptable format?
Sometimes java need escape characters to recognize strings correctly.
This question: What are all the escape characters? , can help you to check if you are using any of those characters. Also check if the conversion in the function is done properly.
Also, if you have more complex URL, consider to use java.net.URL .
Finally, check the user agent parameter Setting user agent of a java URLConnection .
Thanks for your response. The issue is with session cookie to be used for the connection. We are able to connect and get the response back with response code HTTP 200 once the cookie with JSESSIONID is passed as a header. Thanks again.
What I need to do is send POST request to specific URL with two parameters and when the request is sent, I need to redirect user to that link so that he would be able to access functionality.
So far, what I have managed to do from various examples is this:
private void postRemoteAdvisoryLink() throws IOException {
URL obj = new URL(KdrmApplicationContext.getRemoteAdvisoryUrlPath());
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setConnectTimeout(60000);
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "Mozilla/5.0");
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
// For post only - start
con.setDoOutput(true);
OutputStream os = con.getOutputStream();
os.write(("?auth=ssor&TransportKey=" + ssorTransportKey).getBytes());
os.flush();
os.close();
int responseCode = con.getResponseCode();
}
The problem is that now I get connection time out when trying to execute OutputStream os = con.getOutputStream(); line. Also, I still have no idea how to redirect user when request is completed.
Any ideas?
Using the basic Java URL classes would require you to manually handle the details of HTTP protocol - it's better to use libraries like Apache Http Components, as they deal with the underlying protocols for you. Some examples including POST requests can be found on their website.
Given the original question, the Timeout is likely related to host not responding or your Java application being unable to connect to given URL (due to no proxy configuration for example).
If you want to redirect a request based on the answer, you need to check the response headers and http status - if the status is 302, then there should be a header called Location, which will contain the URL you should make another request to.
Before getting an OutputStream, also make sure to set the Content-Length header (and ideally the Content-Type header as well).
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).
I have an Android client making HTTPS request to a server. The firewall logs have entries for CONNECT request methods which are not desired.
When would the CONNECT request get sent out and how can I prevent it from being sent? I expect only a GET request. My understanding is that the call to openConnection() does not actually make a request and that the GET request would go on the call to getResponseMessage().
How can I disable the http client from attempting to establish a proxy tunnel?
Here is how I sent up my connection and make the call:
URL url = new URL("https://some.server.com");
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setConnectTimeout(CONNECT_TIMEOUT);
connection.setReadTimeout(REAT_TIMEOUT);
connection.setRequestProperty(ACCEPT_CHARSET, UTF8_CHARSET);
connection.setRequestProperty(CONTENT_TYPE_HEADER, contentType);
setCustomRequestProperties(connection);
connection.setRequestMethod("GET");
//create response
connection.getResponseMessage();
connection.getResponseCode();
connection.getContentType();
connection.getContent();
EDIT:
Here is the Firewall Log entry that I am trying to prevent:
CONNECT someURL.domain.com:443 HTTP/1.1
Host: someURL.domain.com
User-Agent: CustomUserAgent;1.0.0(Android 4.3;Nexus 4;T-Mobile)
Proxy-Connection: Keep-Alive
X-SSL-Secure: true
X-CS-Source-IP: 10.3.3.3
X-Forwarded-For: 10.3.3.3
I thought this was proxy related because of the "Proxy-Connection" header
The default for URLConnection is to pool the TCP (socket) connections. It seems that the "Proxy-Connection" header was misleading as that header can be misappropriated when "Connection" is really intended.
When I set the system property
System.setProperty("http.keepAlive", "false");
to disable the connection pool, the CONNECT method request entries went away.
There is a slight performance hit since Sockets need to be created for each request but the app does not make a significant number of requests so this is acceptable.
This only happens when you have an HTTP proxy configured. Possibly you have set the system properties http.proxyHost and http.proxyPort, or maybe Android has another way of configuring this.
I made an app. for Android which uses the C2DM service from Google. I
made a server simulator from some tutorials and it works fine. My
problem is, I tried to build a Java Servlet. From the Android device
it receives fine the message and saves the Registration ID, but when I
try to send a https POST request to the Google C2DM Server it always
gets a SocketTimeoutException : Timeout while fetching:
https://android.clients.google.com/c2dm/send.
I don't get why this is happening when the same works on the Android
device. Here is the code:
//The AuthToken from Google Client Login
String auth_key = TOKEN;
StringBuilder postDataBuilder = new StringBuilder();
//some parameters to pass, I've checked and it's correct, it's working
//with Fiddler
postDataBuilder.append(PARAM_REGISTRATION_ID).append("=").append(REGISTRATION_ID);
postDataBuilder.append("&").append(PARAM_COLLAPSE_KEY).append("=").append("0");
postDataBuilder.append("&").append("data.payload").append("=").append(URLEncoder.encode(message, UTF8));
byte[] postData = postDataBuilder.toString().getBytes(UTF8);
URL url = new URL("https://android.clients.google.com/c2dm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
conn.setRequestProperty("Content-Length",Integer.toString(postData.length));
conn.setRequestProperty("Authorization", "GoogleLogin auth="+auth_key);
OutputStream out = conn.getOutputStream();
out.write(postData);
out.close();
int responseCode = conn.getResponseCode();
//here comes the error processing, but I can't reach it, because of
//the exception.
if (responseCode == 401 || responseCode == 403) {
//....
}
Thanks for your help :).
The first obvious thing to check is - if you have thought of this I apologise - are you behind a proxy server e.g. a company firewall? If so a timeout is exactly the symptom I'd expect with the above code. (This catches me out all the time!)
With the latter half of your code (from the HttpURLConnection declaration on), unmodified, I see a timeout; on my system (behind a company firewall), with two changes I get a 200 OK back:
addition of a proxy object passed to the HttpUrlConnection factory as follows:
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("...", 8080));
HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);
accepting the C2DM server's certificate that wasn't trusted by my JVM. For test purposes I overrode the default hostname verifier and TrustManager as described in Trusting all certificates using HttpClient over HTTPS . For production you should look at a more secure solution.
Another thing I spotted; it doesn't seem to matter but http://code.google.com/android/c2dm/index.html#push says to post to https://android.apis.google.com/c2dm/send, not android.clients.google.com - just something to be aware of that might break in future.
I faced same problem and
I had tried :
URL url = new URL("http://android.apis.google.com/c2dm/send");
instead of :
URL url = new URL("https://android.apis.google.com/c2dm/send");
it worked for me.