Skip to content
Closed
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 @@ -2,6 +2,7 @@ package com.margelo.nitro.nitrofetch

import android.app.Application
import android.content.Context
import android.webkit.CookieManager
import org.json.JSONArray
import org.json.JSONObject
import java.net.HttpURLConnection
Expand Down Expand Up @@ -151,16 +152,47 @@ object AutoPrefetcher {
conn.doInput = true
if (body != null) conn.doOutput = true

var hasCookieHeader = false
reqHeaders?.keys()?.forEachRemaining { k ->
if (k.equals("Cookie", ignoreCase = true)) hasCookieHeader = true
conn.setRequestProperty(k, reqHeaders.optString(k, ""))
}

if (!hasCookieHeader) {
try {
val jar = CookieManager.getInstance()
val cookieHeader = jar.getCookie(urlStr)
if (!cookieHeader.isNullOrEmpty()) {
conn.setRequestProperty("Cookie", cookieHeader)
}
} catch (_: Throwable) {
// Best-effort — CookieManager may not be initialized yet
}
}

if (body != null) {
conn.outputStream.use { it.write(body.toByteArray(Charsets.UTF_8)) }
}

val status = conn.responseCode
if (status !in 200..299) return null
if (status !in 200..299) {
android.util.Log.d("NitroFetch", "[TokenRefresh] Refresh endpoint returned HTTP $status")
return null
}

try {
val cookieManager = CookieManager.getInstance()
conn.headerFields?.forEach { (key, values) ->
if (key?.equals("Set-Cookie", ignoreCase = true) == true) {
values.forEach { cookieValue ->
cookieManager.setCookie(urlStr, cookieValue)
}
}
}
cookieManager.flush()
} catch (_: Throwable) {
// Best-effort — CookieManager may not be initialized yet
}

val responseBody = conn.inputStream.use { it.bufferedReader(Charsets.UTF_8).readText() }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.margelo.nitro.nitrofetch
import android.net.Uri
import android.os.Trace
import android.util.Log
import android.webkit.CookieManager
import com.facebook.proguard.annotations.DoNotStrip
import com.margelo.nitro.NitroModules
import com.margelo.nitro.core.ArrayBuffer
Expand Down Expand Up @@ -48,6 +49,25 @@ class NitroFetchClient(private val engine: CronetEngine, private val executor: E
}

companion object {
private fun hasCookieHeader(request: NitroRequest): Boolean {
return request.headers?.any { it.key.equals("Cookie", ignoreCase = true) } == true
}

private fun storeResponseCookies(responseUrl: String, info: UrlResponseInfo) {
try {
val cookieManager = CookieManager.getInstance()
val setCookieHeaders = info.allHeadersAsList.filter {
it.key.equals("Set-Cookie", ignoreCase = true)
}
for (header in setCookieHeaders) {
cookieManager.setCookie(responseUrl, header.value)
}
cookieManager.flush()
} catch (exception: Exception) {
Log.w("NitroFetchClient", "Failed to store response cookies", exception)
}
}

@JvmStatic
fun fetch(
req: NitroRequest,
Expand Down Expand Up @@ -87,6 +107,7 @@ class NitroFetchClient(private val engine: CronetEngine, private val executor: E

override fun onRedirectReceived(request: UrlRequest, info: UrlResponseInfo, newLocationUrl: String) {
if (shouldFollowRedirects) {
storeResponseCookies(info.url, info)
request.followRedirect()
} else {
// Return the redirect response as-is without following
Expand Down Expand Up @@ -131,6 +152,7 @@ class NitroFetchClient(private val engine: CronetEngine, private val executor: E
Trace.endAsyncSection(traceLabel, traceCookie)
}
try {
storeResponseCookies(info.url, info)
val headersArr: Array<NitroHeader> =
info.allHeadersAsList.map { NitroHeader(it.key, it.value) }.toTypedArray()
val status = info.httpStatusCode
Expand Down Expand Up @@ -184,6 +206,18 @@ class NitroFetchClient(private val engine: CronetEngine, private val executor: E
builder.setHttpMethod(method)
req.headers?.forEach { (k, v) -> builder.addHeader(k, v) }

if (!hasCookieHeader(req)) {
try {
val cookieManager = CookieManager.getInstance()
val cookie = cookieManager.getCookie(url)
if (!cookie.isNullOrEmpty()) {
builder.addHeader("Cookie", cookie)
}
} catch (exception: Exception) {
Log.w("NitroFetchClient", "Failed to attach cookie header", exception)
}
}

val formParts = req.bodyFormData
if (formParts != null && formParts.isNotEmpty()) {
val (multipartBody, contentType) = buildMultipartBody(formParts)
Expand Down