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.impl.client;
29
30 import java.util.Locale;
31 import java.util.Map;
32 import java.util.concurrent.ConcurrentHashMap;
33
34 import org.apache.http.HttpRequest;
35 import org.apache.http.annotation.Immutable;
36 import org.apache.http.client.HttpRequestRetryHandler;
37
38 /**
39 * A {@link HttpRequestRetryHandler} which assumes that all requested
40 * HTTP methods which should be idempotent according to RFC-2616 are
41 * in fact idempotent and can be retried.
42 *
43 * According to RFC-2616 section 9.1.2 the idempotent HTTP methods are:
44 * GET, HEAD, PUT, DELETE, OPTIONS, and TRACE
45 *
46 * @since 4.2
47 */
48 @Immutable
49 public class StandardHttpRequestRetryHandler extends DefaultHttpRequestRetryHandler {
50
51 private final Map<String, Boolean> idempotentMethods;
52
53 /**
54 * Default constructor
55 */
56 public StandardHttpRequestRetryHandler(final int retryCount, final boolean requestSentRetryEnabled) {
57 super(retryCount, requestSentRetryEnabled);
58 this.idempotentMethods = new ConcurrentHashMap<String, Boolean>();
59 this.idempotentMethods.put("GET", Boolean.TRUE);
60 this.idempotentMethods.put("HEAD", Boolean.TRUE);
61 this.idempotentMethods.put("PUT", Boolean.TRUE);
62 this.idempotentMethods.put("DELETE", Boolean.TRUE);
63 this.idempotentMethods.put("OPTIONS", Boolean.TRUE);
64 this.idempotentMethods.put("TRACE", Boolean.TRUE);
65 }
66
67 /**
68 * Default constructor
69 */
70 public StandardHttpRequestRetryHandler() {
71 this(3, false);
72 }
73
74 @Override
75 protected boolean handleAsIdempotent(final HttpRequest request) {
76 final String method = request.getRequestLine().getMethod().toUpperCase(Locale.US);
77 final Boolean b = this.idempotentMethods.get(method);
78 return b != null && b.booleanValue();
79 }
80
81 }