Skip to content
This repository has been archived by the owner on Sep 26, 2022. It is now read-only.

Feature/raw requests #238

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.net.URLEncoder;
import java.net.UnknownServiceException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
Expand Down Expand Up @@ -215,7 +216,20 @@ public void setRequestBody(PluginCall call, JSValue body) throws JSONException,
}
uploader.finish();
} else {
this.writeRequestBody(body.toString());
JSObject obj = new JSObject(body.toString());
Iterator<String> keys = obj.keys();

List<Byte> data = new ArrayList<>();
while (keys.hasNext()) {
data.add((byte)obj.getInt(keys.next()));
}

byte[] bytes = new byte[data.size()];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = data.get(i);
}

this.writeRequestBody(bytes);
}
}

Expand All @@ -231,6 +245,18 @@ private void writeRequestBody(String body) throws IOException {
}
}

/**
* Writes the provided bytes to the HTTP connection managed by this instance.
*
* @param body The bytes to write to the connection stream.
*/
private void writeRequestBody(byte[] body) throws IOException {
try (DataOutputStream os = new DataOutputStream(connection.getOutputStream())) {
os.write(body);
os.flush();
}
}

/**
* Opens a communications link to the resource referenced by this
* URL, if such a connection has not already been established.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,12 @@ public static JSObject request(PluginCall call, String httpMethod) throws IOExce
if (data.getValue() != null) {
connection.setDoOutput(true);
connection.setRequestBody(call, data);
} else {
JSValue webFetchExtraData = new JSValue(call, "webFetchExtra", "body");
if (webFetchExtraData.getValue() != null) {
connection.setDoOutput(true);
connection.setRequestBody(call, webFetchExtraData);
}
}
}

Expand Down
29 changes: 17 additions & 12 deletions android/src/main/java/com/getcapacitor/plugin/http/JSValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ public class JSValue {

/**
* @param call The capacitor plugin call, used for accessing the value safely.
* @param name The name of the property to access.
* @param names The names of the property to access.
*/
public JSValue(PluginCall call, String name) {
this.value = this.toValue(call, name);
public JSValue(PluginCall call, String... names) {
this.value = this.toValue(call, names);
}

/**
Expand Down Expand Up @@ -55,14 +55,19 @@ public JSArray toJSArray() throws JSONException {
/**
* Returns the underlying value this object represents, coercing it into a capacitor-friendly object if supported.
*/
private Object toValue(PluginCall call, String name) {
Object value = null;
value = call.getArray(name, null);
if (value != null) return value;
value = call.getObject(name, null);
if (value != null) return value;
value = call.getString(name, null);
if (value != null) return value;
return call.getData().opt(name);
private Object toValue(PluginCall call, String... names) {
Object retValue = null;
for (String name : names) {
Object value;
value = call.getArray(name, null);
if (value != null) return value;
retValue = retValue == null ? call.getObject(name, null) : ((JSObject)retValue).opt(name);
if (retValue != null) continue;
value = call.getString(name, null);
if (value != null) return value;
value = call.getData().opt(name);
if (value != null) return value;
}
return retValue;
}
}
19 changes: 17 additions & 2 deletions ios/Plugin/CapacitorUrlRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,22 @@ public class CapacitorUrlRequest: NSObject, URLSessionTaskDelegate {
}
return Data(stringData.utf8)
}

private func getRequestDataAsRaw(_ data: JSValue) throws -> Data? {
guard let obj = data as? JSObject else {
throw CapacitorUrlRequestError.serializationError("[ data ] argument could not be parsed as raw data")
}
let strings: [String: Int] = obj.compactMapValues { any in
any as? Int
}

var raw = [UInt8](repeating: 0, count: strings.keys.count)
strings.forEach { key, value in
raw[Int(key) ?? 0] = UInt8(value)
}

return Data(raw)
}

func getRequestHeader(_ index: String) -> Any? {
var normalized = [:] as [String:Any]
Expand All @@ -105,9 +121,8 @@ public class CapacitorUrlRequest: NSObject, URLSessionTaskDelegate {
return try getRequestDataAsFormUrlEncoded(body)
} else if contentType.contains("multipart/form-data") {
return try getRequestDataAsMultipartFormData(body)
} else {
throw CapacitorUrlRequestError.serializationError("[ data ] argument could not be parsed for content type [ \(contentType) ]")
}
return try getRequestDataAsRaw(body);
}

public func setRequestHeaders(_ headers: [String: String]) {
Expand Down
3 changes: 2 additions & 1 deletion ios/Plugin/HttpRequestHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ class HttpRequestHandler {
let responseType = call.getString("responseType") ?? "text";
let connectTimeout = call.getDouble("connectTimeout");
let readTimeout = call.getDouble("readTimeout");
let extra = (call.getObject("webFetchExtra") ?? [:]) as! [String: Any]

let request = try! CapacitorHttpRequestBuilder()
.setUrl(urlString)
Expand All @@ -173,7 +174,7 @@ class HttpRequestHandler {
let timeout = (connectTimeout ?? readTimeout ?? 600000.0) / 1000.0;
request.setTimeout(timeout)

if let data = call.options["data"] as? JSValue {
if let data = (call.options["data"] ?? extra["body"]) as? JSValue {
do {
try request.setRequestBody(data)
} catch {
Expand Down