Search in sources :

Example 1 with HttpException

use of org.openecard.apache.http.HttpException in project open-ecard by ecsec.

the class ResourceContext method getStreamInt.

private static ResourceContext getStreamInt(URL url, CertificateValidator v, List<Pair<URL, TlsServerCertificate>> serverCerts, int maxRedirects) throws IOException, ResourceException, ValidationError, InvalidAddressException {
    try {
        DynamicContext dynCtx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
        CookieManager cManager = (CookieManager) dynCtx.get(TR03112Keys.COOKIE_MANAGER);
        LOG.info("Trying to load resource from: {}", url);
        if (maxRedirects == 0) {
            throw new ResourceException(MAX_REDIRECTS);
        }
        maxRedirects--;
        String protocol = url.getProtocol();
        String hostname = url.getHost();
        int port = url.getPort();
        if (port == -1) {
            port = url.getDefaultPort();
        }
        String resource = url.getFile();
        resource = resource.isEmpty() ? "/" : resource;
        if (!"https".equals(protocol)) {
            throw new InvalidAddressException(INVALID_ADDRESS);
        }
        // open a TLS connection, retrieve the server certificate and save it
        TlsClientProtocol h;
        DynamicAuthentication tlsAuth = new DynamicAuthentication(hostname);
        // add PKIX validator if not doin nPA auth
        if (isPKIXVerify()) {
            tlsAuth.addCertificateVerifier(new JavaSecVerifier());
        }
        // FIXME: validate certificate chain as soon as a usable solution exists for the trust problem
        // tlsAuth.setCertificateVerifier(new JavaSecVerifier());
        TlsCrypto crypto = new BcTlsCrypto(ReusableSecureRandom.getInstance());
        ClientCertTlsClient tlsClient = new ClientCertDefaultTlsClient(crypto, hostname, true);
        tlsClient.setAuthentication(tlsAuth);
        // connect tls client
        tlsClient.setClientVersion(ProtocolVersion.TLSv12);
        Socket socket = ProxySettings.getDefault().getSocket(protocol, hostname, port);
        h = new TlsClientProtocol(socket.getInputStream(), socket.getOutputStream());
        LOG.debug("Performing TLS handshake.");
        h.connect(tlsClient);
        LOG.debug("TLS handshake performed.");
        serverCerts.add(new Pair<>(url, tlsAuth.getServerCertificate()));
        // check result
        CertificateValidator.VerifierResult verifyResult = v.validate(url, tlsAuth.getServerCertificate());
        if (verifyResult == CertificateValidator.VerifierResult.FINISH) {
            List<Pair<URL, TlsServerCertificate>> pairs = Collections.unmodifiableList(serverCerts);
            return new ResourceContext(tlsClient, h, pairs);
        }
        StreamHttpClientConnection conn = new StreamHttpClientConnection(h.getInputStream(), h.getOutputStream());
        HttpContext ctx = new BasicHttpContext();
        HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
        BasicHttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest("GET", resource);
        HttpRequestHelper.setDefaultHeader(req, url);
        req.setHeader("Accept", "text/xml, */*;q=0.8");
        req.setHeader("Accept-Charset", "utf-8, *;q=0.8");
        setCookieHeader(req, cManager, url);
        HttpUtils.dumpHttpRequest(LOG, req);
        LOG.debug("Sending HTTP request.");
        HttpResponse response = httpexecutor.execute(req, conn, ctx);
        storeCookies(response, cManager, url);
        LOG.debug("HTTP response received.");
        StatusLine status = response.getStatusLine();
        int statusCode = status.getStatusCode();
        String reason = status.getReasonPhrase();
        HttpUtils.dumpHttpResponse(LOG, response, null);
        HttpEntity entity = null;
        boolean finished = false;
        if (TR03112Utils.isRedirectStatusCode(statusCode)) {
            Header[] headers = response.getHeaders("Location");
            if (headers.length > 0) {
                String uri = headers[0].getValue();
                url = new URL(uri);
            } else {
                // FIXME: refactor exception handling
                throw new ResourceException(MISSING_LOCATION_HEADER);
            }
        } else if (statusCode >= 400) {
            // according to the HTTP RFC, codes greater than 400 signal errors
            LOG.debug("Received a result code {} '{}' from server.", statusCode, reason);
            throw new InvalidResultStatus(LANG.translationForKey(INVALID_RESULT_STATUS, statusCode, reason));
        } else {
            if (verifyResult == CertificateValidator.VerifierResult.CONTINUE) {
                throw new InvalidAddressException(INVALID_REFRESH_ADDRESS_NOSOP);
            } else {
                conn.receiveResponseEntity(response);
                entity = response.getEntity();
                finished = true;
            }
        }
        // follow next redirect or finish?
        if (finished) {
            assert (entity != null);
            ResourceContext result = new ResourceContext(tlsClient, h, serverCerts);
            LimitedInputStream is = new LimitedInputStream(entity.getContent());
            result.setStream(is);
            return result;
        } else {
            h.close();
            return getStreamInt(url, v, serverCerts, maxRedirects);
        }
    } catch (URISyntaxException ex) {
        throw new IOException(LANG.translationForKey(FAILED_PROXY), ex);
    } catch (HttpException ex) {
        // don't translate this, it is handled in the ActivationAction
        throw new IOException("Invalid HTTP message received.", ex);
    }
}
Also used : HttpRequestExecutor(org.openecard.apache.http.protocol.HttpRequestExecutor) HttpEntity(org.openecard.apache.http.HttpEntity) BasicHttpContext(org.openecard.apache.http.protocol.BasicHttpContext) LimitedInputStream(org.openecard.common.io.LimitedInputStream) TlsClientProtocol(org.openecard.bouncycastle.tls.TlsClientProtocol) URISyntaxException(java.net.URISyntaxException) ClientCertTlsClient(org.openecard.crypto.tls.ClientCertTlsClient) StreamHttpClientConnection(org.openecard.transport.httpcore.StreamHttpClientConnection) URL(java.net.URL) TlsCrypto(org.openecard.bouncycastle.tls.crypto.TlsCrypto) BcTlsCrypto(org.openecard.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto) HttpException(org.openecard.apache.http.HttpException) CookieManager(org.openecard.transport.httpcore.cookies.CookieManager) JavaSecVerifier(org.openecard.crypto.tls.verify.JavaSecVerifier) InvalidResultStatus(org.openecard.transport.httpcore.InvalidResultStatus) Pair(org.openecard.common.util.Pair) BasicHttpEntityEnclosingRequest(org.openecard.apache.http.message.BasicHttpEntityEnclosingRequest) BasicHttpContext(org.openecard.apache.http.protocol.BasicHttpContext) HttpContext(org.openecard.apache.http.protocol.HttpContext) ClientCertDefaultTlsClient(org.openecard.crypto.tls.ClientCertDefaultTlsClient) HttpResponse(org.openecard.apache.http.HttpResponse) BcTlsCrypto(org.openecard.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto) IOException(java.io.IOException) StatusLine(org.openecard.apache.http.StatusLine) Header(org.openecard.apache.http.Header) DynamicAuthentication(org.openecard.crypto.tls.auth.DynamicAuthentication) InvalidAddressException(org.openecard.binding.tctoken.ex.InvalidAddressException) Socket(java.net.Socket) DynamicContext(org.openecard.common.DynamicContext)

