Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets create this in a function like NitroFetchClient.kt . Lets avoid 2 code doing the exact thing but in different ways

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()
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will run everytime even though we dont have cookies . Maybe we can add check here to run only if actually set-cookie exist

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also maybe we flush once on onSucceeded . Idk if thats good . Ideally we should not flush on every redirect

} 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()
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

} 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