Skip to content

Commit afbd9cf

Browse files
committed
Switch to using ByteArrays for HTTP bodies rather than strings
1 parent 6a60dbe commit afbd9cf

File tree

6 files changed

+118
-23
lines changed

6 files changed

+118
-23
lines changed

bridge-settings/src/main/java/com/penumbraos/bridge_settings/SettingsWebServer.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import io.ktor.server.netty.NettyApplicationEngine
2121
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
2222
import io.ktor.server.request.httpMethod
2323
import io.ktor.server.request.receive
24-
import io.ktor.server.request.receiveText
2524
import io.ktor.server.request.uri
2625
import io.ktor.server.response.respond
2726
import io.ktor.server.response.respondBytes
@@ -282,10 +281,10 @@ class SettingsWebServer(
282281
intercept(ApplicationCallPipeline.Call) {
283282
val fullPath = call.request.uri.substringBefore('?')
284283
val method = call.request.httpMethod.value
285-
284+
286285
var matchedEndpoint: RegisteredEndpoint? = null
287286
var pathParams: Map<String, String>? = null
288-
287+
289288
for (endpoint in registeredEndpoints.values) {
290289
if (endpoint.method.equals(method, ignoreCase = true)) {
291290
val match = endpoint.matchesPath(fullPath)
@@ -304,7 +303,7 @@ class SettingsWebServer(
304303
val queryParams = call.request.queryParameters.toMap()
305304
.mapValues { it.value.firstOrNull() ?: "" }
306305
val body = try {
307-
call.receiveText()
306+
call.receive<ByteArray>()
308307
} catch (e: Exception) {
309308
null
310309
}
@@ -325,10 +324,10 @@ class SettingsWebServer(
325324
}
326325

327326
val contentType = ContentType.parse(response.contentType)
328-
call.respondText(
329-
response.body,
327+
call.respondBytes(
328+
response.body ?: ByteArray(0),
330329
contentType,
331-
HttpStatusCode.fromValue(response.statusCode)
330+
HttpStatusCode.fromValue(response.statusCode),
332331
)
333332
return@intercept finish()
334333
} catch (e: Exception) {

bridge-settings/src/main/java/com/penumbraos/bridge_settings/server/types.kt

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,63 @@ data class EndpointRequest(
1212
val headers: Map<String, String>,
1313
val queryParams: Map<String, String>,
1414
val pathParams: Map<String, String>,
15-
val body: String?
16-
)
15+
val body: ByteArray?
16+
) {
17+
override fun equals(other: Any?): Boolean {
18+
if (this === other) return true
19+
if (javaClass != other?.javaClass) return false
20+
21+
other as EndpointRequest
22+
23+
if (path != other.path) return false
24+
if (method != other.method) return false
25+
if (headers != other.headers) return false
26+
if (queryParams != other.queryParams) return false
27+
if (pathParams != other.pathParams) return false
28+
if (!body.contentEquals(other.body)) return false
29+
30+
return true
31+
}
32+
33+
override fun hashCode(): Int {
34+
var result = path.hashCode()
35+
result = 31 * result + method.hashCode()
36+
result = 31 * result + headers.hashCode()
37+
result = 31 * result + queryParams.hashCode()
38+
result = 31 * result + pathParams.hashCode()
39+
result = 31 * result + (body?.contentHashCode() ?: 0)
40+
return result
41+
}
42+
}
1743

1844
data class EndpointResponse(
1945
val statusCode: Int = 200,
2046
val headers: Map<String, String> = emptyMap(),
21-
val body: String = "",
47+
val body: ByteArray?,
2248
val contentType: String = "application/json"
23-
)
49+
) {
50+
override fun equals(other: Any?): Boolean {
51+
if (this === other) return true
52+
if (javaClass != other?.javaClass) return false
53+
54+
other as EndpointResponse
55+
56+
if (statusCode != other.statusCode) return false
57+
if (headers != other.headers) return false
58+
if (!body.contentEquals(other.body)) return false
59+
if (contentType != other.contentType) return false
60+
61+
return true
62+
}
63+
64+
override fun hashCode(): Int {
65+
var result = statusCode
66+
result = 31 * result + headers.hashCode()
67+
result = 31 * result + (body?.contentHashCode() ?: 0)
68+
result = 31 * result + contentType.hashCode()
69+
return result
70+
}
71+
}
2472

2573
interface EndpointCallback {
2674
suspend fun handle(request: EndpointRequest): EndpointResponse
@@ -51,7 +99,7 @@ class AidlEndpointCallback(
5199
override fun sendResponse(
52100
statusCode: Int,
53101
headers: MutableMap<Any?, Any?>?,
54-
body: String?,
102+
body: ByteArray?,
55103
contentType: String?
56104
) {
57105
val headers = (headers?.mapKeys { it.key.toString() }
@@ -63,7 +111,7 @@ class AidlEndpointCallback(
63111
val response = EndpointResponse(
64112
statusCode = statusCode,
65113
headers = headers,
66-
body = body ?: "",
114+
body = body,
67115
contentType = contentType ?: "application/json"
68116
)
69117
continuation.resume(response)
@@ -83,7 +131,7 @@ class AidlEndpointCallback(
83131
} catch (e: Exception) {
84132
val errorResponse = EndpointResponse(
85133
statusCode = 500,
86-
body = "{\"error\": \"Internal server error: ${e.message}\"}",
134+
body = "{\"error\": \"Internal server error: ${e.message}\"}".toByteArray(),
87135
contentType = "application/json"
88136
)
89137
continuation.resume(errorResponse)

bridge-shared/aidl/com/penumbraos/bridge/callback/IHttpEndpointCallback.aidl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ package com.penumbraos.bridge.callback;
33
import com.penumbraos.bridge.callback.IHttpResponseCallback;
44

55
interface IHttpEndpointCallback {
6-
void onHttpRequest(String path, String method, in Map pathParams, in Map headers, in Map queryParams, String body, IHttpResponseCallback responseCallback);
6+
void onHttpRequest(String path, String method, in Map pathParams, in Map headers, in Map queryParams, in byte[] body, IHttpResponseCallback responseCallback);
77
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
package com.penumbraos.bridge.callback;
22

33
interface IHttpResponseCallback {
4-
void sendResponse(int statusCode, in Map headers, String body, String contentType);
4+
void sendResponse(int statusCode, in Map headers, in byte[] body, String contentType);
55
}

sdk/src/main/java/com/penumbraos/sdk/api/SettingsClient.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ class SettingsClient(private val settingsProvider: ISettingsProvider) {
185185
pathParams: MutableMap<Any?, Any?>,
186186
headers: MutableMap<Any?, Any?>?,
187187
queryParams: MutableMap<Any?, Any?>?,
188-
body: String?,
188+
body: ByteArray?,
189189
responseCallback: IHttpResponseCallback
190190
) {
191191
try {
@@ -218,7 +218,7 @@ class SettingsClient(private val settingsProvider: ISettingsProvider) {
218218
responseCallback.sendResponse(
219219
500,
220220
emptyMap<Any?, Any?>(),
221-
"{\"error\": \"Internal server error: ${e.message}\"}",
221+
"{\"error\": \"Internal server error: ${e.message}\"}".toByteArray(),
222222
"application/json"
223223
)
224224
}
@@ -229,7 +229,7 @@ class SettingsClient(private val settingsProvider: ISettingsProvider) {
229229
responseCallback.sendResponse(
230230
500,
231231
emptyMap<Any?, Any?>().toMutableMap(),
232-
"{\"error\": \"Callback error: ${e.message}\"}",
232+
"{\"error\": \"Callback error: ${e.message}\"}".toByteArray(),
233233
"application/json"
234234
)
235235
} catch (callbackError: Exception) {

sdk/src/main/java/com/penumbraos/sdk/api/types/settingsTypes.kt

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,63 @@ data class HttpRequest(
66
val pathParams: Map<String, String>,
77
val headers: Map<String, String>,
88
val queryParams: Map<String, String>,
9-
val body: String?
10-
)
9+
val body: ByteArray?
10+
) {
11+
override fun equals(other: Any?): Boolean {
12+
if (this === other) return true
13+
if (javaClass != other?.javaClass) return false
14+
15+
other as HttpRequest
16+
17+
if (path != other.path) return false
18+
if (method != other.method) return false
19+
if (pathParams != other.pathParams) return false
20+
if (headers != other.headers) return false
21+
if (queryParams != other.queryParams) return false
22+
if (!body.contentEquals(other.body)) return false
23+
24+
return true
25+
}
26+
27+
override fun hashCode(): Int {
28+
var result = path.hashCode()
29+
result = 31 * result + method.hashCode()
30+
result = 31 * result + pathParams.hashCode()
31+
result = 31 * result + headers.hashCode()
32+
result = 31 * result + queryParams.hashCode()
33+
result = 31 * result + (body?.contentHashCode() ?: 0)
34+
return result
35+
}
36+
}
1137

1238
data class HttpResponse(
1339
val statusCode: Int = 200,
1440
val headers: Map<String, String> = emptyMap(),
15-
val body: String = "",
41+
val body: ByteArray? = null,
1642
val contentType: String = "application/json"
17-
)
43+
) {
44+
override fun equals(other: Any?): Boolean {
45+
if (this === other) return true
46+
if (javaClass != other?.javaClass) return false
47+
48+
other as HttpResponse
49+
50+
if (statusCode != other.statusCode) return false
51+
if (headers != other.headers) return false
52+
if (!body.contentEquals(other.body)) return false
53+
if (contentType != other.contentType) return false
54+
55+
return true
56+
}
57+
58+
override fun hashCode(): Int {
59+
var result = statusCode
60+
result = 31 * result + headers.hashCode()
61+
result = 31 * result + (body?.contentHashCode() ?: 0)
62+
result = 31 * result + contentType.hashCode()
63+
return result
64+
}
65+
}
1866

1967
interface HttpEndpointHandler {
2068
suspend fun handleRequest(request: HttpRequest): HttpResponse

0 commit comments

Comments
 (0)