Example 2 with HttpException

use of org.openecard.apache.http.HttpException in project open-ecard by ecsec.

the class PAOS method sendStartPAOS.

/**
 * Sends start PAOS and answers all successor messages to the server associated with this instance.
 * Messages are exchanged until the server replies with a {@code StartPAOSResponse} message.
 *
 * @param message The StartPAOS message which is sent in the first message.
 * @return The {@code StartPAOSResponse} message from the server.
 * @throws DispatcherException In case there errors with the message conversion or the dispatcher.
 * @throws PAOSException In case there were errors in the transport layer.
 * @throws PAOSConnectionException
 */
public StartPAOSResponse sendStartPAOS(StartPAOS message) throws DispatcherException, PAOSException, PAOSConnectionException {
    Object msg = message;
    StreamHttpClientConnection conn = null;
    HttpContext ctx = new BasicHttpContext();
    HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
    DefaultConnectionReuseStrategy reuse = new DefaultConnectionReuseStrategy();
    boolean connectionDropped = false;
    ResponseBaseType lastResponse = null;
    try {
        // loop and send makes a computer happy
        while (true) {
            // set up connection to PAOS endpoint
            // if this one fails we may not continue
            conn = openHttpStream();
            boolean isReusable;
            // send as long as connection is valid
            try {
                do {
                    // save the last message we sent to the eID-Server.
                    if (msg instanceof ResponseBaseType) {
                        lastResponse = (ResponseBaseType) msg;
                    }
                    // prepare request
                    String resource = tlsHandler.getResource();
                    BasicHttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest("POST", resource);
                    HttpRequestHelper.setDefaultHeader(req, tlsHandler.getServerAddress());
                    req.setHeader(HEADER_KEY_PAOS, headerValuePaos);
                    req.setHeader("Accept", "text/xml, application/xml, application/vnd.paos+xml");
                    ContentType reqContentType = ContentType.create("application/vnd.paos+xml", "UTF-8");
                    HttpUtils.dumpHttpRequest(LOG, "before adding content", req);
                    String reqMsgStr = createPAOSResponse(msg);
                    StringEntity reqMsg = new StringEntity(reqMsgStr, reqContentType);
                    req.setEntity(reqMsg);
                    req.setHeader(reqMsg.getContentType());
                    req.setHeader("Content-Length", Long.toString(reqMsg.getContentLength()));
                    // send request and receive response
                    LOG.debug("Sending HTTP request.");
                    HttpResponse response = httpexecutor.execute(req, conn, ctx);
                    LOG.debug("HTTP response received.");
                    int statusCode = response.getStatusLine().getStatusCode();
                    try {
                        checkHTTPStatusCode(statusCode);
                    } catch (PAOSConnectionException ex) {
                        // response with error. So check the status of our last response to the eID-Server
                        if (lastResponse != null) {
                            WSHelper.checkResult(lastResponse);
                        }
                        throw ex;
                    }
                    conn.receiveResponseEntity(response);
                    HttpEntity entity = response.getEntity();
                    byte[] entityData = FileUtils.toByteArray(entity.getContent());
                    HttpUtils.dumpHttpResponse(LOG, response, entityData);
                    // consume entity
                    Object requestObj = processPAOSRequest(new ByteArrayInputStream(entityData));
                    // break when message is startpaosresponse
                    if (requestObj instanceof StartPAOSResponse) {
                        StartPAOSResponse startPAOSResponse = (StartPAOSResponse) requestObj;
                        // an ok.
                        if (lastResponse != null) {
                            WSHelper.checkResult(lastResponse);
                        }
                        WSHelper.checkResult(startPAOSResponse);
                        return startPAOSResponse;
                    }
                    // send via dispatcher
                    msg = dispatcher.deliver(requestObj);
                    // check if connection can be used one more time
                    isReusable = reuse.keepAlive(response, ctx);
                    connectionDropped = false;
                } while (isReusable);
            } catch (IOException ex) {
                if (!connectionDropped) {
                    connectionDropped = true;
                    LOG.warn("PAOS server closed the connection. Trying to connect again.");
                } else {
                    String errMsg = "Error in the link to the PAOS server.";
                    LOG.error(errMsg);
                    throw new PAOSException(DELIVERY_FAILED, ex);
                }
            }
        }
    } catch (HttpException ex) {
        throw new PAOSException(DELIVERY_FAILED, ex);
    } catch (SOAPException ex) {
        throw new PAOSException(SOAP_MESSAGE_FAILURE, ex);
    } catch (MarshallingTypeException ex) {
        throw new PAOSDispatcherException(MARSHALLING_ERROR, ex);
    } catch (InvocationTargetException ex) {
        throw new PAOSDispatcherException(DISPATCHER_ERROR, ex);
    } catch (TransformerException ex) {
        throw new DispatcherException(ex);
    } catch (WSException ex) {
        throw new PAOSException(ex);
    } finally {
        try {
            if (conn != null) {
                conn.close();
            }
        } catch (IOException ex) {
        // throw new PAOSException(ex);
        }
    }
}
Also used : MarshallingTypeException(org.openecard.ws.marshal.MarshallingTypeException) HttpRequestExecutor(org.openecard.apache.http.protocol.HttpRequestExecutor) ContentType(org.openecard.apache.http.entity.ContentType) HttpEntity(org.openecard.apache.http.HttpEntity) BasicHttpContext(org.openecard.apache.http.protocol.BasicHttpContext) DefaultConnectionReuseStrategy(org.openecard.apache.http.impl.DefaultConnectionReuseStrategy) StartPAOSResponse(iso.std.iso_iec._24727.tech.schema.StartPAOSResponse) StreamHttpClientConnection(org.openecard.transport.httpcore.StreamHttpClientConnection) StringEntity(org.openecard.apache.http.entity.StringEntity) SOAPException(org.openecard.ws.soap.SOAPException) WSException(org.openecard.common.WSHelper.WSException) HttpException(org.openecard.apache.http.HttpException) TransformerException(javax.xml.transform.TransformerException) BasicHttpEntityEnclosingRequest(org.openecard.apache.http.message.BasicHttpEntityEnclosingRequest) BasicHttpContext(org.openecard.apache.http.protocol.BasicHttpContext) HttpContext(org.openecard.apache.http.protocol.HttpContext) HttpResponse(org.openecard.apache.http.HttpResponse) DispatcherException(org.openecard.common.interfaces.DispatcherException) ResponseBaseType(oasis.names.tc.dss._1_0.core.schema.ResponseBaseType) IOException(java.io.IOException) InvocationTargetException(java.lang.reflect.InvocationTargetException) ByteArrayInputStream(java.io.ByteArrayInputStream)

