HttpUrlConnection caching ip

  • Thread starter Christophe Darville
  • Start date
C

Christophe Darville

Daniel Hagen said:
Christophe said:
Sam,

Unfortunately, this is not DNS caching problem. When I ping (on the same
machine where my java application is running) the domain, the new ip address
is exact (after a few seconds, of course) but it is never exact in the java
application. The only way to use the new ip, is to restart the java
application.
So it is a DNS caching problem, but at the java level

Christophe

Just a thought (not considered very carefully, not tested and a very
ugly workaround):

Couldn't you use the API of your underlying OS via JNI to get the IP and
set the HTTP Host Header "manually" for the URLConnection?

Something like:

String formattedIp = someIpFormatMethod(
someNativeGetHostByNameMethod("a.domain") );

URL url = new URL("http://" + formattedIp);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty( "Host", "a.domain");

[...]

Daniel

Hi Daniel,

Your workaround works fine !

The connection.setRequestProperty("Host","...") command was the piece of
puzzle that was missing to me to solve the virtual hosting problem !

Thank you very much
Christophe
 
M

marcus

I am impressed -- I had no idea you could set the host after the
connection. very cool

Christophe said:
Christophe said:
Sam,

Unfortunately, this is not DNS caching problem. When I ping (on the same
machine where my java application is running) the domain, the new ip
address
is exact (after a few seconds, of course) but it is never exact in the
java
application. The only way to use the new ip, is to restart the java
application.
So it is a DNS caching problem, but at the java level

Christophe

Just a thought (not considered very carefully, not tested and a very
ugly workaround):

Couldn't you use the API of your underlying OS via JNI to get the IP and
set the HTTP Host Header "manually" for the URLConnection?

Something like:

String formattedIp = someIpFormatMethod(
someNativeGetHostByNameMethod("a.domain") );

URL url = new URL("http://" + formattedIp);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty( "Host", "a.domain");

[...]

Daniel


Hi Daniel,

Your workaround works fine !

The connection.setRequestProperty("Host","...") command was the piece of
puzzle that was missing to me to solve the virtual hosting problem !

Thank you very much
Christophe
 
C

Christophe Darville

in fact between the openConnection() and connect()

marcus said:
I am impressed -- I had no idea you could set the host after the
connection. very cool

Christophe said:
Christophe Darville wrote:

Sam,

Unfortunately, this is not DNS caching problem. When I ping (on the same
machine where my java application is running) the domain, the new ip
address

is exact (after a few seconds, of course) but it is never exact in the
java

application. The only way to use the new ip, is to restart the java
application.
So it is a DNS caching problem, but at the java level

Christophe

Just a thought (not considered very carefully, not tested and a very
ugly workaround):

Couldn't you use the API of your underlying OS via JNI to get the IP and
set the HTTP Host Header "manually" for the URLConnection?

Something like:

String formattedIp = someIpFormatMethod(
someNativeGetHostByNameMethod("a.domain") );

URL url = new URL("http://" + formattedIp);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty( "Host", "a.domain");

[...]

Daniel


Hi Daniel,

Your workaround works fine !

The connection.setRequestProperty("Host","...") command was the piece of
puzzle that was missing to me to solve the virtual hosting problem !

Thank you very much
Christophe
 
Joined
Feb 14, 2008
Messages
2
Reaction score
0
JVM DNS caching

This thread was very helpful.

The following link on the http client forums helped me alot: -
http://mail-archives.apache.org/mod_mbox/hc-httpclient-users/200506.mbox/<[email protected]>

Essentially, one can disable Sun's JVM level dns caching with the help of: -

Code:
Security.setProperty("networkaddress.cache.ttl", "0");
Security.setProperty("networkaddress.cache.negative.ttl", "0");

Other networking properties can be found here: -
http://java.sun.com/j2se/1.5.0/docs/guide/net/properties.html

I have tested dns caching properties in the following way: -
Code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.Inet4Address;
import java.net.MalformedURLException;
import java.net.PasswordAuthentication;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.Security;
import java.util.concurrent.TimeUnit;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;

public class DNSCachingTest {

