Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problem with HttpsURLConnection and post (getOutputStream)

Status
Not open for further replies.

siberian

Programmer
Sep 27, 2003
1,295
US
I am trying to use the HttpsURLConnection as described by sedj in previous posts in the archives and its just not working. The urlConn variable is properly instantiated but when I try to grab the getOutputStream so I can post my XML to it the code exits without even an exception.

Anyone have any ideas? Works fine non-ssl. This code snippet below is the WORKING non-ssl version, the commented lines are what I am uncommenting (and commenting out the non-ssl line) to switch to SSL and have my failure.

Thanks!
Code:
String URL = "[URL unfurl="true"]http://www.site.com");[/URL]
//String URL = "[URL unfurl="true"]https://www.site.com/";[/URL]

URL url = new URL (URL);
			
URLConnection urlConn = url.openConnection();
//HttpsURLConnection urlConn= null;

try{
	//urlConn = (HttpsURLConnection)url.openConnection();
	urlConn = url.openConnection();
} catch(Exception e){
	System.err.println("ERROR:"+e.getMessage());	
}
urlConn.setDoInput (true);
urlConn.setDoOutput (true);
urlConn.setUseCaches (false);
urlConn.setRequestProperty("Content-Type", "application/x-[URL unfurl="true"]www-form-urlencoded");[/URL]
			
printout = new DataOutputStream (urlConn.getOutputStream ());
 
siberian,

I've tested the below code - there are two classes - the first one for sending a file, and the second one as a test listener if your desired URL is still not working ...

Run it like :

java SendFile /usr/local/test/test.txt

Code:
import java.io.*;
import java.net.*;
import javax.net.ssl.*;
public class SendFile {

	public static void main(String[] args) throws Exception {

		HttpsURLConnection c = (HttpsURLConnection)(new URL(args[0]).openConnection());
		//HttpURLConnection c = (HttpURLConnection)(new URL(args[0]).openConnection());

		c.setDoOutput(true);
		c.setDoInput(true);
		c.setRequestProperty("Connection","Keep-Alive");
		c.setRequestProperty("Proxy-Connection","Keep-Alive");
		c.setRequestProperty("Content-Type","text/xml");
		c.setRequestMethod("POST");
		c.setUseCaches(false);
		c.connect();

		OutputStream out = c.getOutputStream();

		FileInputStream fis = new FileInputStream(args[1]);
		byte buf[] = new byte[(int)new File(args[1]).length()];
		fis.read(buf);

		out.write(buf);
		out.flush();
		out.close();

		System.out.println("WRITTEN AND FLUSHED");
		BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));

		int b = 0;
		while((b = br.read()) != -1) {
			System.err.print((char)b);
		}

		br.close();

		c.disconnect();
		System.out.println("\nCaptured response.");

	}
}

and the listener for testing :

Code:
public class ListenerServlet extends HttpServlet {

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.err.println("INCOMING REQUEST !!!");
		response.setContentType("text/xml");

		// Get the IO streams that we'll use for reading the xml request
		// and writing the xml response.
		InputStream in = request.getInputStream();
		OutputStream out = response.getOutputStream();


		BufferedReader br = new BufferedReader(new InputStreamReader(in));
		String line = "";
		while ((line = br.readLine()) != null) {
			System.err.println(line);
		}

		out.write("Thanks, got the request ...".getBytes());
		out.flush();

		br.close();
		in.close();
		out.close();


	}

}

--------------------------------------------------
Free Database Connection Pooling Software
 
Still no luck, it bombs on the connect or on the OutputStream. The site is known good, I connect to it with other clients in other languages, its just the java client that is not being happy.

Thanks Sedj, I think your solution is correct, there must be something wrong in how I am making my connection.

 
NOTE: I did not try the listener class you put up, I think that would work fine, most likely there is something on my apache server that is being a pain.
 
Hmmmm.... I've tried this at work and on my network at home, so it must be your config or something - maybe check your firewall / proxys etc ?

--------------------------------------------------
Free Database Connection Pooling Software
 
Not sure where its failing, my https server is known good. I will try the listener later today and see what happens and report back.

Tx Sedj

 
Question, on the listener I don't see any ssl handling/certificate loading etc.

Is the listener just handling a standard request or an ssl request?
 
As far as listening resources are concerned (be it servlets/JSP/html pages etc) there is no difference between http and https. The webserver (apache or tomcat or IIS etc) and the browser handle the SSL protocol encryption - not the listener.

--------------------------------------------------
Free Database Connection Pooling Software
 
Duh on me, yes.

See, thats what I get for posting that early in the morning :)
 
Ok update here.

