1 /*
2  * ====================================================================
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  * ====================================================================
20  *
21  * This software consists of voluntary contributions made by many
22  * individuals on behalf of the Apache Software Foundation.  For more
23  * information on the Apache Software Foundation, please see
24  * <http://www.apache.org/>.
25  *
26  */

27
28 package org.apache.http.protocol;
29
30 import java.io.IOException;
31 import java.net.InetAddress;
32
33 import org.apache.http.HttpConnection;
34 import org.apache.http.HttpException;
35 import org.apache.http.HttpHost;
36 import org.apache.http.HttpInetConnection;
37 import org.apache.http.HttpRequest;
38 import org.apache.http.HttpRequestInterceptor;
39 import org.apache.http.HttpVersion;
40 import org.apache.http.ProtocolException;
41 import org.apache.http.ProtocolVersion;
42 import org.apache.http.annotation.ThreadingBehavior;
43 import org.apache.http.annotation.Contract;
44 import org.apache.http.util.Args;
45
46 /**
47  * RequestTargetHost is responsible for adding {@code Host} header. This
48  * interceptor is required for client side protocol processors.
49  *
50  * @since 4.0
51  */

52 @Contract(threading = ThreadingBehavior.IMMUTABLE)
53 public class RequestTargetHost implements HttpRequestInterceptor {
54
55     public RequestTargetHost() {
56         super();
57     }
58
59     @Override
60     public void process(final HttpRequest request, final HttpContext context)
61             throws HttpException, IOException {
62         Args.notNull(request, "HTTP request");
63
64         final HttpCoreContext coreContext = HttpCoreContext.adapt(context);
65
66         final ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
67         final String method = request.getRequestLine().getMethod();
68         if (method.equalsIgnoreCase("CONNECT") && ver.lessEquals(HttpVersion.HTTP_1_0)) {
69             return;
70         }
71
72         if (!request.containsHeader(HTTP.TARGET_HOST)) {
73             HttpHost targetHost = coreContext.getTargetHost();
74             if (targetHost == null) {
75                 final HttpConnection conn = coreContext.getConnection();
76                 if (conn instanceof HttpInetConnection) {
77                     // Populate the context with a default HTTP host based on the
78                     // inet address of the target host
79                     final InetAddress address = ((HttpInetConnection) conn).getRemoteAddress();
80                     final int port = ((HttpInetConnection) conn).getRemotePort();
81                     if (address != null) {
82                         targetHost = new HttpHost(address.getHostName(), port);
83                     }
84                 }
85                 if (targetHost == null) {
86                     if (ver.lessEquals(HttpVersion.HTTP_1_0)) {
87                         return;
88                     }
89                     throw new ProtocolException("Target host missing");
90                 }
91             }
92             request.addHeader(HTTP.TARGET_HOST, targetHost.toHostString());
93         }
94     }
95
96 }
97