OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.net.urlconnection; | 5 package org.chromium.net.urlconnection; |
6 | 6 |
7 import android.os.Build; | 7 import android.os.Build; |
8 import android.test.suitebuilder.annotation.SmallTest; | 8 import android.test.suitebuilder.annotation.SmallTest; |
9 | 9 |
10 import org.chromium.base.annotations.SuppressFBWarnings; | 10 import org.chromium.base.annotations.SuppressFBWarnings; |
11 import org.chromium.base.test.util.Feature; | 11 import org.chromium.base.test.util.Feature; |
12 import org.chromium.net.CronetTestActivity; | 12 import org.chromium.net.CronetTestActivity; |
13 import org.chromium.net.CronetTestBase; | 13 import org.chromium.net.CronetTestBase; |
14 import org.chromium.net.MockUrlRequestJobFactory; | 14 import org.chromium.net.MockUrlRequestJobFactory; |
15 import org.chromium.net.NativeTestServer; | 15 import org.chromium.net.NativeTestServer; |
16 import org.chromium.net.UrlRequestContextConfig; | 16 import org.chromium.net.UrlRequestContextConfig; |
17 import org.chromium.net.UrlRequestException; | 17 import org.chromium.net.UrlRequestException; |
18 | 18 |
19 import java.io.ByteArrayOutputStream; | 19 import java.io.ByteArrayOutputStream; |
20 import java.io.FileNotFoundException; | 20 import java.io.FileNotFoundException; |
21 import java.io.IOException; | 21 import java.io.IOException; |
22 import java.io.InputStream; | 22 import java.io.InputStream; |
| 23 import java.io.OutputStream; |
| 24 import java.lang.reflect.Method; |
23 import java.net.HttpURLConnection; | 25 import java.net.HttpURLConnection; |
24 import java.net.MalformedURLException; | 26 import java.net.MalformedURLException; |
25 import java.net.URL; | 27 import java.net.URL; |
26 import java.util.ArrayList; | 28 import java.util.ArrayList; |
27 import java.util.Arrays; | 29 import java.util.Arrays; |
28 import java.util.List; | 30 import java.util.List; |
29 import java.util.Map; | 31 import java.util.Map; |
30 import java.util.regex.Matcher; | 32 import java.util.regex.Matcher; |
31 import java.util.regex.Pattern; | 33 import java.util.regex.Pattern; |
32 | 34 |
33 /** | 35 /** |
34 * Basic tests of Cronet's HttpURLConnection implementation. | 36 * Basic tests of Cronet's HttpURLConnection implementation. |
35 * Tests annotated with {@code CompareDefaultWithCronet} will run once with the | 37 * Tests annotated with {@code CompareDefaultWithCronet} will run once with the |
36 * default HttpURLConnection implementation and then with Cronet's | 38 * default HttpURLConnection implementation and then with Cronet's |
37 * HttpURLConnection implementation. Tests annotated with | 39 * HttpURLConnection implementation. Tests annotated with |
38 * {@code OnlyRunCronetHttpURLConnection} only run Cronet's implementation. | 40 * {@code OnlyRunCronetHttpURLConnection} only run Cronet's implementation. |
39 * See {@link CronetTestBase#runTest()} for details. | 41 * See {@link CronetTestBase#runTest()} for details. |
40 */ | 42 */ |
41 public class CronetHttpURLConnectionTest extends CronetTestBase { | 43 public class CronetHttpURLConnectionTest extends CronetTestBase { |
42 private CronetTestActivity mActivity; | |
43 | 44 |
44 @Override | 45 @Override |
45 protected void setUp() throws Exception { | 46 protected void setUp() throws Exception { |
46 super.setUp(); | 47 super.setUp(); |
47 UrlRequestContextConfig config = new UrlRequestContextConfig(); | 48 UrlRequestContextConfig config = new UrlRequestContextConfig(); |
48 config.setStoragePath(prepareTestStorage()); | 49 config.setStoragePath(prepareTestStorage()); |
49 config.enableHttpCache(UrlRequestContextConfig.HttpCache.DISK, | 50 config.enableHttpCache(UrlRequestContextConfig.HttpCache.DISK, |
50 1000 * 1024); | 51 1000 * 1024); |
51 String[] commandLineArgs = { | 52 String[] commandLineArgs = { |
52 CronetTestActivity.CONFIG_KEY, config.toString()}; | 53 CronetTestActivity.CONFIG_KEY, config.toString()}; |
53 mActivity = launchCronetTestAppWithUrlAndCommandLineArgs(null, | 54 launchCronetTestAppWithUrlAndCommandLineArgs(null, |
54 commandLineArgs); | 55 commandLineArgs); |
55 assertTrue(NativeTestServer.startNativeTestServer( | 56 assertTrue(NativeTestServer.startNativeTestServer( |
56 getInstrumentation().getTargetContext())); | 57 getInstrumentation().getTargetContext())); |
57 } | 58 } |
58 | 59 |
59 @Override | 60 @Override |
60 protected void tearDown() throws Exception { | 61 protected void tearDown() throws Exception { |
61 NativeTestServer.shutdownNativeTestServer(); | 62 NativeTestServer.shutdownNativeTestServer(); |
62 super.tearDown(); | 63 super.tearDown(); |
63 } | 64 } |
64 | 65 |
65 @SmallTest | 66 @SmallTest |
66 @Feature({"Cronet"}) | 67 @Feature({"Cronet"}) |
67 @CompareDefaultWithCronet | 68 @CompareDefaultWithCronet |
68 public void testBasicGet() throws Exception { | 69 public void testBasicGet() throws Exception { |
69 URL url = new URL(NativeTestServer.getEchoMethodURL()); | 70 URL url = new URL(NativeTestServer.getEchoMethodURL()); |
70 HttpURLConnection urlConnection = | 71 HttpURLConnection urlConnection = |
71 (HttpURLConnection) url.openConnection(); | 72 (HttpURLConnection) url.openConnection(); |
72 assertEquals(200, urlConnection.getResponseCode()); | 73 assertEquals(200, urlConnection.getResponseCode()); |
73 assertEquals("OK", urlConnection.getResponseMessage()); | 74 assertEquals("OK", urlConnection.getResponseMessage()); |
74 assertEquals("GET", getResponseAsString(urlConnection)); | 75 assertEquals("GET", getResponseAsString(urlConnection)); |
75 urlConnection.disconnect(); | 76 urlConnection.disconnect(); |
76 } | 77 } |
77 | 78 |
| 79 /** |
| 80 * Tests that using reflection to find {@code fixedContentLengthLong} works. |
| 81 */ |
| 82 @SmallTest |
| 83 @Feature({"Cronet"}) |
| 84 @OnlyRunCronetHttpURLConnection |
| 85 public void testSetFixedLengthStreamingModeLong() throws Exception { |
| 86 URL url = new URL(NativeTestServer.getEchoBodyURL()); |
| 87 HttpURLConnection connection = |
| 88 (HttpURLConnection) url.openConnection(); |
| 89 connection.setDoOutput(true); |
| 90 connection.setRequestMethod("POST"); |
| 91 if (Build.VERSION.SDK_INT >= 19) { |
| 92 String dataString = "some very important data"; |
| 93 byte[] data = dataString.getBytes(); |
| 94 Class<?> c = connection.getClass(); |
| 95 Method method = c.getMethod("setFixedLengthStreamingMode", |
| 96 new Class[] {long.class}); |
| 97 method.invoke(connection, (long) data.length); |
| 98 OutputStream out = connection.getOutputStream(); |
| 99 out.write(data); |
| 100 assertEquals(200, connection.getResponseCode()); |
| 101 assertEquals("OK", connection.getResponseMessage()); |
| 102 assertEquals(dataString, getResponseAsString(connection)); |
| 103 connection.disconnect(); |
| 104 } |
| 105 } |
| 106 |
| 107 @SmallTest |
| 108 @Feature({"Cronet"}) |
| 109 @OnlyRunCronetHttpURLConnection |
| 110 // TODO(xunjieli): Change the test after chunked support is added. |
| 111 public void testPostChunked() throws Exception { |
| 112 URL url = new URL(NativeTestServer.getEchoBodyURL()); |
| 113 HttpURLConnection connection = |
| 114 (HttpURLConnection) url.openConnection(); |
| 115 connection.setDoOutput(true); |
| 116 connection.setRequestMethod("POST"); |
| 117 try { |
| 118 connection.setChunkedStreamingMode(0); |
| 119 } catch (UnsupportedOperationException e) { |
| 120 assertEquals("Chunked mode not supported yet", e.getMessage()); |
| 121 } |
| 122 } |
| 123 |
78 @SmallTest | 124 @SmallTest |
79 @Feature({"Cronet"}) | 125 @Feature({"Cronet"}) |
80 @CompareDefaultWithCronet | 126 @CompareDefaultWithCronet |
81 public void testNotFoundURLRequest() throws Exception { | 127 public void testNotFoundURLRequest() throws Exception { |
82 URL url = new URL(NativeTestServer.getFileURL("/notfound.html")); | 128 URL url = new URL(NativeTestServer.getFileURL("/notfound.html")); |
83 HttpURLConnection urlConnection = | 129 HttpURLConnection urlConnection = |
84 (HttpURLConnection) url.openConnection(); | 130 (HttpURLConnection) url.openConnection(); |
85 assertEquals(404, urlConnection.getResponseCode()); | 131 assertEquals(404, urlConnection.getResponseCode()); |
86 assertEquals("Not Found", urlConnection.getResponseMessage()); | 132 assertEquals("Not Found", urlConnection.getResponseMessage()); |
87 try { | 133 try { |
(...skipping 22 matching lines...) Expand all Loading... |
110 URL url = new URL(NativeTestServer.getFileURL("/success.txt")); | 156 URL url = new URL(NativeTestServer.getFileURL("/success.txt")); |
111 HttpURLConnection urlConnection = | 157 HttpURLConnection urlConnection = |
112 (HttpURLConnection) url.openConnection(); | 158 (HttpURLConnection) url.openConnection(); |
113 assertEquals("this is a text file\n", | 159 assertEquals("this is a text file\n", |
114 getResponseAsString(urlConnection)); | 160 getResponseAsString(urlConnection)); |
115 // After shutting down the server, the server should not be handling | 161 // After shutting down the server, the server should not be handling |
116 // new requests. | 162 // new requests. |
117 NativeTestServer.shutdownNativeTestServer(); | 163 NativeTestServer.shutdownNativeTestServer(); |
118 HttpURLConnection secondConnection = | 164 HttpURLConnection secondConnection = |
119 (HttpURLConnection) url.openConnection(); | 165 (HttpURLConnection) url.openConnection(); |
| 166 // Default implementation reports this type of error in connect(). |
| 167 // However, since Cronet's wrapper only receives the error in its listen
er |
| 168 // callback when message loop is running, Cronet's wrapper only knows |
| 169 // about the error when it starts to read response. |
120 try { | 170 try { |
121 secondConnection.connect(); | 171 secondConnection.getResponseCode(); |
122 fail(); | 172 fail(); |
123 } catch (IOException e) { | 173 } catch (IOException e) { |
124 assertTrue(e instanceof java.net.ConnectException | 174 assertTrue(e instanceof java.net.ConnectException |
125 || e instanceof UrlRequestException); | 175 || e instanceof UrlRequestException); |
126 assertTrue((e.getMessage().contains("ECONNREFUSED") | 176 assertTrue((e.getMessage().contains("ECONNREFUSED") |
127 || e.getMessage().contains("net::ERR_CONNECTION_REFUSED"))); | 177 || e.getMessage().contains("net::ERR_CONNECTION_REFUSED"))); |
128 } | 178 } |
129 checkExceptionsAreThrown(secondConnection); | 179 checkExceptionsAreThrown(secondConnection); |
130 // Starts the server to avoid crashing on shutdown in tearDown(). | 180 // Starts the server to avoid crashing on shutdown in tearDown(). |
131 assertTrue(NativeTestServer.startNativeTestServer( | 181 assertTrue(NativeTestServer.startNativeTestServer( |
132 getInstrumentation().getTargetContext())); | 182 getInstrumentation().getTargetContext())); |
133 } | 183 } |
134 | 184 |
135 @SmallTest | 185 @SmallTest |
136 @Feature({"Cronet"}) | 186 @Feature({"Cronet"}) |
137 @CompareDefaultWithCronet | 187 @CompareDefaultWithCronet |
138 public void testBadIP() throws Exception { | 188 public void testBadIP() throws Exception { |
139 URL url = new URL("http://0.0.0.0/"); | 189 URL url = new URL("http://0.0.0.0/"); |
140 HttpURLConnection urlConnection = | 190 HttpURLConnection urlConnection = |
141 (HttpURLConnection) url.openConnection(); | 191 (HttpURLConnection) url.openConnection(); |
| 192 // Default implementation reports this type of error in connect(). |
| 193 // However, since Cronet's wrapper only receives the error in its listen
er |
| 194 // callback when message loop is running, Cronet's wrapper only knows |
| 195 // about the error when it starts to read response. |
142 try { | 196 try { |
143 urlConnection.connect(); | 197 urlConnection.getResponseCode(); |
144 fail(); | 198 fail(); |
145 } catch (IOException e) { | 199 } catch (IOException e) { |
146 assertTrue(e instanceof java.net.ConnectException | 200 assertTrue(e instanceof java.net.ConnectException |
147 || e instanceof UrlRequestException); | 201 || e instanceof UrlRequestException); |
148 assertTrue((e.getMessage().contains("ECONNREFUSED") | 202 assertTrue((e.getMessage().contains("ECONNREFUSED") |
149 || e.getMessage().contains("net::ERR_CONNECTION_REFUSED"))); | 203 || e.getMessage().contains("net::ERR_CONNECTION_REFUSED"))); |
150 } | 204 } |
151 checkExceptionsAreThrown(urlConnection); | 205 checkExceptionsAreThrown(urlConnection); |
152 } | 206 } |
153 | 207 |
154 @SmallTest | 208 @SmallTest |
155 @Feature({"Cronet"}) | 209 @Feature({"Cronet"}) |
156 @CompareDefaultWithCronet | 210 @CompareDefaultWithCronet |
157 public void testBadHostname() throws Exception { | 211 public void testBadHostname() throws Exception { |
158 URL url = new URL("http://this-weird-host-name-does-not-exist/"); | 212 URL url = new URL("http://this-weird-host-name-does-not-exist/"); |
159 HttpURLConnection urlConnection = | 213 HttpURLConnection urlConnection = |
160 (HttpURLConnection) url.openConnection(); | 214 (HttpURLConnection) url.openConnection(); |
| 215 // Default implementation reports this type of error in connect(). |
| 216 // However, since Cronet's wrapper only receives the error in its listen
er |
| 217 // callback when message loop is running, Cronet's wrapper only knows |
| 218 // about the error when it starts to read response. |
161 try { | 219 try { |
162 urlConnection.connect(); | 220 urlConnection.getResponseCode(); |
163 fail(); | 221 fail(); |
164 } catch (java.net.UnknownHostException e) { | 222 } catch (java.net.UnknownHostException e) { |
165 // Expected. | 223 // Expected. |
166 } catch (UrlRequestException e) { | 224 } catch (UrlRequestException e) { |
167 // Expected. | 225 // Expected. |
168 } | 226 } |
169 checkExceptionsAreThrown(urlConnection); | 227 checkExceptionsAreThrown(urlConnection); |
170 } | 228 } |
171 | 229 |
172 @SuppressFBWarnings("DLS_DEAD_LOCAL_STORE") | 230 @SuppressFBWarnings("DLS_DEAD_LOCAL_STORE") |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 InputStream in = urlConnection.getInputStream(); | 277 InputStream in = urlConnection.getInputStream(); |
220 fail(); | 278 fail(); |
221 } catch (Exception e) { | 279 } catch (Exception e) { |
222 // Ignored. | 280 // Ignored. |
223 } | 281 } |
224 } | 282 } |
225 | 283 |
226 @SmallTest | 284 @SmallTest |
227 @Feature({"Cronet"}) | 285 @Feature({"Cronet"}) |
228 @CompareDefaultWithCronet | 286 @CompareDefaultWithCronet |
| 287 public void testMultipleDisconnect() throws Exception { |
| 288 URL url = new URL(NativeTestServer.getEchoMethodURL()); |
| 289 HttpURLConnection urlConnection = |
| 290 (HttpURLConnection) url.openConnection(); |
| 291 assertEquals(200, urlConnection.getResponseCode()); |
| 292 assertEquals("OK", urlConnection.getResponseMessage()); |
| 293 assertEquals("GET", getResponseAsString(urlConnection)); |
| 294 // Disconnect multiple times should be fine. |
| 295 for (int i = 0; i < 10; i++) { |
| 296 urlConnection.disconnect(); |
| 297 } |
| 298 } |
| 299 |
| 300 @SmallTest |
| 301 @Feature({"Cronet"}) |
| 302 @CompareDefaultWithCronet |
229 public void testAddRequestProperty() throws Exception { | 303 public void testAddRequestProperty() throws Exception { |
230 URL url = new URL(NativeTestServer.getEchoAllHeadersURL()); | 304 URL url = new URL(NativeTestServer.getEchoAllHeadersURL()); |
231 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); | 305 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); |
232 connection.addRequestProperty("foo-header", "foo"); | 306 connection.addRequestProperty("foo-header", "foo"); |
233 connection.addRequestProperty("bar-header", "bar"); | 307 connection.addRequestProperty("bar-header", "bar"); |
234 | 308 |
235 // Before connection is made, check request headers are set. | 309 // Before connection is made, check request headers are set. |
236 Map<String, List<String>> requestHeadersMap = | 310 Map<String, List<String>> requestHeadersMap = |
237 connection.getRequestProperties(); | 311 connection.getRequestProperties(); |
238 List<String> fooValues = requestHeadersMap.get("foo-header"); | 312 List<String> fooValues = requestHeadersMap.get("foo-header"); |
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 CacheSetting.USE_CACHE, ExpectedOutcome.SUCCESS); | 947 CacheSetting.USE_CACHE, ExpectedOutcome.SUCCESS); |
874 NativeTestServer.shutdownNativeTestServer(); | 948 NativeTestServer.shutdownNativeTestServer(); |
875 // Disables caching. No cached response is received. | 949 // Disables caching. No cached response is received. |
876 checkRequestCaching(url, | 950 checkRequestCaching(url, |
877 CacheSetting.DONT_USE_CACHE, ExpectedOutcome.FAILURE); | 951 CacheSetting.DONT_USE_CACHE, ExpectedOutcome.FAILURE); |
878 } | 952 } |
879 | 953 |
880 private void checkExceptionsAreThrown(HttpURLConnection connection) | 954 private void checkExceptionsAreThrown(HttpURLConnection connection) |
881 throws Exception { | 955 throws Exception { |
882 try { | 956 try { |
883 connection.connect(); | |
884 fail(); | |
885 } catch (IOException e) { | |
886 // Expected. | |
887 } | |
888 | |
889 try { | |
890 connection.getInputStream(); | 957 connection.getInputStream(); |
891 fail(); | 958 fail(); |
892 } catch (IOException e) { | 959 } catch (IOException e) { |
893 // Expected. | 960 // Expected. |
894 } | 961 } |
895 | 962 |
896 try { | 963 try { |
897 connection.getResponseCode(); | 964 connection.getResponseCode(); |
898 fail(); | 965 fail(); |
899 } catch (IOException e) { | 966 } catch (IOException e) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 String headerName) { | 1014 String headerName) { |
948 Pattern pattern = Pattern.compile(headerName + ":\\s(.*)\\r\\n"); | 1015 Pattern pattern = Pattern.compile(headerName + ":\\s(.*)\\r\\n"); |
949 Matcher matcher = pattern.matcher(allHeaders); | 1016 Matcher matcher = pattern.matcher(allHeaders); |
950 List<String> headerValues = new ArrayList<String>(); | 1017 List<String> headerValues = new ArrayList<String>(); |
951 while (matcher.find()) { | 1018 while (matcher.find()) { |
952 headerValues.add(matcher.group(1)); | 1019 headerValues.add(matcher.group(1)); |
953 } | 1020 } |
954 return headerValues; | 1021 return headerValues; |
955 } | 1022 } |
956 } | 1023 } |
OLD | NEW |