[android] Fix semantics in absence of response headers

Absence of response headers should result in null etag/modified/expires optionals, not present-but-0-or-"" optionals.
This commit is contained in:
John Firebaugh
2016-01-20 17:35:07 -08:00
parent 1c21d0fd4c
commit fd847bca9e

View File

@@ -42,8 +42,8 @@ public:
void cancel() final;
void onFailure(int type, std::string message);
void onResponse(int code, std::string message, std::string etag, std::string modified, std::string cacheControl, std::string expires, std::string body);
void onFailure(JNIEnv*, int type, jstring message);
void onResponse(JNIEnv*, int code, jstring message, jstring etag, jstring modified, jstring cacheControl, jstring expires, jbyteArray body);
private:
void finish();
@@ -188,20 +188,31 @@ void HTTPAndroidRequest::finish() {
delete this;
}
void HTTPAndroidRequest::onResponse(int code, std::string message, std::string etag, std::string modified, std::string cacheControl, std::string expires, std::string body) {
void HTTPAndroidRequest::onResponse(JNIEnv* env, int code, jstring /* message */, jstring etag, jstring modified, jstring cacheControl, jstring expires, jbyteArray body) {
response = std::make_unique<Response>();
using Error = Response::Error;
// the message param is unused, this generates a warning at build time
// this was breaking builds for `make android -j4`
(void)message;
response->modified = SystemClock::from_time_t(parse_date(modified.c_str()));
response->etag = etag;
response->expires = parseCacheControl(cacheControl.c_str());
if (!expires.empty()) {
response->expires = SystemClock::from_time_t(parse_date(expires.c_str()));
if (etag != nullptr) {
response->etag = mbgl::android::std_string_from_jstring(env, etag);
}
if (modified != nullptr) {
response->modified = SystemClock::from_time_t(parse_date(mbgl::android::std_string_from_jstring(env, modified).c_str()));
}
if (cacheControl != nullptr) {
response->expires = parseCacheControl(mbgl::android::std_string_from_jstring(env, cacheControl).c_str());
}
if (expires != nullptr) {
response->expires = SystemClock::from_time_t(parse_date(mbgl::android::std_string_from_jstring(env, expires).c_str()));
}
if (body != nullptr) {
jbyte* bodyData = env->GetByteArrayElements(body, nullptr);
response->data = std::make_shared<std::string>(reinterpret_cast<char*>(bodyData), env->GetArrayLength(body));
env->ReleaseByteArrayElements(body, bodyData, JNI_ABORT);
}
response->data = std::make_shared<std::string>(body);
if (code == 200) {
// Nothing to do; this is what we want
@@ -234,22 +245,24 @@ void HTTPAndroidRequest::onResponse(int code, std::string message, std::string e
async.send();
}
void HTTPAndroidRequest::onFailure(int type, std::string message) {
void HTTPAndroidRequest::onFailure(JNIEnv* env, int type, jstring message) {
std::string messageStr = mbgl::android::std_string_from_jstring(env, message);
response = std::make_unique<Response>();
using Error = Response::Error;
switch (type) {
case connectionError:
response->error = std::make_unique<Error>(Error::Reason::Connection, message);
response->error = std::make_unique<Error>(Error::Reason::Connection, messageStr);
break;
case temporaryError:
response->error = std::make_unique<Error>(Error::Reason::Server, message);
response->error = std::make_unique<Error>(Error::Reason::Server, messageStr);
break;
case canceledError:
response->error = std::make_unique<Error>(Error::Reason::Canceled, "Request was cancelled");
break;
default:
response->error = std::make_unique<Error>(Error::Reason::Other, message);
response->error = std::make_unique<Error>(Error::Reason::Other, messageStr);
}
async.send();
@@ -259,44 +272,16 @@ std::unique_ptr<HTTPContextBase> HTTPContextBase::createContext() {
return std::make_unique<HTTPAndroidContext>();
}
#pragma clang diagnostic ignored "-Wunused-parameter"
void JNICALL nativeOnFailure(JNIEnv *env, jobject obj, jlong nativePtr, jint type, jstring message) {
void JNICALL nativeOnFailure(JNIEnv* env, jobject, jlong nativePtr, jint type, jstring message) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeOnFailure");
assert(nativePtr != 0);
HTTPAndroidRequest *request = reinterpret_cast<HTTPAndroidRequest *>(nativePtr);
std::string messageStr = mbgl::android::std_string_from_jstring(env, message);
return request->onFailure(type, messageStr);
return reinterpret_cast<HTTPAndroidRequest*>(nativePtr)->onFailure(env, type, message);
}
void JNICALL nativeOnResponse(JNIEnv *env, jobject obj, jlong nativePtr, jint code, jstring message, jstring etag, jstring modified, jstring cacheControl, jstring expires, jbyteArray body) {
void JNICALL nativeOnResponse(JNIEnv* env, jobject, jlong nativePtr, jint code, jstring message, jstring etag, jstring modified, jstring cacheControl, jstring expires, jbyteArray body) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeOnResponse");
assert(nativePtr != 0);
HTTPAndroidRequest *request = reinterpret_cast<HTTPAndroidRequest *>(nativePtr);
std::string messageStr = mbgl::android::std_string_from_jstring(env, message);
std::string etagStr;
if (etag != nullptr) {
etagStr = mbgl::android::std_string_from_jstring(env, etag);
}
std::string modifiedStr;
if (modified != nullptr) {
modifiedStr = mbgl::android::std_string_from_jstring(env, modified);
}
std::string cacheControlStr;
if (cacheControl != nullptr) {
cacheControlStr = mbgl::android::std_string_from_jstring(env, cacheControl);
}
std::string expiresStr;
if (expires != nullptr) {
expiresStr = mbgl::android::std_string_from_jstring(env, expires);
}
std::string bodyStr;
if (body != nullptr) {
jbyte* bodyData = env->GetByteArrayElements(body, nullptr);
bodyStr = std::string(reinterpret_cast<char*>(bodyData), env->GetArrayLength(body));
env->ReleaseByteArrayElements(body, bodyData, JNI_ABORT);
}
return request->onResponse(code, messageStr, etagStr, modifiedStr, cacheControlStr, expiresStr, bodyStr);
return reinterpret_cast<HTTPAndroidRequest*>(nativePtr)->onResponse(env, code, message, etag, modified, cacheControl, expires, body);
}
}