	public static final String host = "xyz.dyndns.org";

	public static final int port = 8086;

	public static final String auth[] = { "username", "password" };

	public static void main(String[] args) {

		// System.getProperties().list(System.out);

		System.out.println("networkaddress.cache.ttl - "
				+ Security.getProperty("networkaddress.cache.ttl"));
		System.out.println("networkaddress.cache.negative.ttl - "
				+ Security.getProperty("networkaddress.cache.negative.ttl"));

		Security.setProperty("networkaddress.cache.ttl", "0");
		Security.setProperty("networkaddress.cache.negative.ttl", "0");

		boolean flag = true;
		while (flag) {

			printIp();
			System.out.println("---------");
			checkUrlConnection();
			System.out.println("---------");
			checkHttpClient();
			System.out.println("---------");

			try {

				TimeUnit.SECONDS.sleep(60);
			} catch (InterruptedException e) {

				e.printStackTrace();
			}

			// flag = false;
		}
	}

	public static void printIp() {

		try {

			System.out.println("Address: " + Inet4Address.getByName(host));
		} catch (UnknownHostException e) {

			e.printStackTrace();
		}
	}

	public static void checkUrlConnection() {

		URL url;
		try {
			url = new URL("http://" + host + ":" + port + "/");

			if (auth != null) {
				
				Authenticator.setDefault(new Authenticator() {

					protected PasswordAuthentication getPasswordAuthentication() {
						return new PasswordAuthentication(auth[0], auth[1]
								.toCharArray());
					}
				});
			}

			HttpURLConnection con = (HttpURLConnection) url.openConnection();
			con.setConnectTimeout(10000);
			con.setReadTimeout(10000);

			int responseCode = con.getResponseCode();

			if (responseCode == HttpURLConnection.HTTP_OK) {

				BufferedReader br = new BufferedReader(new InputStreamReader(
						con.getInputStream()));

				while (br.readLine() != null)
					;

				System.out.println("checkUrlConnection: ok");
			} else {

				System.out.println("Response code (checkUrlConnection): "
						+ responseCode);
			}
		} catch (MalformedURLException e) {

			e.printStackTrace();
		} catch (IOException e) {

			e.printStackTrace();
		}
	}

	public static void checkHttpClient() {

		try {

			HttpClient httpClient = new HttpClient();
			httpClient.getHttpConnectionManager().getParams()
					.setConnectionTimeout(10000);
			httpClient.getHttpConnectionManager().getParams()
					.setConnectionTimeout(10000);
			if (auth != null) {

				httpClient.getState().setCredentials(new AuthScope(host, port),
						new UsernamePasswordCredentials(auth[0], auth[1]));
			}

			GetMethod method = new GetMethod("http://" + host + ":" + port
					+ "/");
			int responseCode;

			responseCode = httpClient.executeMethod(method);
			if (responseCode == HttpURLConnection.HTTP_OK) {

				BufferedReader br = new BufferedReader(new InputStreamReader(
						method.getResponseBodyAsStream()));

				while (br.readLine() != null)
					;

				System.out.println("checkHttpClient: ok");
			} else {

				System.out.println("Response code (checkHttpClient): "
						+ responseCode);
			}
		} catch (HttpException e) {

			e.printStackTrace();
		} catch (IOException e) {

			e.printStackTrace();
		}
	}

}

Resolution for xyz.dyndns.org can be switched between an existent and a non-existent IP address using the services provided at dyndns.com. Depending on how you switch, success messages and exceptions should get printed alternatively.

Following is another helpful command in context of this experiment: -
Code:
nslookup xyz.dyndns.org

HTH.
Santosh.
 
Joined
Feb 14, 2008
Messages
2
Reaction score
0
JVM DNS caching with JBoss

Another useful observation I encountered was that

Code:
Security.setProperty("networkaddress.cache.ttl", "0");
Security.setProperty("networkaddress.cache.negative.ttl", "0");

does not work in JBoss. One has to modify these properties in the JAVA_HOME/lib/security/java.security files for the settings to take effect.

Regards
Santosh.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,219
Latest member
KristieKoh

Latest Threads

Top