/* DigiDoc4J library * * This software is released under either the GNU Library General Public * License (see LICENSE.LGPL). * * Note that the only valid version of the LGPL license as far as this * project is concerned is the original GNU Library General Public License * Version 2.1, February 1999 */ package org.digidoc4j.impl.bdoc; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.URI; import org.apache.commons.io.IOUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.BufferedHttpEntity; import org.apache.http.entity.InputStreamEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.util.EntityUtils; import org.digidoc4j.Configuration; import org.digidoc4j.SignatureProfile; import org.digidoc4j.exceptions.TechnicalException; import org.digidoc4j.utils.Helper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import eu.europa.esig.dss.DSSException; import eu.europa.esig.dss.client.http.commons.CommonsDataLoader; import eu.europa.esig.dss.client.http.commons.OCSPDataLoader; public class SkDataLoader extends CommonsDataLoader { private static final Logger logger = LoggerFactory.getLogger(SkDataLoader.class); public static final String TIMESTAMP_CONTENT_TYPE = "application/timestamp-query"; private String userAgent; public static SkDataLoader createOcspDataLoader(Configuration configuration) { SkDataLoader dataLoader = new SkDataLoader(configuration); dataLoader.setContentType(OCSPDataLoader.OCSP_CONTENT_TYPE); return dataLoader; } public static SkDataLoader createTimestampDataLoader(Configuration configuration) { SkDataLoader dataLoader = new SkDataLoader(configuration); dataLoader.setContentType(TIMESTAMP_CONTENT_TYPE); return dataLoader; } protected SkDataLoader(Configuration configuration) { DataLoaderDecorator.decorateWithProxySettings(this, configuration); DataLoaderDecorator.decarateWithSslSettings(this, configuration); } @Override public byte[] post(final String url, final byte[] content) throws DSSException { logger.info("Getting OCSP response from " + url); if(userAgent == null) { throw new TechnicalException("User Agent must be set for OCSP requests"); } HttpPost httpRequest = null; HttpResponse httpResponse = null; CloseableHttpClient client = null; try { final URI uri = URI.create(url.trim()); httpRequest = new HttpPost(uri); httpRequest.setHeader("User-Agent", userAgent); // The length for the InputStreamEntity is needed, because some receivers (on the other side) need this information. // To determine the length, we cannot read the content-stream up to the end and re-use it afterwards. // This is because, it may not be possible to reset the stream (= go to position 0). // So, the solution is to cache temporarily the complete content data (as we do not expect much here) in a byte-array. final ByteArrayInputStream bis = new ByteArrayInputStream(content); final HttpEntity httpEntity = new InputStreamEntity(bis, content.length); final HttpEntity requestEntity = new BufferedHttpEntity(httpEntity); httpRequest.setEntity(requestEntity); if (contentType != null) { httpRequest.setHeader(CONTENT_TYPE, contentType); } client = getHttpClient(url); httpResponse = getHttpResponse(client, httpRequest, url); final byte[] returnedBytes = readHttpResponse(url, httpResponse); return returnedBytes; } catch (IOException e) { throw new DSSException(e); } finally { try { if (httpRequest != null) { httpRequest.releaseConnection(); } if (httpResponse != null) { EntityUtils.consumeQuietly(httpResponse.getEntity()); } } finally { IOUtils.closeQuietly(client); } } } public void setUserAgentSignatureProfile(SignatureProfile signatureProfile) { userAgent = Helper.createBDocUserAgent(signatureProfile); } public String getUserAgent() { return userAgent; } }