001package org.apache.maven.wagon.shared.http;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.http.Header;
023import org.apache.http.HttpHost;
024import org.apache.http.client.config.RequestConfig;
025import org.apache.http.message.BasicHeader;
026import org.apache.maven.wagon.Wagon;
027
028import java.net.InetAddress;
029import java.net.UnknownHostException;
030import java.util.Arrays;
031import java.util.Map;
032import java.util.Properties;
033import java.util.regex.Matcher;
034import java.util.regex.Pattern;
035
036/**
037 * Configuration helper class
038 */
039public class ConfigurationUtils
040{
041
042    private static final String SO_TIMEOUT                  = "http.socket.timeout";
043    private static final String STALE_CONNECTION_CHECK      = "http.connection.stalecheck";
044    private static final String CONNECTION_TIMEOUT          = "http.connection.timeout";
045    private static final String USE_EXPECT_CONTINUE         = "http.protocol.expect-continue";
046    private static final String DEFAULT_PROXY               = "http.route.default-proxy";
047    private static final String LOCAL_ADDRESS               = "http.route.local-address";
048    private static final String PROXY_AUTH_PREF             = "http.auth.proxy-scheme-pref";
049    private static final String TARGET_AUTH_PREF            = "http.auth.target-scheme-pref";
050    private static final String HANDLE_AUTHENTICATION       = "http.protocol.handle-authentication";
051    private static final String ALLOW_CIRCULAR_REDIRECTS    = "http.protocol.allow-circular-redirects";
052    private static final String CONN_MANAGER_TIMEOUT        = "http.conn-manager.timeout";
053    private static final String COOKIE_POLICY               = "http.protocol.cookie-policy";
054    private static final String MAX_REDIRECTS               = "http.protocol.max-redirects";
055    private static final String HANDLE_REDIRECTS            = "http.protocol.handle-redirects";
056    private static final String REJECT_RELATIVE_REDIRECT    = "http.protocol.reject-relative-redirect";
057    private static final String HANDLE_CONTENT_COMPRESSION  = "http.protocol.handle-content-compression";
058    private static final String HANDLE_URI_NORMALIZATION    = "http.protocol.handle-uri-normalization";
059
060    private static final String COERCE_PATTERN = "%(\\w+),(.+)";
061
062    public static void copyConfig( HttpMethodConfiguration config, RequestConfig.Builder builder )
063    {
064        builder.setConnectTimeout( config.getConnectionTimeout() );
065        builder.setSocketTimeout( config.getReadTimeout() );
066
067        Properties params = config.getParams();
068        if ( params != null )
069        {
070
071            Pattern coercePattern = Pattern.compile( COERCE_PATTERN );
072            for ( Map.Entry entry : params.entrySet() )
073            {
074                String key = (String) entry.getKey();
075                String value = (String) entry.getValue();
076                Matcher matcher = coercePattern.matcher( value );
077                if ( matcher.matches() )
078                {
079                    value = matcher.group( 2 );
080                }
081
082                if ( key.equals( SO_TIMEOUT ) )
083                {
084                    builder.setSocketTimeout( Integer.parseInt( value ) );
085                }
086                else if ( key.equals( STALE_CONNECTION_CHECK ) )
087                {
088                    builder.setStaleConnectionCheckEnabled( Boolean.valueOf( value ) );
089                }
090                else if ( key.equals( CONNECTION_TIMEOUT ) )
091                {
092                    builder.setConnectTimeout( Integer.parseInt( value ) );
093                }
094                else if ( key.equals( USE_EXPECT_CONTINUE ) )
095                {
096                    builder.setExpectContinueEnabled( Boolean.valueOf( value ) );
097                }
098                else if ( key.equals( DEFAULT_PROXY ) )
099                {
100                    builder.setProxy( HttpHost.create( value ) );
101                }
102                else if ( key.equals( LOCAL_ADDRESS ) )
103                {
104                    try
105                    {
106                        builder.setLocalAddress( InetAddress.getByName( value ) );
107                    }
108                    catch ( UnknownHostException ignore )
109                    {
110                        // ignore
111                    }
112                }
113                else if ( key.equals( PROXY_AUTH_PREF ) )
114                {
115                    builder.setProxyPreferredAuthSchemes( Arrays.asList( value.split( "," ) ) );
116                }
117                else if ( key.equals( TARGET_AUTH_PREF ) )
118                {
119                    builder.setTargetPreferredAuthSchemes( Arrays.asList( value.split( "," ) ) );
120                }
121                else if ( key.equals( HANDLE_AUTHENTICATION ) )
122                {
123                    builder.setAuthenticationEnabled( Boolean.valueOf( value ) );
124                }
125                else if ( key.equals( ALLOW_CIRCULAR_REDIRECTS ) )
126                {
127                    builder.setCircularRedirectsAllowed( Boolean.valueOf( value ) );
128                }
129                else if ( key.equals( CONN_MANAGER_TIMEOUT ) )
130                {
131                    builder.setConnectionRequestTimeout( Integer.parseInt( value ) );
132                }
133                else if ( key.equals( COOKIE_POLICY ) )
134                {
135                    builder.setCookieSpec( value );
136                }
137                else if ( key.equals( MAX_REDIRECTS ) )
138                {
139                    builder.setMaxRedirects( Integer.parseInt( value ) );
140                }
141                else if ( key.equals( HANDLE_REDIRECTS ) )
142                {
143                    builder.setRedirectsEnabled( Boolean.valueOf( value ) );
144                }
145                else if ( key.equals( REJECT_RELATIVE_REDIRECT ) )
146                {
147                    builder.setRelativeRedirectsAllowed( !Boolean.valueOf( value ) );
148                }
149                else if ( key.equals ( HANDLE_CONTENT_COMPRESSION ) )
150                {
151                    builder.setContentCompressionEnabled( Boolean.valueOf( value ) );
152                }
153                else if ( key.equals ( HANDLE_URI_NORMALIZATION ) )
154                {
155                    builder.setNormalizeUri( Boolean.valueOf( value ) );
156                }
157            }
158        }
159    }
160
161    public static Header[] asRequestHeaders( HttpMethodConfiguration config )
162    {
163        Properties headers = config.getHeaders();
164        if ( headers == null )
165        {
166            return new Header[0];
167        }
168
169        Header[] result = new Header[headers.size()];
170
171        int index = 0;
172        for ( Map.Entry entry : headers.entrySet() )
173        {
174            String key = (String) entry.getKey();
175            String value = (String) entry.getValue();
176
177            Header header = new BasicHeader( key, value );
178            result[index++] = header;
179        }
180
181        return result;
182    }
183
184    public static HttpMethodConfiguration merge( HttpMethodConfiguration defaults, HttpMethodConfiguration base,
185                                            HttpMethodConfiguration local )
186    {
187        HttpMethodConfiguration result = merge( defaults, base );
188        return merge( result, local );
189    }
190
191    public static HttpMethodConfiguration merge( HttpMethodConfiguration base, HttpMethodConfiguration local )
192    {
193        if ( base == null && local == null )
194        {
195            return null;
196        }
197        else if ( base == null )
198        {
199            return local;
200        }
201        else if ( local == null )
202        {
203            return base;
204        }
205        else
206        {
207            HttpMethodConfiguration result = base.copy();
208
209            if ( local.getConnectionTimeout() != Wagon.DEFAULT_CONNECTION_TIMEOUT )
210            {
211                result.setConnectionTimeout( local.getConnectionTimeout() );
212            }
213
214            if ( local.getReadTimeout() != Wagon.DEFAULT_READ_TIMEOUT )
215            {
216                result.setReadTimeout( local.getReadTimeout() );
217            }
218
219            if ( local.getHeaders() != null )
220            {
221                result.getHeaders().putAll( local.getHeaders() );
222            }
223
224            if ( local.getParams() != null )
225            {
226                result.getParams().putAll( local.getParams() );
227            }
228
229            if ( local.getUseDefaultHeaders() != null )
230            {
231                result.setUseDefaultHeaders( local.isUseDefaultHeaders() );
232            }
233
234            return result;
235        }
236    }
237
238}