tags:

views:

697

answers:

2

Hi guys (and girls),

I have a problem POSTing data via HTTPS in Java. The server response is the same whether or not I send 'query'. Maybe someone can point out what the problem is...

Thanks!

Main class:

package bind;

public class Main {

    public static final String urlString = "https://www.sms.ethz.ch/cgi-bin/sms/send.pl";

    public static void main(String[] args) {

 Message msg = new Message("Alles klar?");
 URL url = new URL(urlString);

 String[][] values = new String[3][2];
 values[0][0] = "action";
 values[0][1] = "listoriginators";
 values[1][0] = "username";
 values[1][1] = "xxxxxx";
 values[2][0] = "password";
 values[2][1] = "xxxxxx";


 Query query = new Query(values);
 System.out.println("Query: " + query.getQuery());

 Request request = new Request(url.getURL(), query.getQuery());


    }
}

Request class:

package bind;

public class Request {
    static private int ic = 0;
    private URL url;

    protected Request(java.net.URL URL, String query){
 ic++;
 if(CONSTANTS.SHOW_LOGS) { System.out.println("log: new instance of 'Message'"); }

 // connect
 try {

     System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
     java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

     javax.net.ssl.HttpsURLConnection connection = (javax.net.ssl.HttpsURLConnection) URL.openConnection();
     connection.setDoInput(true);
     connection.setDoOutput(true);
     connection.setRequestMethod("POST");
     connection.setFollowRedirects(true);

     connection.setRequestProperty("Content-Length", String.valueOf(query.length()));
     connection.setRequestProperty("Content-Type", "application/x-www- form-urlencoded");
     connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");

     java.io.DataOutputStream output = new java.io.DataOutputStream(connection.getOutputStream());

     output.writeBytes(query); // <<-- NOTHING CHANGES IF I COMMENT THIS OUT OR NOT !!??!?!

     System.out.println("log: response code: " + connection.getResponseCode());
     System.out.println("log: response message: " + connection.getResponseMessage());

     java.io.DataInputStream input = new java.io.DataInputStream(connection.getInputStream());
     for(int i = input.read(); i != -1; i = input.read()) {
  System.out.print((char)i);
     }
     System.out.print("\n");
     input.close();

 } catch(java.io.IOException e) {
     if(CONSTANTS.SHOW_LOGS) {
  System.out.println("error: unable to connect");
  System.out.println(e);
  e.printStackTrace();
     }
 }

    }
}

URL Class:

public class URL {
    static private int ic = 0;
    private String URLString;
    private java.net.URL url;

    protected URL(String a_url){
 ic++;

 if(CONSTANTS.SHOW_LOGS) { System.out.println("log: new instance of 'URL'"); }

 setURLString(a_url);
 createURL();
    }

    private void setURLString(String a_url) {
 URLString = a_url;
    }

    private void createURL() {
 try {
     url = new java.net.URL(URLString);
 } catch(java.net.MalformedURLException e) {
     System.out.println("error: invalid URL");
     System.out.println(e);
     e.printStackTrace();
 }
    }

    private void showURL() {
 System.out.println("URL: " + url.getHost() + url.getPath());
    }

    public java.net.URL getURL() {
 return url;
    }

}

PS: mostly from here: http://www.java-samples.com/java/POST-toHTTPS-url-free-java-sample-program.htm

+1  A: 

Urk. Could you possibly be persuaded to use the Apache commons http client instead?

This link is more direct.

It's a lot less work than debugging this code.

bmargulies
Thanks for the tip. I will look into that. Thanks!
ostollmann
Just wanted to thank you for the tip about Apache commons libs, they are amazing! Thanks!
ostollmann
A: 

You forgot to flush() or, better, close() the stream afterwards (which already does an implicit flush). Flushing is necessary because the data may be internally buffered to a certain length and flushing forces the entire buffer to be actually written to the output.

So, change

 output.writeBytes(query);

to

 output.writeBytes(query);
 output.close();

Actually, the normal idiom is to close streams in the finally block of the try block as you've acquired them, so that you can guarantee that they get closed whenever an IOException occurs during the write. Closing is important because it frees up system resources.

Stream stream = null; // Can be InputStream, OutputStream, Reader or Writer.
try {
    stream = new SomeStream();
    // ...
} finally {
    if (stream != null) try { stream.close(); } catch (IOException logOrIgnore) {} // You can if necessary bake an utility method taking Closeable or take a look for commons IO.
}

Also see the Sun Java IO tutorial for more basic lessons and guidelines.

BalusC
Thanks for the answer, this doesn't change anything though. I had actually tried that before (don't know why I removed it again). I might try the Apache Commons HTTP Client bmargulies mentioned above.
ostollmann
You did call `output.close()` **before** calling `connection.getInputStream()`, did you?
BalusC
Sorry for the late response, I have been using the Apache libs mentioned by bmargulies so I sort of dropped this issue. But I did add it on the line right after output.writeBytes(query), still didn't work.I think it may just have something to do with ssl... Anyway I have moved to the Apache libs and they work great.Thanks for the help :-)
ostollmann
No problem. Don't forget to mark his answer as accepted, else this question will remain unanswered.
BalusC