1069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/*
2069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/ResponseConnControl.java $
3069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * $Revision: 618017 $
4069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * $Date: 2008-02-03 08:42:22 -0800 (Sun, 03 Feb 2008) $
5069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
6069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * ====================================================================
7069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one
8069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * or more contributor license agreements.  See the NOTICE file
9069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * distributed with this work for additional information
10069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * regarding copyright ownership.  The ASF licenses this file
11069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to you under the Apache License, Version 2.0 (the
12069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * "License"); you may not use this file except in compliance
13069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * with the License.  You may obtain a copy of the License at
14069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
15069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *   http://www.apache.org/licenses/LICENSE-2.0
16069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
17069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Unless required by applicable law or agreed to in writing,
18069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * software distributed under the License is distributed on an
19069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * KIND, either express or implied.  See the License for the
21069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * specific language governing permissions and limitations
22069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * under the License.
23069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * ====================================================================
24069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
25069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This software consists of voluntary contributions made by many
26069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * individuals on behalf of the Apache Software Foundation.  For more
27069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * information on the Apache Software Foundation, please see
28069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <http://www.apache.org/>.
29069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
30069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */
31069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
32069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpackage org.apache.http.protocol;
33069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
34069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.io.IOException;
35069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
36069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.Header;
37069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.HttpEntity;
38069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.HttpException;
39069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.HttpRequest;
40069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.HttpResponse;
41069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.HttpResponseInterceptor;
42069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.HttpStatus;
43069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.HttpVersion;
44069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.ProtocolVersion;
45069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
46069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/**
47069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * A response interceptor that suggests connection keep-alive to the client.
48069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * For use on the server side.
49069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
50069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
51069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
52069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @version $Revision: 618017 $
53069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
54069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @since 4.0
55069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */
56069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpublic class ResponseConnControl implements HttpResponseInterceptor {
57069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
58069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public ResponseConnControl() {
59069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        super();
60069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
61069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
62069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public void process(final HttpResponse response, final HttpContext context)
63069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throws HttpException, IOException {
64069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (response == null) {
65069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new IllegalArgumentException("HTTP response may not be null");
66069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
67069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (context == null) {
68069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new IllegalArgumentException("HTTP context may not be null");
69069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
70069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // Always drop connection after certain type of responses
71069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        int status = response.getStatusLine().getStatusCode();
72069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (status == HttpStatus.SC_BAD_REQUEST ||
73069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                status == HttpStatus.SC_REQUEST_TIMEOUT ||
74069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                status == HttpStatus.SC_LENGTH_REQUIRED ||
75069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                status == HttpStatus.SC_REQUEST_TOO_LONG ||
76069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                status == HttpStatus.SC_REQUEST_URI_TOO_LONG ||
77069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                status == HttpStatus.SC_SERVICE_UNAVAILABLE ||
78069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                status == HttpStatus.SC_NOT_IMPLEMENTED) {
79069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);
80069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return;
81069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
82069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // Always drop connection for HTTP/1.0 responses and below
83069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // if the content body cannot be correctly delimited
84069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        HttpEntity entity = response.getEntity();
85069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (entity != null) {
86069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            ProtocolVersion ver = response.getStatusLine().getProtocolVersion();
87069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (entity.getContentLength() < 0 &&
88069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    (!entity.isChunked() || ver.lessEquals(HttpVersion.HTTP_1_0))) {
89069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);
90069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                return;
91069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
92069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
93069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // Drop connection if requested by the client
94069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        HttpRequest request = (HttpRequest)
95069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            context.getAttribute(ExecutionContext.HTTP_REQUEST);
96069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (request != null) {
97069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            Header header = request.getFirstHeader(HTTP.CONN_DIRECTIVE);
98069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (header != null) {
99069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                response.setHeader(HTTP.CONN_DIRECTIVE, header.getValue());
100069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
101069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
102069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
103069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
104069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project}
105