33import com .loopj .android .http .AsyncHttpClient ;
44import com .loopj .android .http .AsyncHttpResponseHandler ;
55import com .qiniu .android .common .Constants ;
6+ import com .qiniu .android .utils .Dns ;
67
78import org .apache .http .Header ;
89import org .apache .http .HttpEntity ;
1516import java .net .URISyntaxException ;
1617import java .util .Map ;
1718import java .util .Random ;
19+ import java .util .concurrent .ExecutorService ;
20+ import java .util .concurrent .ThreadPoolExecutor ;
1821
1922import static java .lang .String .format ;
2023
@@ -41,9 +44,10 @@ public HttpManager(Proxy proxy, IReport reporter, String backUpIp,
4144 this .backUpIp = backUpIp ;
4245 client = new AsyncHttpClient ();
4346 client .setConnectTimeout (connectTimeout *1000 );
44- client .setResponseTimeout (responseTimeout * 1000 );
47+ client .setResponseTimeout (responseTimeout * 1000 );
4548 client .setUserAgent (userAgent );
46- client .setEnableRedirects (false );
49+ client .setEnableRedirects (true );
50+ client .setRedirectHandler (new UpRedirectHandler ());
4751 AsyncHttpClient .blockRetryExceptionClass (CancellationHandler .CancellationException .class );
4852 if (proxy != null ) {
4953 client .setProxy (proxy .hostAddress , proxy .port , proxy .user , proxy .password );
@@ -97,18 +101,18 @@ private static String getUserAgent() {
97101 * @param completionHandler 发送数据完成后续动作处理对象
98102 */
99103 public void postData (String url , byte [] data , int offset , int size , Header [] headers ,
100- ProgressHandler progressHandler , final CompletionHandler completionHandler , CancellationHandler c ) {
104+ ProgressHandler progressHandler , final CompletionHandler completionHandler , CancellationHandler c , boolean forceIp ) {
101105 ByteArrayEntity entity = new ByteArrayEntity (data , offset , size , progressHandler , c );
102- postEntity (url , entity , headers , progressHandler , completionHandler );
106+ postEntity (url , entity , headers , progressHandler , completionHandler , forceIp );
103107 }
104108
105109 public void postData (String url , byte [] data , Header [] headers , ProgressHandler progressHandler ,
106- CompletionHandler completionHandler , CancellationHandler c ) {
107- postData (url , data , 0 , data .length , headers , progressHandler , completionHandler , c );
110+ CompletionHandler completionHandler , CancellationHandler c , boolean forceIp ) {
111+ postData (url , data , 0 , data .length , headers , progressHandler , completionHandler , c , forceIp );
108112 }
109113
110114 private void postEntity (String url , final HttpEntity entity , Header [] headers ,
111- ProgressHandler progressHandler , CompletionHandler completionHandler ) {
115+ ProgressHandler progressHandler , CompletionHandler completionHandler , final boolean forceIp ) {
112116 final CompletionHandler wrapper = wrap (completionHandler );
113117 final Header [] h = reporter .appendStatHeaders (headers );
114118
@@ -117,32 +121,35 @@ private void postEntity(String url, final HttpEntity entity, Header[] headers,
117121 }
118122
119123 final AsyncHttpResponseHandler originHandler = new ResponseHandler (url , wrapper , progressHandler );
120- if (backUpIp == null ){
124+ if (backUpIp == null || converter != null ){
121125 client .post (null , url , h , entity , null , originHandler );
122126 return ;
123127 }
124128 final String url2 = url ;
125- client .post (null , url , h , entity , null , new ResponseHandler (url , new CompletionHandler () {
129+
130+ ExecutorService t = client .getThreadPool ();
131+ t .execute (new Runnable () {
126132 @ Override
127- public void complete (ResponseInfo info , JSONObject response ) {
128- if (info .statusCode != ResponseInfo .UnknownHost ){
129- wrapper .complete (info , response );
130- return ;
133+ public void run () {
134+ URI uri = URI .create (url2 );
135+ String ip = Dns .getAddress (uri .getHost ());
136+ if (ip == null || ip .equals ("" ) || forceIp ) {
137+ ip = backUpIp ;
131138 }
139+
132140 Header [] h2 = new Header [h .length + 1 ];
133141 System .arraycopy (h , 0 , h2 , 0 , h .length );
134142
135- URI uri = URI .create (url2 );
136143 String newUrl = null ;
137144 try {
138- newUrl = new URI (uri .getScheme (), null , backUpIp , uri .getPort (), uri .getPath (), uri .getQuery (), null ).toString ();
145+ newUrl = new URI (uri .getScheme (), null , ip , uri .getPort (), uri .getPath (), uri .getQuery (), null ).toString ();
139146 } catch (URISyntaxException e ) {
140147 throw new AssertionError (e );
141148 }
142149 h2 [h .length ] = new BasicHeader ("Host" , uri .getHost ());
143150 client .post (null , newUrl , h2 , entity , null , originHandler );
144151 }
145- }, progressHandler ) );
152+ });
146153 }
147154
148155 /**
@@ -154,7 +161,7 @@ public void complete(ResponseInfo info, JSONObject response) {
154161 * @param completionHandler 发送数据完成后续动作处理对象
155162 */
156163 public void multipartPost (String url , PostArgs args , ProgressHandler progressHandler ,
157- final CompletionHandler completionHandler , CancellationHandler c ) {
164+ final CompletionHandler completionHandler , CancellationHandler c , boolean forceIp ) {
158165 MultipartBuilder mbuilder = new MultipartBuilder ();
159166 for (Map .Entry <String , String > entry : args .params .entrySet ()) {
160167 mbuilder .addPart (entry .getKey (), entry .getValue ());
@@ -178,7 +185,7 @@ public void multipartPost(String url, PostArgs args, ProgressHandler progressHan
178185
179186 ByteArrayEntity entity = mbuilder .build (progressHandler , c );
180187 Header [] h = reporter .appendStatHeaders (new Header [0 ]);
181- postEntity (url , entity , h , progressHandler , completionHandler );
188+ postEntity (url , entity , h , progressHandler , completionHandler , forceIp );
182189 }
183190
184191 private CompletionHandler wrap (final CompletionHandler completionHandler ) {
@@ -194,40 +201,4 @@ public void complete(ResponseInfo info, JSONObject response) {
194201 }
195202 };
196203 }
197-
198- /**
199- * fixed key escape for async http client
200- * Appends a quoted-string to a StringBuilder.
201- * <p/>
202- * <p>RFC 2388 is rather vague about how one should escape special characters
203- * in form-data parameters, and as it turns out Firefox and Chrome actually
204- * do rather different things, and both say in their comments that they're
205- * not really sure what the right approach is. We go with Chrome's behavior
206- * (which also experimentally seems to match what IE does), but if you
207- * actually want to have a good chance of things working, please avoid
208- * double-quotes, newlines, percent signs, and the like in your field names.
209- */
210- private static String escapeMultipartString (String key ) {
211- StringBuilder target = new StringBuilder ();
212-
213- for (int i = 0 , len = key .length (); i < len ; i ++) {
214- char ch = key .charAt (i );
215- switch (ch ) {
216- case '\n' :
217- target .append ("%0A" );
218- break ;
219- case '\r' :
220- target .append ("%0D" );
221- break ;
222- case '"' :
223- target .append ("%22" );
224- break ;
225- default :
226- target .append (ch );
227- break ;
228- }
229- }
230- return target .toString ();
231- }
232-
233204}
0 commit comments