android: Add support to POST data via SimpleFetcher

That's required for OCSP verification.
This commit is contained in:
Tobias Brunner
2017-09-04 10:41:29 +02:00
parent 6e39240a3e
commit 829cc56a53
2 changed files with 62 additions and 6 deletions
@@ -17,16 +17,18 @@ package org.strongswan.android.logic;
import android.support.annotation.Keep; import android.support.annotation.Keep;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
@Keep @Keep
public class SimpleFetcher public class SimpleFetcher
{ {
public static byte[] fetch(String uri) throws IOException public static byte[] fetch(String uri, byte[] data, String contentType) throws IOException
{ {
URL url = new URL(uri); URL url = new URL(uri);
HttpURLConnection conn = (HttpURLConnection)url.openConnection(); HttpURLConnection conn = (HttpURLConnection)url.openConnection();
@@ -34,6 +36,18 @@ public class SimpleFetcher
conn.setReadTimeout(10000); conn.setReadTimeout(10000);
try try
{ {
if (contentType != null)
{
conn.setRequestProperty("Content-Type", contentType);
}
if (data != null)
{
conn.setDoOutput(true);
conn.setFixedLengthStreamingMode(data.length);
OutputStream out = new BufferedOutputStream(conn.getOutputStream());
out.write(data);
out.close();
}
return streamToArray(conn.getInputStream()); return streamToArray(conn.getInputStream());
} }
finally finally
@@ -42,7 +56,7 @@ public class SimpleFetcher
} }
} }
private static byte[] streamToArray(InputStream in) private static byte[] streamToArray(InputStream in) throws IOException
{ {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[1024]; byte[] buf = new byte[1024];
@@ -60,6 +74,10 @@ public class SimpleFetcher
{ {
e.printStackTrace(); e.printStackTrace();
} }
finally
{
in.close();
}
return null; return null;
} }
} }
@@ -31,6 +31,16 @@ struct android_fetcher_t {
* Callback function * Callback function
*/ */
fetcher_callback_t cb; fetcher_callback_t cb;
/**
* Data to POST
*/
chunk_t data;
/**
* Type of data to POST
*/
char *request_type;
}; };
METHOD(fetcher_t, fetch, status_t, METHOD(fetcher_t, fetch, status_t,
@@ -38,8 +48,8 @@ METHOD(fetcher_t, fetch, status_t,
{ {
JNIEnv *env; JNIEnv *env;
jmethodID method_id; jmethodID method_id;
jobjectArray jdata; jobjectArray jdata = NULL;
jstring juri; jstring juri, jct = NULL;
chunk_t data; chunk_t data;
status_t status = FAILED; status_t status = FAILED;
@@ -51,7 +61,7 @@ METHOD(fetcher_t, fetch, status_t,
androidjni_attach_thread(&env); androidjni_attach_thread(&env);
/* can't use FindClass here as this is not called by the main thread */ /* can't use FindClass here as this is not called by the main thread */
method_id = (*env)->GetStaticMethodID(env, android_simple_fetcher_class, method_id = (*env)->GetStaticMethodID(env, android_simple_fetcher_class,
"fetch", "(Ljava/lang/String;)[B"); "fetch", "(Ljava/lang/String;[BLjava/lang/String;)[B");
if (!method_id) if (!method_id)
{ {
goto failed; goto failed;
@@ -61,8 +71,24 @@ METHOD(fetcher_t, fetch, status_t,
{ {
goto failed; goto failed;
} }
if (this->request_type)
{
jct = (*env)->NewStringUTF(env, this->request_type);
if (!jct)
{
goto failed;
}
}
if (this->data.ptr)
{
jdata = byte_array_from_chunk(env, this->data);
if (!jdata)
{
goto failed;
}
}
jdata = (*env)->CallStaticObjectMethod(env, android_simple_fetcher_class, jdata = (*env)->CallStaticObjectMethod(env, android_simple_fetcher_class,
method_id, juri); method_id, juri, jdata, jct);
if (!jdata || androidjni_exception_occurred(env)) if (!jdata || androidjni_exception_occurred(env))
{ {
goto failed; goto failed;
@@ -97,6 +123,16 @@ METHOD(fetcher_t, set_option, bool,
this->cb = va_arg(args, fetcher_callback_t); this->cb = va_arg(args, fetcher_callback_t);
break; break;
} }
case FETCH_REQUEST_DATA:
{
this->data = chunk_clone(va_arg(args, chunk_t));
break;
}
case FETCH_REQUEST_TYPE:
{
this->request_type = strdup(va_arg(args, char*));
break;
}
default: default:
supported = FALSE; supported = FALSE;
break; break;
@@ -108,6 +144,8 @@ METHOD(fetcher_t, set_option, bool,
METHOD(fetcher_t, destroy, void, METHOD(fetcher_t, destroy, void,
android_fetcher_t *this) android_fetcher_t *this)
{ {
chunk_clear(&this->data);
free(this->request_type);
free(this); free(this);
} }