| // |
| // ======================================================================== |
| // Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd. |
| // ------------------------------------------------------------------------ |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v1.0 |
| // and Apache License v2.0 which accompanies this distribution. |
| // |
| // The Eclipse Public License is available at |
| // http://www.eclipse.org/legal/epl-v10.html |
| // |
| // The Apache License v2.0 is available at |
| // http://www.opensource.org/licenses/apache2.0.php |
| // |
| // You may elect to redistribute this code under either of these licenses. |
| // ======================================================================== |
| // |
| |
| package org.eclipse.jetty.client.http; |
| |
| import org.eclipse.jetty.client.HttpChannel; |
| import org.eclipse.jetty.client.HttpExchange; |
| import org.eclipse.jetty.client.HttpReceiver; |
| import org.eclipse.jetty.client.HttpSender; |
| import org.eclipse.jetty.client.api.Response; |
| import org.eclipse.jetty.client.api.Result; |
| import org.eclipse.jetty.http.HttpFields; |
| import org.eclipse.jetty.http.HttpHeader; |
| import org.eclipse.jetty.http.HttpHeaderValue; |
| import org.eclipse.jetty.http.HttpMethod; |
| import org.eclipse.jetty.http.HttpVersion; |
| |
| public class HttpChannelOverHTTP extends HttpChannel |
| { |
| private final HttpConnectionOverHTTP connection; |
| private final HttpSenderOverHTTP sender; |
| private final HttpReceiverOverHTTP receiver; |
| |
| public HttpChannelOverHTTP(HttpConnectionOverHTTP connection) |
| { |
| super(connection.getHttpDestination()); |
| this.connection = connection; |
| this.sender = newHttpSender(); |
| this.receiver = newHttpReceiver(); |
| } |
| |
| protected HttpSenderOverHTTP newHttpSender() |
| { |
| return new HttpSenderOverHTTP(this); |
| } |
| |
| protected HttpReceiverOverHTTP newHttpReceiver() |
| { |
| return new HttpReceiverOverHTTP(this); |
| } |
| |
| @Override |
| protected HttpSender getHttpSender() |
| { |
| return sender; |
| } |
| |
| @Override |
| protected HttpReceiver getHttpReceiver() |
| { |
| return receiver; |
| } |
| |
| public HttpConnectionOverHTTP getHttpConnection() |
| { |
| return connection; |
| } |
| |
| @Override |
| public void send() |
| { |
| HttpExchange exchange = getHttpExchange(); |
| if (exchange != null) |
| sender.send(exchange); |
| } |
| |
| @Override |
| public void release() |
| { |
| connection.release(); |
| } |
| |
| public void receive() |
| { |
| receiver.receive(); |
| } |
| |
| @Override |
| public void exchangeTerminated(HttpExchange exchange, Result result) |
| { |
| super.exchangeTerminated(exchange, result); |
| |
| Response response = result.getResponse(); |
| HttpFields responseHeaders = response.getHeaders(); |
| |
| String closeReason = null; |
| if (result.isFailed()) |
| closeReason = "failure"; |
| else if (receiver.isShutdown()) |
| closeReason = "server close"; |
| |
| if (closeReason == null) |
| { |
| if (response.getVersion().compareTo(HttpVersion.HTTP_1_1) < 0) |
| { |
| // HTTP 1.0 must close the connection unless it has |
| // an explicit keep alive or it's a CONNECT method. |
| boolean keepAlive = responseHeaders.contains(HttpHeader.CONNECTION, HttpHeaderValue.KEEP_ALIVE.asString()); |
| boolean connect = HttpMethod.CONNECT.is(exchange.getRequest().getMethod()); |
| if (!keepAlive && !connect) |
| closeReason = "http/1.0"; |
| } |
| else |
| { |
| // HTTP 1.1 or greater closes only if it has an explicit close. |
| if (responseHeaders.contains(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString())) |
| closeReason = "http/1.1"; |
| } |
| } |
| |
| if (closeReason != null) |
| { |
| if (LOG.isDebugEnabled()) |
| LOG.debug("Closing, reason: {} - {}", closeReason, connection); |
| connection.close(); |
| } |
| else |
| { |
| release(); |
| } |
| } |
| |
| @Override |
| public String toString() |
| { |
| return String.format("%s[send=%s,recv=%s]", |
| super.toString(), |
| sender, |
| receiver); |
| } |
| } |