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        if ( config.getConnectionTimeout() > 0 )
065        {
066            builder.setConnectTimeout( config.getConnectionTimeout() );
067        }
068        if ( config.getReadTimeout() > 0 )
069        {
070            builder.setSocketTimeout( config.getReadTimeout() );
071        }
072        Properties params = config.getParams();
073        if ( params != null )
074        {
075
076            Pattern coercePattern = Pattern.compile( COERCE_PATTERN );
077            for ( Map.Entry entry : params.entrySet() )
078            {
079                String key = (String) entry.getKey();
080                String value = (String) entry.getValue();
081                Matcher matcher = coercePattern.matcher( value );
082                if ( matcher.matches() )
083                {
084                    value = matcher.group( 2 );
085                }
086
087                if ( key.equals( SO_TIMEOUT ) )
088                {
089                    builder.setSocketTimeout( Integer.parseInt( value ) );
090                }
091                else if ( key.equals( STALE_CONNECTION_CHECK ) )
092                {
093                    builder.setStaleConnectionCheckEnabled( Boolean.valueOf( value ) );
094                }
095                else if ( key.equals( CONNECTION_TIMEOUT ) )
096                {
097                    builder.setConnectTimeout( Integer.parseInt( value ) );
098                }
099                else if ( key.equals( USE_EXPECT_CONTINUE ) )
100                {
101                    builder.setExpectContinueEnabled( Boolean.valueOf( value ) );
102                }
103                else if ( key.equals( DEFAULT_PROXY ) )
104                {
105                    builder.setProxy( HttpHost.create( value ) );
106                }
107                else if ( key.equals( LOCAL_ADDRESS ) )
108                {
109                    try
110                    {
111                        builder.setLocalAddress( InetAddress.getByName( value ) );
112                    }
113                    catch ( UnknownHostException ignore )
114                    {
115                        // ignore
116                    }
117                }
118                else if ( key.equals( PROXY_AUTH_PREF ) )
119                {
120                    builder.setProxyPreferredAuthSchemes( Arrays.asList( value.split( "," ) ) );
121                }
122                else if ( key.equals( TARGET_AUTH_PREF ) )
123                {
124                    builder.setTargetPreferredAuthSchemes( Arrays.asList( value.split( "," ) ) );
125                }
126                else if ( key.equals( HANDLE_AUTHENTICATION ) )
127                {
128                    builder.setAuthenticationEnabled( Boolean.valueOf( value ) );
129                }
130                else if ( key.equals( ALLOW_CIRCULAR_REDIRECTS ) )
131                {
132                    builder.setCircularRedirectsAllowed( Boolean.valueOf( value ) );
133                }
134                else if ( key.equals( CONN_MANAGER_TIMEOUT ) )
135                {
136                    builder.setConnectionRequestTimeout( Integer.parseInt( value ) );
137                }
138                else if ( key.equals( COOKIE_POLICY ) )
139                {
140                    builder.setCookieSpec( value );
141                }
142                else if ( key.equals( MAX_REDIRECTS ) )
143                {
144                    builder.setMaxRedirects( Integer.parseInt( value ) );
145                }
146                else if ( key.equals( HANDLE_REDIRECTS ) )
147                {
148                    builder.setRedirectsEnabled( Boolean.valueOf( value ) );
149                }
150                else if ( key.equals( REJECT_RELATIVE_REDIRECT ) )
151                {
152                    builder.setRelativeRedirectsAllowed( !Boolean.valueOf( value ) );
153                }
154                else if ( key.equals ( HANDLE_CONTENT_COMPRESSION ) )
155                {
156                    builder.setContentCompressionEnabled( Boolean.valueOf( value ) );
157                }
158                else if ( key.equals ( HANDLE_URI_NORMALIZATION ) )
159                {
160                    builder.setNormalizeUri( Boolean.valueOf( value ) );
161                }
162            }
163        }
164    }
165
166    public static Header[] asRequestHeaders( HttpMethodConfiguration config )
167    {
168        Properties headers = config.getHeaders();
169        if ( headers == null )
170        {
171            return new Header[0];
172        }
173
174        Header[] result = new Header[headers.size()];
175
176        int index = 0;
177        for ( Map.Entry entry : headers.entrySet() )
178        {
179            String key = (String) entry.getKey();
180            String value = (String) entry.getValue();
181
182            Header header = new BasicHeader( key, value );
183            result[index++] = header;
184        }
185
186        return result;
187    }
188
189    public static HttpMethodConfiguration merge( HttpMethodConfiguration defaults, HttpMethodConfiguration base,
190                                            HttpMethodConfiguration local )
191    {
192        HttpMethodConfiguration result = merge( defaults, base );
193        return merge( result, local );
194    }
195
196    public static HttpMethodConfiguration merge( HttpMethodConfiguration base, HttpMethodConfiguration local )
197    {
198        if ( base == null && local == null )
199        {
200            return null;
201        }
202        else if ( base == null )
203        {
204            return local;
205        }
206        else if ( local == null )
207        {
208            return base;
209        }
210        else
211        {
212            HttpMethodConfiguration result = base.copy();
213
214            if ( local.getConnectionTimeout() != Wagon.DEFAULT_CONNECTION_TIMEOUT )
215            {
216                result.setConnectionTimeout( local.getConnectionTimeout() );
217            }
218
219            if ( local.getReadTimeout() != Wagon.DEFAULT_READ_TIMEOUT )
220            {
221                result.setReadTimeout( local.getReadTimeout() );
222            }
223
224            if ( local.getHeaders() != null )
225            {
226                result.getHeaders().putAll( local.getHeaders() );
227            }
228
229            if ( local.getParams() != null )
230            {
231                result.getParams().putAll( local.getParams() );
232            }
233
234            if ( local.getUseDefaultHeaders() != null )
235            {
236                result.setUseDefaultHeaders( local.isUseDefaultHeaders() );
237            }
238
239            return result;
240        }
241    }
242
243}