Example 3 with HttpException

use of org.openecard.apache.http.HttpException in project open-ecard by ecsec.

the class ControlCommonHandler method handle.

/**
 * Handles a HTTP request.
 *
 * @param request HttpRequest
 * @param response HttpResponse
 * @param context HttpContext
 * @throws HttpException
 * @throws IOException
 */
@Override
public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException {
    _logger.debug("HTTP request: {}", request.toString());
    HttpResponse httpResponse = null;
    try {
        // Forward request parameters to response parameters
        response.setParams(request.getParams());
        httpResponse = handle(request);
    } catch (org.openecard.control.binding.http.HttpException e) {
        httpResponse = new Http11Response(HttpStatus.SC_BAD_REQUEST);
        httpResponse.setEntity(new StringEntity(e.getMessage(), "UTF-8"));
        if (e.getMessage() != null && !e.getMessage().isEmpty()) {
            httpResponse.setEntity(new StringEntity(e.getMessage(), "UTF-8"));
        }
        httpResponse.setStatusCode(e.getHTTPStatusCode());
    } catch (Exception e) {
        httpResponse = new Http11Response(HttpStatus.SC_INTERNAL_SERVER_ERROR);
        _logger.error(e.getMessage(), e);
    } finally {
        Http11Response.copyHttpResponse(httpResponse, response);
        _logger.debug("HTTP response: {}", response);
        _logger.debug("HTTP request handled by: {}", this.getClass().getName());
    }
}
Also used : StringEntity(org.openecard.apache.http.entity.StringEntity) HttpResponse(org.openecard.apache.http.HttpResponse) HttpException(org.openecard.apache.http.HttpException) IOException(java.io.IOException) Http11Response(org.openecard.control.binding.http.common.Http11Response)

