use of org.openecard.apache.http.protocol.BasicHttpContext in project open-ecard by ecsec.
the class HttpGetTask method getRequest.
private void getRequest() throws IOException, ConnectionError, URISyntaxException, HttpException {
TlsConnectionHandler tlsHandler = new TlsConnectionHandler(dispatcher, tokenRequest, connectionHandle);
tlsHandler.setUpClient();
// connect the tls endpoint and make a get request
TlsClientProtocol handler = tlsHandler.createTlsConnection();
// set up connection to endpoint
InputStream in = handler.getInputStream();
OutputStream out = handler.getOutputStream();
StreamHttpClientConnection conn = new StreamHttpClientConnection(in, out);
// prepare HTTP connection
HttpContext ctx = new BasicHttpContext();
HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
DefaultConnectionReuseStrategy reuse = new DefaultConnectionReuseStrategy();
// prepare request
String resource = tlsHandler.getResource();
BasicHttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest("GET", resource);
HttpRequestHelper.setDefaultHeader(req, tlsHandler.getServerAddress());
req.setHeader("Accept", "text/html, */*;q=0.8");
req.setHeader("Accept-Charset", "utf-8, *;q=0.8");
HttpUtils.dumpHttpRequest(LOG, req);
// send request and receive response
HttpResponse response = httpexecutor.execute(req, conn, ctx);
int statusCode = response.getStatusLine().getStatusCode();
conn.receiveResponseEntity(response);
HttpEntity entity = response.getEntity();
byte[] entityData = FileUtils.toByteArray(entity.getContent());
HttpUtils.dumpHttpResponse(LOG, response, entityData);
conn.close();
if (statusCode < 200 || statusCode > 299) {
throw new ConnectionError(WRONG_SERVER_RESULT, statusCode);
}
}
use of org.openecard.apache.http.protocol.BasicHttpContext 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);
}
}
use of org.openecard.apache.http.protocol.BasicHttpContext in project open-ecard by ecsec.
the class HttpService method run.
@Override
public void run() {
while (!Thread.interrupted()) {
try {
final DefaultBHttpServerConnection connection;
CharsetDecoder dec = Charset.forName("UTF-8").newDecoder();
CharsetEncoder enc = Charset.forName("UTF-8").newEncoder();
connection = new DefaultBHttpServerConnection(8192, dec, enc, null);
connection.bind(accept());
new Thread() {
@Override
public void run() {
try {
while (connection.isOpen()) {
service.handleRequest(connection, new BasicHttpContext());
}
} catch (ConnectionClosedException ex) {
// connection closed by client, this is the expected outcome
} catch (org.openecard.apache.http.HttpException ex) {
LOG.error("Error processing HTTP request or response.", ex);
} catch (IOException ex) {
LOG.error("IO Error while processing HTTP request or response.", ex);
} finally {
try {
connection.shutdown();
} catch (IOException ignore) {
}
}
}
}.start();
} catch (IOException | HttpServiceError ex) {
// if interrupted the error is intentionally (SocketClosedException)
if (!Thread.interrupted()) {
LOG.error(ex.getMessage(), ex);
} else {
// set interrupt status again after reading it
thread.interrupt();
}
}
}
}
use of org.openecard.apache.http.protocol.BasicHttpContext in project open-ecard by ecsec.
the class StreamHttpClientConnectionTest method consumeEntity.
private void consumeEntity(StreamHttpClientConnection conn, String hostName, int numIt) throws IOException, HttpException {
HttpContext ctx = new BasicHttpContext();
HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
HttpResponse response = null;
DefaultConnectionReuseStrategy reuse = new DefaultConnectionReuseStrategy();
int i = 0;
while (i == 0 || (i < numIt && reuse.keepAlive(response, ctx))) {
i++;
// send request and receive response
HttpRequest request = new BasicHttpRequest("GET", "/");
HttpRequestHelper.setDefaultHeader(request, hostName);
response = httpexecutor.execute(request, conn, ctx);
conn.receiveResponseEntity(response);
HttpEntity entity = response.getEntity();
assertNotNull(entity);
// consume entity
byte[] content = FileUtils.toByteArray(entity.getContent());
// read header and check if content size is correct
Header lengthHeader = response.getFirstHeader("Content-Length");
long length = Long.parseLong(lengthHeader.getValue());
assertNotNull(lengthHeader);
assertEquals(entity.getContentLength(), length);
assertEquals(content.length, length);
// consume everything from the entity and close stream
EntityUtils.consume(entity);
}
}
use of org.openecard.apache.http.protocol.BasicHttpContext 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);
}
}
}
Aggregations