@Override public boolean startResponse(HttpVersion version, int status, String reason) { if (updateState(State.IDLE, State.RECEIVE)) { HttpExchange exchange = connection.getExchange(); // The exchange may be null if it failed concurrently if (exchange != null) { HttpConversation conversation = exchange.getConversation(); HttpResponse response = exchange.getResponse(); String method = exchange.getRequest().method(); parser.setHeadResponse(HttpMethod.HEAD.is(method) || HttpMethod.CONNECT.is(method)); response.version(version).status(status).reason(reason); // Probe the protocol handlers HttpClient client = connection.getHttpClient(); ProtocolHandler protocolHandler = client.findProtocolHandler(exchange.getRequest(), response); Response.Listener handlerListener = null; if (protocolHandler != null) { handlerListener = protocolHandler.getResponseListener(); LOG.debug("Found protocol handler {}", protocolHandler); } exchange.getConversation().updateResponseListeners(handlerListener); LOG.debug("Receiving {}", response); ResponseNotifier notifier = connection.getDestination().getResponseNotifier(); notifier.notifyBegin(conversation.getResponseListeners(), response); } } return false; }
protected boolean success() { HttpExchange exchange = connection.getExchange(); if (exchange == null) return false; AtomicMarkableReference<Result> completion = exchange.responseComplete(null); if (!completion.isMarked()) return false; parser.reset(); decoder = null; if (!updateState(State.RECEIVE, State.IDLE)) throw new IllegalStateException(); exchange.terminateResponse(); HttpResponse response = exchange.getResponse(); List<Response.ResponseListener> listeners = exchange.getConversation().getResponseListeners(); ResponseNotifier notifier = connection.getDestination().getResponseNotifier(); notifier.notifySuccess(listeners, response); LOG.debug("Received {}", response); Result result = completion.getReference(); if (result != null) { connection.complete(exchange, !result.isFailed()); notifier.notifyComplete(listeners, result); } return true; }
@Override public boolean headerComplete() { if (updateState(State.RECEIVE, State.RECEIVE)) { HttpExchange exchange = connection.getExchange(); // The exchange may be null if it failed concurrently if (exchange != null) { HttpConversation conversation = exchange.getConversation(); HttpResponse response = exchange.getResponse(); LOG.debug("Headers {}", response); ResponseNotifier notifier = connection.getDestination().getResponseNotifier(); notifier.notifyHeaders(conversation.getResponseListeners(), response); Enumeration<String> contentEncodings = response.getHeaders().getValues(HttpHeader.CONTENT_ENCODING.asString(), ","); if (contentEncodings != null) { for (ContentDecoder.Factory factory : connection.getHttpClient().getContentDecoderFactories()) { while (contentEncodings.hasMoreElements()) { if (factory.getEncoding().equalsIgnoreCase(contentEncodings.nextElement())) { this.decoder = factory.newContentDecoder(); break; } } } } } } return false; }
@Override public boolean parsedHeader(HttpField field) { if (updateState(State.RECEIVE, State.RECEIVE)) { HttpExchange exchange = connection.getExchange(); // The exchange may be null if it failed concurrently if (exchange != null) { HttpConversation conversation = exchange.getConversation(); HttpResponse response = exchange.getResponse(); ResponseNotifier notifier = connection.getDestination().getResponseNotifier(); boolean process = notifier.notifyHeader(conversation.getResponseListeners(), response, field); if (process) { response.getHeaders().add(field); HttpHeader fieldHeader = field.getHeader(); if (fieldHeader != null) { switch (fieldHeader) { case SET_COOKIE: case SET_COOKIE2: { storeCookie(exchange.getRequest().getURI(), field); break; } default: { break; } } } } } } return false; }
protected void abort(HttpExchange exchange, Throwable cause) { Request request = exchange.getRequest(); HttpResponse response = exchange.getResponse(); getRequestNotifier().notifyFailure(request, cause); List<Response.ResponseListener> listeners = exchange.getConversation().getResponseListeners(); getResponseNotifier().notifyFailure(listeners, response, cause); getResponseNotifier().notifyComplete(listeners, new Result(request, cause, response, cause)); }
@Override public boolean content(ByteBuffer buffer) { if (updateState(State.RECEIVE, State.RECEIVE)) { HttpExchange exchange = connection.getExchange(); // The exchange may be null if it failed concurrently if (exchange != null) { HttpConversation conversation = exchange.getConversation(); HttpResponse response = exchange.getResponse(); LOG.debug("Content {}: {} bytes", response, buffer.remaining()); ContentDecoder decoder = this.decoder; if (decoder != null) { buffer = decoder.decode(buffer); LOG.debug("{} {}: {} bytes", decoder, response, buffer.remaining()); } ResponseNotifier notifier = connection.getDestination().getResponseNotifier(); notifier.notifyContent(conversation.getResponseListeners(), response, buffer); } } return false; }
protected boolean fail(Throwable failure) { HttpExchange exchange = connection.getExchange(); // In case of a response error, the failure has already been notified // and it is possible that a further attempt to read in the receive // loop throws an exception that reenters here but without exchange; // or, the server could just have timed out the connection. if (exchange == null) return false; AtomicMarkableReference<Result> completion = exchange.responseComplete(failure); if (!completion.isMarked()) return false; parser.close(); decoder = null; while (true) { State current = state.get(); if (updateState(current, State.FAILURE)) break; } exchange.terminateResponse(); HttpResponse response = exchange.getResponse(); HttpConversation conversation = exchange.getConversation(); ResponseNotifier notifier = connection.getDestination().getResponseNotifier(); notifier.notifyFailure(conversation.getResponseListeners(), response, failure); LOG.debug("Failed {} {}", response, failure); Result result = completion.getReference(); if (result != null) { connection.complete(exchange, false); notifier.notifyComplete(conversation.getResponseListeners(), result); } return true; }