Example 4 with HttpException

use of org.openecard.apache.http.HttpException in project open-ecard by ecsec.

the class ChipGateway method sendMessage.

private <T> T sendMessage(String resource, String msg, Class<T> resClass, boolean tryAgain) throws ConnectionError, InvalidRedirectUrlException, ChipGatewayDataError {
    try {
        // open initial connection
        if (conn == null || !canReuse || (!conn.isOpen() && canReuse)) {
            openHttpStream();
        }
        // prepare request
        BasicHttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest("POST", resource);
        HttpRequestHelper.setDefaultHeader(req, tlsHandler.getServerAddress());
        req.setHeader("Accept", "application/json");
        ContentType reqContentType = ContentType.create("application/json", "UTF-8");
        if (LOG_HTTP_MESSAGES) {
            HttpUtils.dumpHttpRequest(LOG, "before adding content", req);
        }
        StringEntity reqMsg = new StringEntity(msg, reqContentType);
        req.setEntity(reqMsg);
        req.setHeader(reqMsg.getContentType());
        req.setHeader("Content-Length", Long.toString(reqMsg.getContentLength()));
        if (LOG_HTTP_MESSAGES) {
            LOG.debug(msg);
        }
        // send request and receive response
        LOG.debug("Sending HTTP request.");
        HttpResponse response = httpExecutor.execute(req, conn, httpCtx);
        canReuse = reuseStrategy.keepAlive(response, httpCtx);
        LOG.debug("HTTP response received.");
        int statusCode = response.getStatusLine().getStatusCode();
        checkHTTPStatusCode(statusCode);
        conn.receiveResponseEntity(response);
        HttpEntity entity = response.getEntity();
        byte[] entityData = FileUtils.toByteArray(entity.getContent());
        if (LOG_HTTP_MESSAGES) {
            HttpUtils.dumpHttpResponse(LOG, response, entityData);
        }
        // convert entity and return it
        T resultObj = parseResultObj(entityData, resClass);
        return resultObj;
    } catch (IOException ex) {
        if (!Thread.currentThread().isInterrupted() && tryAgain) {
            String errorMsg = "ChipGateway server closed the connection. Trying to connect again.";
            if (LOG.isDebugEnabled()) {
                LOG.debug(errorMsg, ex);
            } else {
                LOG.info(errorMsg);
            }
            canReuse = false;
            return sendMessage(resource, msg, resClass, false);
        } else {
            throw new ConnectionError(token.finalizeErrorAddress(ResultMinor.COMMUNICATION_ERROR), CONNECTION_OPEN_FAILED, ex);
        }
    } catch (HttpException ex) {
        throw new ConnectionError(token.finalizeErrorAddress(ResultMinor.SERVER_ERROR), HTTP_ERROR, ex);
    }
}
Also used : StringEntity(org.openecard.apache.http.entity.StringEntity) ContentType(org.openecard.apache.http.entity.ContentType) HttpEntity(org.openecard.apache.http.HttpEntity) ConnectionError(org.openecard.addons.cg.ex.ConnectionError) HttpResponse(org.openecard.apache.http.HttpResponse) HttpException(org.openecard.apache.http.HttpException) IOException(java.io.IOException) BasicHttpEntityEnclosingRequest(org.openecard.apache.http.message.BasicHttpEntityEnclosingRequest)

