OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/cronet/android/org_chromium_net_UrlRequest.h" | |
szym
2014/02/28 00:50:40
After reading some more on the https://code.google
mef
2014/03/03 19:15:13
Sounds good. Added TODO for now.
| |
6 | |
7 #include <stdio.h> | |
8 | |
9 #include "net/base/net_errors.h" | |
10 #include "net/base/request_priority.h" | |
11 #include "net/cronet/android/org_chromium_net_UrlRequestContext.h" | |
12 #include "net/cronet/android/url_request_context_peer.h" | |
13 #include "net/cronet/android/url_request_peer.h" | |
14 | |
15 #define LOG_TAG "ChromiumNetwork" | |
mmenke
2014/02/27 23:06:02
this isn't used in this file
mef
2014/03/03 19:15:13
Done.
| |
16 | |
17 static jclass g_class; | |
18 static jmethodID g_method_finish; | |
19 static jmethodID g_method_onAppendChunkCompleted; | |
20 static jmethodID g_method_onResponseStarted; | |
21 static jmethodID g_method_onReadBytes; | |
22 static jclass g_class_OutputStream; | |
23 static jmethodID g_method_write; | |
24 static jfieldID g_request_field; | |
mmenke
2014/02/27 23:06:02
Suggest just putting all these in an anonymous nam
mmenke
2014/02/27 23:06:02
Most of these names violate the Google C++ style g
mef
2014/03/03 19:15:13
Done.
mef
2014/03/03 19:15:13
I'll address this as part of migration to generate
| |
25 | |
26 // Find Java classes and retain them. | |
27 bool UrlRequestRegisterJni(JNIEnv* env) { | |
28 g_class = (jclass) env->NewGlobalRef( | |
29 env->FindClass("org/chromium/net/UrlRequest")); | |
30 g_method_finish = env->GetMethodID(g_class, "finish", "()V"); | |
31 g_method_onAppendChunkCompleted = | |
32 env->GetMethodID(g_class, "onAppendChunkCompleted", "()V"); | |
33 g_method_onResponseStarted = | |
34 env->GetMethodID(g_class, "onResponseStarted", "()V"); | |
35 g_method_onReadBytes = env->GetMethodID(g_class, "onBytesRead", | |
36 "(Ljava/nio/ByteBuffer;)V"); | |
37 g_request_field = env->GetFieldID(g_class, "mRequest", "J"); | |
38 | |
39 g_class_OutputStream = (jclass) env->NewGlobalRef( | |
40 env->FindClass("java/io/OutputStream")); | |
41 g_method_write = env->GetMethodID(g_class_OutputStream, "write", "([BII)V"); | |
42 | |
43 if (!g_class | |
44 || !g_method_finish | |
45 || !g_method_onAppendChunkCompleted | |
46 || !g_method_onResponseStarted | |
47 || !g_method_onReadBytes | |
48 || !g_request_field | |
49 || !g_class_OutputStream | |
50 || !g_method_write) { | |
mmenke
2014/02/27 23:06:02
While this is the right style for Java, and allowe
mef
2014/03/03 19:15:13
Done.
| |
51 return false; | |
52 } | |
53 return true; | |
54 } | |
55 | |
56 static net::RequestPriority ConvertRequestPriority(jint request_priority) { | |
mmenke
2014/02/27 23:06:02
static is not used very often before functions in
mef
2014/03/03 19:15:13
Done.
| |
57 switch (request_priority) { | |
58 case REQUEST_PRIORITY_IDLE: return net::IDLE; | |
59 case REQUEST_PRIORITY_LOWEST: return net::LOWEST; | |
60 case REQUEST_PRIORITY_LOW: return net::LOW; | |
61 case REQUEST_PRIORITY_MEDIUM: return net::MEDIUM; | |
62 case REQUEST_PRIORITY_HIGHEST: return net::HIGHEST; | |
63 default: return net::LOWEST; | |
mmenke
2014/02/27 23:06:02
Put all the returns on the next lines.
mef
2014/03/03 19:15:13
Done.
| |
64 } | |
65 } | |
66 | |
67 /* | |
68 * A delegate of URLRequestPeer that delivers callbacks to the Java layer. | |
69 */ | |
mmenke
2014/02/27 23:06:02
Use C++-style comments. (Goes for entire file)
mef
2014/03/03 19:15:13
Done.
| |
70 class JniURLRequestPeerDelegate : | |
71 public URLRequestPeer::URLRequestPeerDelegate { | |
72 jobject owner_; | |
73 JavaVM* vm_; | |
mmenke
2014/02/27 23:06:02
These should go in a private section at the bottom
mef
2014/03/03 19:15:13
Done.
| |
74 | |
75 public: | |
76 JniURLRequestPeerDelegate(JNIEnv* env, jobject owner) { | |
77 owner_ = env->NewGlobalRef(owner); | |
78 env->GetJavaVM(&vm_); | |
79 } | |
80 | |
81 virtual void OnAppendChunkCompleted(URLRequestPeer* request) OVERRIDE { | |
82 JNIEnv* env = GetEnv(vm_); | |
83 env->CallVoidMethod(owner_, g_method_onAppendChunkCompleted); | |
84 if (env->ExceptionOccurred()) { | |
85 env->ExceptionDescribe(); | |
86 env->ExceptionClear(); | |
87 } | |
88 } | |
89 | |
90 virtual void OnResponseStarted(URLRequestPeer* request) OVERRIDE { | |
91 JNIEnv* env = GetEnv(vm_); | |
92 env->CallVoidMethod(owner_, g_method_onResponseStarted); | |
93 if (env->ExceptionOccurred()) { | |
94 env->ExceptionDescribe(); | |
95 env->ExceptionClear(); | |
96 } | |
97 } | |
98 | |
99 virtual void OnBytesRead(URLRequestPeer* request) OVERRIDE { | |
100 int bytes_read = request->BytesRead(); | |
101 if (bytes_read != 0) { | |
102 JNIEnv* env = GetEnv(vm_); | |
103 jobject bytebuf = env->NewDirectByteBuffer(request->Data(), bytes_read); | |
104 env->CallVoidMethod(owner_, g_method_onReadBytes, bytebuf); | |
105 env->DeleteLocalRef(bytebuf); | |
106 if (env->ExceptionOccurred()) { | |
107 env->ExceptionDescribe(); | |
108 env->ExceptionClear(); | |
109 } | |
110 } | |
111 } | |
112 | |
113 virtual void OnRequestFinished(URLRequestPeer* request) OVERRIDE { | |
114 JNIEnv* env = GetEnv(vm_); | |
115 env->CallVoidMethod(owner_, g_method_finish); | |
116 if (env->ExceptionOccurred()) { | |
117 env->ExceptionDescribe(); | |
118 env->ExceptionClear(); | |
119 } | |
120 } | |
121 | |
122 protected: | |
123 virtual ~JniURLRequestPeerDelegate() { | |
124 GetEnv(vm_)->DeleteGlobalRef(owner_); | |
125 } | |
126 }; | |
127 | |
128 /* | |
129 * Stores a reference to the request in a java field. | |
mmenke
2014/02/27 23:06:02
Should Java be capitalized in comments?
mef
2014/03/03 19:15:13
Done.
| |
130 */ | |
131 static void SetNativeObject(JNIEnv *env, jobject object, | |
mmenke
2014/02/27 23:06:02
Static methods should be moved to the anonymous na
mef
2014/03/03 19:15:13
Done.
| |
132 URLRequestPeer* request) { | |
133 env->SetLongField(object, g_request_field, | |
134 reinterpret_cast<jlong>(request)); | |
135 } | |
136 | |
137 /* | |
138 * Returns a reference to the request, which is stored in a field of | |
139 * the java object. | |
140 */ | |
141 static URLRequestPeer* GetNativeObject(JNIEnv* env, jobject object) { | |
142 return reinterpret_cast<URLRequestPeer *>( | |
143 env->GetLongField(object, g_request_field)); | |
144 } | |
145 | |
146 JNIEXPORT void JNICALL | |
147 Java_org_chromium_net_UrlRequest_nativeInit( | |
mmenke
2014/02/27 23:06:02
Maybe be able to move all these up a line.
mef
2014/03/03 19:15:13
Done.
| |
148 JNIEnv* env, jobject object, jobject request_context, jstring url_string, | |
149 jint priority) { | |
150 URLRequestContextPeer* context = | |
151 GetURLRequestContextPeer(env, request_context); | |
152 CHECK(context != NULL); | |
mmenke
2014/02/27 23:06:02
DCHECK?
mef
2014/03/03 19:15:13
Done.
| |
153 | |
154 const char *url_utf8 = env->GetStringUTFChars(url_string, NULL); | |
mmenke
2014/02/27 23:06:02
Should be char* url_utf8.
mef
2014/03/03 19:15:13
Done.
| |
155 | |
156 DVLOG(context->logging_level()) | |
157 << "New chromium network request. URL:" << url_utf8; | |
158 | |
159 GURL url(url_utf8); | |
160 | |
161 env->ReleaseStringUTFChars(url_string, url_utf8); | |
162 | |
163 URLRequestPeer* request = | |
164 new URLRequestPeer(context, new JniURLRequestPeerDelegate(env, object), | |
165 url, ConvertRequestPriority(priority)); | |
166 | |
167 SetNativeObject(env, object, request); | |
168 } | |
169 | |
170 /* synchronized */ | |
171 JNIEXPORT void JNICALL | |
172 Java_org_chromium_net_UrlRequest_nativeAddHeader( | |
173 JNIEnv* env, jobject object, jstring name, jstring value) { | |
174 URLRequestPeer* request = GetNativeObject(env, object); | |
175 CHECK(request != NULL); | |
mmenke
2014/02/27 23:06:02
DCHECK?
mef
2014/03/03 19:15:13
Done.
| |
176 | |
177 const char *name_utf8 = env->GetStringUTFChars(name, NULL); | |
178 std::string name_string(name_utf8); | |
179 env->ReleaseStringUTFChars(name, name_utf8); | |
180 | |
181 const char *value_utf8 = env->GetStringUTFChars(value, NULL); | |
182 std::string value_string(value_utf8); | |
183 env->ReleaseStringUTFChars(value, value_utf8); | |
184 | |
185 request->AddHeader(name_string, value_string); | |
186 } | |
187 | |
188 static void SetPostContentType(JNIEnv *env, URLRequestPeer* request, | |
189 jstring content_type) { | |
mmenke
2014/02/27 23:06:02
Statics up top, -static
mef
2014/03/03 19:15:13
Done.
| |
190 CHECK(request != NULL); | |
mmenke
2014/02/27 23:06:02
DCHECK?
mef
2014/03/03 19:15:13
Done.
| |
191 | |
192 std::string method_post("POST"); | |
193 request->SetMethod(method_post); | |
194 | |
195 std::string content_type_header("Content-Type"); | |
196 | |
197 const char *content_type_utf8 = env->GetStringUTFChars(content_type, NULL); | |
mmenke
2014/02/27 23:06:02
char* content_...
mef
2014/03/03 19:15:13
Done.
| |
198 std::string content_type_string(content_type_utf8); | |
199 env->ReleaseStringUTFChars(content_type, content_type_utf8); | |
200 | |
201 request->AddHeader(content_type_header, content_type_string); | |
202 } | |
203 | |
204 JNIEXPORT void JNICALL | |
205 Java_org_chromium_net_UrlRequest_nativeSetPostData( | |
206 JNIEnv* env, jobject object, jstring content_type, jbyteArray content) { | |
207 URLRequestPeer* request = GetNativeObject(env, object); | |
208 SetPostContentType(env, request, content_type); | |
209 | |
210 if (content != NULL) { | |
211 jsize size = env->GetArrayLength(content); | |
212 if (size > 0) { | |
213 jbyte* content_bytes = env->GetByteArrayElements(content, NULL); | |
214 request->SetPostContent(reinterpret_cast<const char*>(content_bytes), | |
215 size); | |
216 env->ReleaseByteArrayElements(content, content_bytes, 0); | |
217 } | |
218 } | |
219 } | |
220 | |
221 JNIEXPORT void JNICALL | |
222 Java_org_chromium_net_UrlRequest_nativeBeginChunkedUpload( | |
223 JNIEnv* env, jobject object, jstring content_type) { | |
224 URLRequestPeer* request = GetNativeObject(env, object); | |
225 SetPostContentType(env, request, content_type); | |
226 | |
227 request->EnableStreamingUpload(); | |
228 } | |
229 | |
230 JNIEXPORT void JNICALL | |
231 Java_org_chromium_net_UrlRequest_nativeAppendChunk( | |
232 JNIEnv* env, jobject object, jobject chunk_byte_buffer, jint chunk_size, | |
233 jboolean is_last_chunk) { | |
234 URLRequestPeer* request = GetNativeObject(env, object); | |
235 CHECK(request != NULL); | |
236 | |
237 if (chunk_byte_buffer != NULL) { | |
238 void* chunk = env->GetDirectBufferAddress(chunk_byte_buffer); | |
239 request->AppendChunk(reinterpret_cast<const char*>(chunk), | |
240 chunk_size, is_last_chunk); | |
241 } | |
242 } | |
243 | |
244 /* synchronized */ | |
245 JNIEXPORT void JNICALL | |
246 Java_org_chromium_net_UrlRequest_nativeStart( | |
247 JNIEnv* env, jobject object) { | |
248 URLRequestPeer* request = GetNativeObject(env, object); | |
249 if (request != NULL) { | |
250 request->Start(); | |
251 } | |
252 } | |
253 | |
254 /* synchronized */ | |
255 JNIEXPORT void JNICALL | |
256 Java_org_chromium_net_UrlRequest_nativeRecycle( | |
257 JNIEnv* env, jobject object) { | |
258 URLRequestPeer* request = GetNativeObject(env, object); | |
259 if (request != NULL) { | |
260 request->Destroy(); | |
261 } | |
262 | |
263 SetNativeObject(env, object, NULL); | |
264 } | |
265 | |
266 /* synchronized */ | |
267 JNIEXPORT void JNICALL | |
268 Java_org_chromium_net_UrlRequest_nativeCancel( | |
269 JNIEnv* env, jobject object) { | |
270 URLRequestPeer* request = GetNativeObject(env, object); | |
271 if (request != NULL) { | |
272 request->Cancel(); | |
273 } | |
274 } | |
275 | |
276 JNIEXPORT jint JNICALL | |
277 Java_org_chromium_net_UrlRequest_nativeGetErrorCode( | |
278 JNIEnv* env, jobject object) { | |
279 URLRequestPeer* request = GetNativeObject(env, object); | |
280 int error_code = request->error_code(); | |
281 switch (error_code) { | |
282 case 0: | |
mmenke
2014/02/27 23:06:02
case net::OK:
mmenke
2014/02/27 23:06:02
Please add a TODO about investigating returning su
mef
2014/03/03 19:15:13
Done.
mef
2014/03/03 19:15:13
Done.
| |
283 return ERROR_SUCCESS; | |
284 | |
285 // Comment from src/content/browser/download/download_resource_handler.cc: | |
286 // ERR_CONTENT_LENGTH_MISMATCH and ERR_INCOMPLETE_CHUNKED_ENCODING are | |
287 // allowed since a number of servers in the wild close the connection too | |
288 // early by mistake. Other browsers - IE9, Firefox 11.0, and Safari 5.1.4 - | |
289 // treat downloads as complete in both cases, so we follow their lead. | |
mmenke
2014/02/27 23:06:02
Add a TODO about investigating this. The fact is
mef
2014/03/03 19:15:13
Done.
| |
290 case net::ERR_CONTENT_LENGTH_MISMATCH: | |
291 case net::ERR_INCOMPLETE_CHUNKED_ENCODING: | |
292 return ERROR_SUCCESS; | |
293 | |
294 case net::ERR_INVALID_URL: | |
295 case net::ERR_DISALLOWED_URL_SCHEME: | |
296 case net::ERR_UNKNOWN_URL_SCHEME: | |
297 return ERROR_MALFORMED_URL; | |
298 | |
299 case net::ERR_CONNECTION_TIMED_OUT: | |
300 return ERROR_CONNECTION_TIMED_OUT; | |
301 | |
302 case net::ERR_NAME_NOT_RESOLVED: | |
303 return ERROR_UNKNOWN_HOST; | |
304 } | |
305 return ERROR_UNKNOWN; | |
306 } | |
307 | |
308 JNIEXPORT jstring JNICALL | |
309 Java_org_chromium_net_UrlRequest_nativeGetErrorString( | |
310 JNIEnv* env, jobject object) { | |
311 int error_code = GetNativeObject(env, object)->error_code(); | |
312 char buffer[200]; | |
313 snprintf(buffer, sizeof(buffer), "System error: %s(%d)", | |
314 net::ErrorToString(error_code), error_code); | |
315 return env->NewStringUTF(buffer); | |
316 } | |
317 | |
318 JNIEXPORT jint JNICALL | |
319 Java_org_chromium_net_UrlRequest_getHttpStatusCode( | |
320 JNIEnv* env, jobject object) { | |
321 return GetNativeObject(env, object)->http_status_code(); | |
322 } | |
323 | |
324 JNIEXPORT jstring JNICALL | |
325 Java_org_chromium_net_UrlRequest_nativeGetContentType( | |
326 JNIEnv* env, jobject object) { | |
327 URLRequestPeer* request = GetNativeObject(env, object); | |
328 if (request == NULL) { | |
329 return NULL; | |
330 } | |
331 std::string type = request->content_type(); | |
332 if (!type.empty()) { | |
333 return env->NewStringUTF(type.c_str()); | |
334 } else { | |
335 return NULL; | |
336 } | |
337 } | |
338 | |
339 JNIEXPORT jlong JNICALL | |
340 Java_org_chromium_net_UrlRequest_nativeGetContentLength( | |
341 JNIEnv* env, jobject object) { | |
342 URLRequestPeer* request = GetNativeObject(env, object); | |
343 if (request == NULL) { | |
344 return 0; | |
345 } | |
346 return request->content_length(); | |
347 } | |
OLD | NEW |