Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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 */
28 package ch.boye.httpclientandroidlib.client.methods;
30 import java.io.IOException;
31 import java.net.URI;
32 import java.util.concurrent.locks.Lock;
33 import java.util.concurrent.locks.ReentrantLock;
35 import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
37 import ch.boye.httpclientandroidlib.ProtocolVersion;
38 import ch.boye.httpclientandroidlib.RequestLine;
39 import ch.boye.httpclientandroidlib.client.utils.CloneUtils;
40 import ch.boye.httpclientandroidlib.conn.ClientConnectionRequest;
41 import ch.boye.httpclientandroidlib.conn.ConnectionReleaseTrigger;
42 import ch.boye.httpclientandroidlib.message.AbstractHttpMessage;
43 import ch.boye.httpclientandroidlib.message.BasicRequestLine;
44 import ch.boye.httpclientandroidlib.message.HeaderGroup;
45 import ch.boye.httpclientandroidlib.params.HttpParams;
46 import ch.boye.httpclientandroidlib.params.HttpProtocolParams;
48 /**
49 * Basic implementation of an HTTP request that can be modified.
50 *
51 *
52 * @since 4.0
53 */
54 @NotThreadSafe
55 public abstract class HttpRequestBase extends AbstractHttpMessage
56 implements HttpUriRequest, AbortableHttpRequest, Cloneable {
58 private Lock abortLock;
60 private boolean aborted;
62 private URI uri;
63 private ClientConnectionRequest connRequest;
64 private ConnectionReleaseTrigger releaseTrigger;
66 public HttpRequestBase() {
67 super();
68 this.abortLock = new ReentrantLock();
69 }
71 public abstract String getMethod();
73 public ProtocolVersion getProtocolVersion() {
74 return HttpProtocolParams.getVersion(getParams());
75 }
77 /**
78 * Returns the original request URI.
79 * <p>
80 * Please note URI remains unchanged in the course of request execution and
81 * is not updated if the request is redirected to another location.
82 */
83 public URI getURI() {
84 return this.uri;
85 }
87 public RequestLine getRequestLine() {
88 String method = getMethod();
89 ProtocolVersion ver = getProtocolVersion();
90 URI uri = getURI();
91 String uritext = null;
92 if (uri != null) {
93 uritext = uri.toASCIIString();
94 }
95 if (uritext == null || uritext.length() == 0) {
96 uritext = "/";
97 }
98 return new BasicRequestLine(method, uritext, ver);
99 }
101 public void setURI(final URI uri) {
102 this.uri = uri;
103 }
105 public void setConnectionRequest(final ClientConnectionRequest connRequest)
106 throws IOException {
107 this.abortLock.lock();
108 try {
109 if (this.aborted) {
110 throw new IOException("Request already aborted");
111 }
113 this.releaseTrigger = null;
114 this.connRequest = connRequest;
115 } finally {
116 this.abortLock.unlock();
117 }
118 }
120 public void setReleaseTrigger(final ConnectionReleaseTrigger releaseTrigger)
121 throws IOException {
122 this.abortLock.lock();
123 try {
124 if (this.aborted) {
125 throw new IOException("Request already aborted");
126 }
128 this.connRequest = null;
129 this.releaseTrigger = releaseTrigger;
130 } finally {
131 this.abortLock.unlock();
132 }
133 }
135 public void abort() {
136 ClientConnectionRequest localRequest;
137 ConnectionReleaseTrigger localTrigger;
139 this.abortLock.lock();
140 try {
141 if (this.aborted) {
142 return;
143 }
144 this.aborted = true;
146 localRequest = connRequest;
147 localTrigger = releaseTrigger;
148 } finally {
149 this.abortLock.unlock();
150 }
152 // Trigger the callbacks outside of the lock, to prevent
153 // deadlocks in the scenario where the callbacks have
154 // their own locks that may be used while calling
155 // setReleaseTrigger or setConnectionRequest.
156 if (localRequest != null) {
157 localRequest.abortRequest();
158 }
159 if (localTrigger != null) {
160 try {
161 localTrigger.abortConnection();
162 } catch (IOException ex) {
163 // ignore
164 }
165 }
166 }
168 public boolean isAborted() {
169 return this.aborted;
170 }
172 @Override
173 public Object clone() throws CloneNotSupportedException {
174 HttpRequestBase clone = (HttpRequestBase) super.clone();
175 clone.abortLock = new ReentrantLock();
176 clone.aborted = false;
177 clone.releaseTrigger = null;
178 clone.connRequest = null;
179 clone.headergroup = (HeaderGroup) CloneUtils.clone(this.headergroup);
180 clone.params = (HttpParams) CloneUtils.clone(this.params);
181 return clone;
182 }
184 }