3

I am trying to post data to a server with java to this url:

https:www.stackoverflow.com

It's not updating the data.

But when I tried the same with curl it's updating the data with this url:

E:\curl ssl>curl -k -X POST -u"user:pass" "www.stackoverflow.com" 

Edit:

public void authenticatePostUrl() {

        HostnameVerifier hv = new HostnameVerifier() {

            @Override
            public boolean verify(String urlHostName, SSLSession session) {
                System.out.println("Warning: URL Host: " + urlHostName
                        + " vs. " + session.getPeerHost());
                return true;
            }
        };
        // Now you are telling the JRE to trust any https server.
        // If you know the URL that you are connecting to then this should
        // not be a problem
        try {
            trustAllHttpsCertificates();
        } catch (Exception e) {
            System.out.println("Trustall" + e.getStackTrace());
        }
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        try {
            URL url = new URL("www.stackoverflow.com");

            String credentials = "user" + ":" + "password";
            String encoding = Base64Converter.encode(credentials.getBytes("UTF-8"));
            HttpsURLConnection  uc = (HttpsURLConnection) url.openConnection();
            uc.setDoInput(true); 
            uc.setDoOutput(true);
            uc.setRequestProperty("Authorization", String.format("Basic %s", encoding));
            uc.setRequestMethod("POST");
            uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
            uc.setRequestProperty("Accept", "application/x-www-form-urlencoded; charset=utf-8");
            uc.getInputStream();
            System.out.println(uc.getContentType());
            InputStream content = (InputStream) uc.getInputStream();
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    content));
            String line;
            while ((line = in.readLine()) != null) {
                pw.println(line);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
            pw.println("Invalid URL");
        } catch (IOException e) {
            e.printStackTrace();
            pw.println("Error reading URL");
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(sw.toString());
    }


    public static void main(String[] args) {
        // TODO Auto-generated method stub
        CurlAuthentication au = new CurlAuthentication();
        au.authenticatePostUrl();
        au.authenticateUrl();
    }

    // Just add these two functions in your program

    public static class TempTrustedManager implements
            javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public boolean isServerTrusted(
                java.security.cert.X509Certificate[] certs) {
            return true;
        }

        public boolean isClientTrusted(
                java.security.cert.X509Certificate[] certs) {
            return true;
        }

        public void checkServerTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }

        public void checkClientTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }
    }

    private static void trustAllHttpsCertificates() throws Exception {

        // Create a trust manager that does not validate certificate chains:

        javax.net.ssl.TrustManager[] trustAllCerts =

        new javax.net.ssl.TrustManager[1];

        javax.net.ssl.TrustManager tm = new TempTrustedManager();

        trustAllCerts[0] = tm;

        javax.net.ssl.SSLContext sc =

        javax.net.ssl.SSLContext.getInstance("SSL");

        sc.init(null, trustAllCerts, null);

        javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(

        sc.getSocketFactory());

    }

Why is it not working in Java?

(For security reasons I changed the URLs above.)

halfer
  • 19,824
  • 17
  • 99
  • 186
developer
  • 9,116
  • 29
  • 91
  • 150

3 Answers3

4

So you are trying to POST do_not_disturb=no to the server? That's why I asked you in the comments to your previous question...

By appending ?do_not_disturb=No to the URL these parameters are automatically send as a GET request to the server, to send them as POST you have to put them in the request body with something like this:

String postData = "do_not_disturb=No";

OutputStreamWriter outputWriter = new OutputStreamWriter(uc.getOutputStream());
outputWriter.write(postData);
outputWriter.flush();
outputWriter.close();

Then your Accept-Header is probably wrong, as this tells the server in which format you are expecting to get some response data (the content). If you expect to get some XML from the server, this should read uc.setRequestProperty("Accept", "application/xml");.

UPDATE

By adding the verbose-flag (-v) to your curl command, i got the header it is sending:

POST /api/domains/amj.nms.mixnetworks.net/subscribers/9001/ HTTP/1.1
Authorization: Basic {URL_ENCODED_AUTHENTICATION_STRING}
User-Agent: curl/7.22.0 (i686-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
Host: 8.7.177.4
Accept: */*
Content-Length: 17
Content-Type: application/x-www-form-urlencoded

so please try changing your code like this:

uc.setRequestProperty("Authorization", String.format("Basic %s", encoding));
uc.setRequestMethod("POST");
uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
uc.setRequestProperty("Accept", "*/*");
uc.setRequestProperty("Content-Length", Integer.toString(postData.getBytes().length));

The user agent string should be of no interest, unless your server is doing really strange things.

If it's still not working, see if your variable encoding has the same value as the part after Basic in a verbose curl run.

Community
  • 1
  • 1
Jan Gerlinger
  • 7,361
  • 1
  • 44
  • 52
  • after changing code as per your suggestion, still its not saving – developer Jul 08 '12 at 13:32
  • 1
    Please use [Wireshark](http://www.wireshark.org/) and record one request using `curl` and one request using your Java application, then share them with us. – Jan Gerlinger Jul 08 '12 at 13:37
  • You can edit your question or you can upload it to http://pastebin.com/ or some similar service. – Jan Gerlinger Jul 08 '12 at 13:43
  • i saved the recorded data in the form of pcap, but pastebin supports it? Iam very new with WiresShark, please can you provide me some more deatils – developer Jul 08 '12 at 13:50
  • Unfortunately I missed that you are doing a HTTPS request and so Wireshark is of no use here. I added the `-v`-flag (verbose output) to your `curl` command and could get that request. I'll update my answer shortly. – Jan Gerlinger Jul 08 '12 at 14:15
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/13580/discussion-between-developer-and-jan-gerlinger) – developer Jul 08 '12 at 14:52
  • i have one more issue. Please can you help me, please join the chat by clicking the link – developer Jul 19 '12 at 10:30
  • Please write a new question, so other people can also have a look at your problem ;) – Jan Gerlinger Jul 19 '12 at 11:22
  • did you check the post which is posted? do you have any idea how to resolve – developer Jul 19 '12 at 14:03
1

In my case, curl works for a POST call, HttpUrlConnection in java won't work, returns 403 Forbidden saying I'm using anonymous login, yet the actual job this POST call is supposed to do was done. Very confusing at first. Then found that I need to disable url redirect (this is xtend code but you get the idea):

val conn = url.openConnection() as HttpURLConnection
conn.setInstanceFollowRedirects(false)
Emily
  • 306
  • 4
  • 8
0

There are a few options here. One is that you could add a Java class to run a bash script using Runtime().exec.

However, I debugged my Java connection and found that I was not using TLSv1.2

        System.setProperty("deployment.security.TLSv1.2", "true");
        System.setProperty("https.protocols", "TLSv1.2");
        System.setProperty("javax.net.debug", "ssl"); // "" or "ssl"

After I moved from Java 7 to Java 8, the Java command worked.

Often times curl works but Java does not or Java works and curl does not. I generally check the SSL configurations (using -v and -k for curl), try changing http versus https or look at the SSL cert installer here: https://confluence.atlassian.com/download/attachments/180292346/InstallCert.java (I modified this to install the cert during runtime)

Scott Izu
  • 2,229
  • 25
  • 12