Search code examples
apache-commons-httpclientapache-httpcomponents

Unable to POST data using TLS 1.2


I am trying to POST data to a server who is just using TLS1.2 When i am running the code i am getting the following response from server.

HttpResponseProxy{HTTP/1.1 415 Unsupported Media Type [Date: Wed, 07 Sep 2016 17:42:57 CST, Server: , Strict-Transport-Security: max-age=63072000; includeSubdomains; preload, Pragma: no-cache, Content-Length: 0, charset: ISO-8859-1, X-ORACLE-DMS-RID: 0, X-ORACLE-DMS-ECID: 343fa6c0-ed24-4003-ad58-342caf000404-00000383, Set-Cookie: JSESSIONID=1ZMIvt1NqrtWpHgHs4mMmYyTPUGTOQgrA9biCE3Dok5v0gDCPXu6!681252631; path=/; secure; HttpOnly;HttpOnly;Secure, Cache-Control: no-store, P3P: policyref="/w3c/p3p.xml", CP="WBP DSP NOR AMT ADM DOT URT POT NOT", Keep-Alive: timeout=5, max=250, Connection: Keep-Alive, Content-Type: text/xml, Content-Language: en] [Content-Type: text/xml,Content-Length: 0,Chunked: false]}

I am using the below code to post the data to server . I am using apache httpcomponents-client-4.5.2.

private static Registry<ConnectionSocketFactory> getRegistry() throws KeyManagementException, NoSuchAlgorithmException {
        SSLContext sslContext = SSLContexts.custom().build();
        SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,
                new String[]{"TLSv1.2"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
        return RegistryBuilder.<ConnectionSocketFactory>create()
                .register("https", sslConnectionSocketFactory)
                .register("https", sslConnectionSocketFactory)
                .build();
    }

    public static void main(String[] args) throws Exception
    {    
        PoolingHttpClientConnectionManager clientConnectionManager = new PoolingHttpClientConnectionManager(getRegistry());
        clientConnectionManager.setMaxTotal(100);
        clientConnectionManager.setDefaultMaxPerRoute(20);
        HttpClient client = HttpClients.custom().setConnectionManager(clientConnectionManager).build();
        HttpPost  request = new HttpPost("https://someserver.com/dataupload");
        File file = new File("C://Nible//code//_client//Request.xml");
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();        
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        builder.setContentType(ContentType.TEXT_XML);
        FileBody fileBody = new FileBody(file);
        builder.addPart("my_file", fileBody); 
        HttpEntity reqEntity = builder.build();
        request.setEntity(reqEntity);
        HttpResponse response = client.execute(request);
       System.out.println(response);
    }

Can you please tell me what wrong am i doing?

I tried using below code instead of MultipartEntityBuilder. I am still getting the same error.

EntityBuilder builder = EntityBuilder.create();
builder.setFile(file);
builder.setContentType(ContentType.TEXT_XML);

If i am sending the BLANK REQUEST to server then also i am getting the same error. Blank error means i am not putting any thing in request just

HttpPost  request = new HttpPost("https://someserver.com/dataupload");
 HttpResponse response = client.execute(request);

Solution

  • I suspect of these lines in your code:

    MultipartEntityBuilder builder = MultipartEntityBuilder.create();        
    builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
    builder.setContentType(ContentType.TEXT_XML);
    

    Multipart entities cannot be of content-type xml. They must be one of these types:

    • multipart/mixed
    • multipart/alternative
    • multipart/digest
    • multipart/parallel

    (See RFC 1341 7.2)

    I guess you should use one of these content-types for the multipart entity, and set text/xml as the content type of the single part:

    FileBody fileBody = new FileBody(file, ContentType.TEXT_XML);
    

    (Another issue is that I don't see necessary to send a multipart for just one file: You could leave out the MultipartEntityBuilder object and build directly a FileEntity.)