Even on a GET I now have this error :

Code:
sun.security.validator.ValidatorException: No trusted certificate found


If i turn off https it retrieves fine. This is a known good SSL system in production.

Here is my code

Code:
			HttpsURLConnection c = (HttpsURLConnection)(new URL("[URL unfurl="true"]https://www.printme.com/").openConnection());[/URL]
	
			c.setDoOutput(true);
			c.setDoInput(true);
			c.setRequestProperty("Connection","Keep-Alive");
			c.setRequestProperty("Proxy-Connection","Keep-Alive");
			c.setRequestProperty("Content-Type","text/xml");

			c.setRequestMethod("GET");
			c.setUseCaches(false);
			c.connect();




			System.out.println("WRITTEN AND FLUSHED");
			BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));

			int b = 0;
			while((b = br.read()) != -1) {
				System.err.print((char)b);
			}

			br.close();

			c.disconnect();
			System.out.println("\nCaptured response.");
		} catch(Exception e){
			System.out.println("URL ERROR FORM:"+e.getMessage());
		}

Any ideas sedj?
 
Looks like that is because your SSL certificated is not signed by a tursted root listed in your java keystore. You will need to import your SSL certificate into the Java keystore, which normally locate at <JAVA_HOME>/jre/lib/cacerts

to import a certificate:

keytool -import -trustcacerts -keystore <JAVA_HOME>/jre/lib/cacerts -alias <alise of the certificate> -file <your X.509 certificate file>

for details:
 
Interesting, I will try that. I've build https clients in other languages and never had to import the keys like this, I hope i can roll it into my distro so that each install doesn't have to deal with it.

Tx for the info.
 
Wait, I dont have the certificate. So I have to download the certificate from the website that I dont control in order to bring it locally into my java install?

I am not trying to serve SSL, just connect to someone elses server.

Seems odd, I am missing something here. I've done SSL in C and Perl and never had to import the foreign cert and/or key...

I am not trying to use SSL for authentication, just encryption. Is this just a nuance of the ssl implementation within Java?

Tx

 
By default, keystore that comes with Java 1.4.2 only have the following trusted root certificates issued by the most world known CA:

thawtepersonalfreemailca, 12-Feb-1999, trustedCertEntry,
baltimorecodesigningca, 10-May-2002, trustedCertEntry,
thawtepersonalbasicca, 12-Feb-1999, trustedCertEntry,
gtecybertrustglobalca, 10-May-2002, trustedCertEntry,
verisignclass3ca, 29-Jun-1998, trustedCertEntry,
thawteserverca, 12-Feb-1999, trustedCertEntry,
thawtepersonalpremiumca, 12-Feb-1999, trustedCertEntry,
verisignclass4ca, 29-Jun-1998, trustedCertEntry,
baltimorecybertrustca, 10-May-2002, trustedCertEntry,
verisignclass1ca, 29-Jun-1998, trustedCertEntry,
verisignserverca, 29-Jun-1998, trustedCertEntry,
thawtepremiumserverca, 12-Feb-1999, trustedCertEntry,
gtecybertrustca, 10-May-2002, trustedCertEntry,
gtecybertrust5ca, 10-May-2002, trustedCertEntry,
verisignclass2ca, 29-Jun-1998, trustedCertEntry,

Where as Internet Explorer has registered with more then 100 trusted root certificates (to see the list in IE, Internet Option -> Content -> Certificates (select Trusted Root Certificate Tab).

IE has lots more trusted root certificates, this is why IE has no problem in accessing the SSL site but not in Java.

If you know what trusted root CA of SSL certificate is, you can then export the relavent certificate from IE and import that into Java keystore.

If you don't know what the Trusted root CA for the SSL certificate, try, in IE, enable "Check for server certificate revocation" under Internet Options --> Advance. then access the SSL site via IE. IE should then show you the SSL certificate, which you can then identify the root CA.
 
Thanks byam, final question :)

Do i have to use the keystore app to get the key into the store or can I just copy it to a directory?

I'm building an automated distribution and it would be a lot easier to have the installer copy a file then attempt to run command line apps and all that can go wrong there.

Tx for the info.
 
I *think* you can just copy it into it - as long as its the same format as keystore would generate ...

--------------------------------------------------
Free Database Connection Pooling Software
 
After you imported the root certificate into the keystore, you can just copy the keystore file into your application.

However, you will need to add the following system property to your application; otherwise it will still uses the default keystore in JAVA_HOME/lib/jre/sercurity.

-Djavax.net.ssl.trustStore=<yourKeystore>

where <yourKeystore> = file path to the keystore that contains the certificate.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top