Aggregations

IOException (java.io.IOException)4 HttpException (org.openecard.apache.http.HttpException)4 HttpResponse (org.openecard.apache.http.HttpResponse)4 HttpEntity (org.openecard.apache.http.HttpEntity)3 StringEntity (org.openecard.apache.http.entity.StringEntity)3 BasicHttpEntityEnclosingRequest (org.openecard.apache.http.message.BasicHttpEntityEnclosingRequest)3 ContentType (org.openecard.apache.http.entity.ContentType)2 BasicHttpContext (org.openecard.apache.http.protocol.BasicHttpContext)2 HttpContext (org.openecard.apache.http.protocol.HttpContext)2 HttpRequestExecutor (org.openecard.apache.http.protocol.HttpRequestExecutor)2 StreamHttpClientConnection (org.openecard.transport.httpcore.StreamHttpClientConnection)2 StartPAOSResponse (iso.std.iso_iec._24727.tech.schema.StartPAOSResponse)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Socket (java.net.Socket)1 URISyntaxException (java.net.URISyntaxException)1 URL (java.net.URL)1 TransformerException (javax.xml.transform.TransformerException)1 ResponseBaseType (oasis.names.tc.dss._1_0.core.schema.ResponseBaseType)1 ConnectionError (org.openecard.addons.cg.ex.ConnectionError)1