POST request with unbuffered RestTemplate and sslcontext customization

29 Views Asked by At

Using Spring RestTemplate I try to send a large stream to a server. Than I receive getBody not supported error. If I do it with SimpleClientHttpRequestFactory it works normally, but I can't make my own sslcontext, that I need. What am I doing wrong and how can I fix it?

I use spring boot 2.6.4, if it's important.

Code samples:

RestTemplate creation:

public RestTemplate configureSSLRestTemplate(final String keystoreLocation,
                                                 final String keystorePassword,
                                                 final String keyPassword,
                                                 final int requestTimeout) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, KeyManagementException {
        final HttpClient httpClient = httpClientConfiguration(keystoreLocation, keystorePassword, keyPassword);

        final HttpComponentsClientHttpRequestFactory customRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);

            customRequestFactory.setBufferRequestBody(false);
            customRequestFactory.setConnectTimeout(requestTimeout);
            customRequestFactory.setReadTimeout(requestTimeout);
            customRequestFactory.setConnectionRequestTimeout(requestTimeout);
        

        return new RestTemplate(customRequestFactory);

    }

    private CloseableHttpClient httpClientConfiguration(final String keystoreLocation,
                                                        final String keystorePassword,
                                                        final String keyPassword) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, KeyManagementException {
        final TrustManager[] trustCheckedCertificates = new TrustManager[]{new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }

            public void checkClientTrusted(final X509Certificate[] certs, String authType) {
            }

            public void checkServerTrusted(final X509Certificate[] certs, String authType) throws CertificateException {

                if (!certificateValidatorService.validateCertificate(certs[0], false)) {
                    throw new CertificateException("Server certificate is wrong"); //TODO
                }
            }
        }};

        final SSLContext sslContext = configureSSLContext(keystoreLocation, keystorePassword, keyPassword, trustCheckedCertificates);

        return HttpClients.custom().setSSLContext(sslContext)
                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).build();
    }

    public SSLContext configureSSLContext(final String keystoreLocation,
                                          final String keystorePassword,
                                          final String keyPassword,
                                          final TrustManager[] trustCheckedCertificates) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, KeyManagementException {
        final KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
        try (InputStream in = new FileInputStream(keystoreLocation)) {
            keystore.load(in, keystorePassword.toCharArray());
        }
        final KeyManagerFactory keyManagerFactory =
                KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keystore, keyPassword.toCharArray());

        final SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(keyManagerFactory.getKeyManagers(), trustCheckedCertificates, new SecureRandom());

        return sslContext;
    }

Message sending:

final RequestCallback requestCallback = new RequestCallback() {
                @Override
                public void doWithRequest(ClientHttpRequest clientHttpRequest) throws IOException {
                    IOUtils.copy(request.getInputStream(), clientHttpRequest.getBody());

                }
            };

            ResponseEntity<String> responseEntity;

                responseEntity = restTemplate.execute(clientApi, HttpMethod.POST,
                        requestCallback, restTemplate.responseEntityExtractor(String.class));
}
0

There are 0 best solutions below