Skip to content
Draft
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 @@ -43,18 +43,14 @@ public val STREAM_CDN_HOST_PATTERN: Regex =
/**
* Returns whether this URL is served from a Stream CDN host that understands resizing query parameters.
*
* @param cdnHost An optional custom Stream CDN host (e.g. a proxied domain). When provided, the URL host is
* matched against it with a substring check, mirroring iOS' `StreamCDNRequester(cdnHost:)`; when null, the
* default [STREAM_CDN_HOST_PATTERN] is used.
* @param cdnHost An optional custom Stream CDN host (e.g. a proxied domain), matched with a substring check
* in addition to the default [STREAM_CDN_HOST_PATTERN], mirroring iOS' `StreamCDNRequester(cdnHost:)`.
*/
@InternalStreamChatApi
public fun String.isStreamCdnHosted(cdnHost: String? = null): Boolean {
val host = this.toUri().host ?: return false
return if (cdnHost != null) {
host.contains(cdnHost, ignoreCase = true)
} else {
STREAM_CDN_HOST_PATTERN.matches(host)
}
return STREAM_CDN_HOST_PATTERN.matches(host) ||
(cdnHost != null && host.contains(cdnHost, ignoreCase = true))
}

/**
Expand Down Expand Up @@ -223,8 +219,9 @@ public fun String.createResizedStreamCdnImageUrl(
if (maxImagePixels <= 0L) return this
if (!isStreamCdnHosted(cdnHost)) return this
val dimensions = getStreamCdnHostedImageDimensions() ?: return this
if (dimensions.originalWidth <= 0 || dimensions.originalHeight <= 0) return this
val totalPixels = dimensions.originalWidth.toLong() * dimensions.originalHeight.toLong()
if (totalPixels <= 0L || totalPixels <= maxImagePixels) return this
if (totalPixels <= maxImagePixels) return this
val scale = sqrt(maxImagePixels.toDouble() / totalPixels.toDouble()).toFloat()
return createResizedStreamCdnImageUrl(
resizedWidthPercentage = scale,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,26 @@ internal class StringExtensionsKtTest {
(resized.toUri().getQueryParameter(QUERY_PARAMETER_KEY_RESIZED_WIDTH) != null) shouldBeEqualTo true
}

@Test
fun `custom cdn host matching is additive - default Stream hosts still resize`() {
val streamUrl = createStreamCdnImageLink(originalWidth = 4000, originalHeight = 2000)

// With a custom host configured, default Stream CDN images must still be resized.
val resized = streamUrl.createResizedStreamCdnImageUrl(
maxImagePixels = 2_000_000L,
cdnHost = "images.example.com",
)
(resized != streamUrl) shouldBeEqualTo true
(resized.toUri().getQueryParameter(QUERY_PARAMETER_KEY_RESIZED_WIDTH) != null) shouldBeEqualTo true
}

@Test
fun `Given non-positive original dimensions Should return the url unchanged`() {
val negativeDimsUrl = createStreamCdnImageLink(originalWidth = -4000, originalHeight = -2000)

negativeDimsUrl.createResizedStreamCdnImageUrl(maxImagePixels = 2_000_000L) shouldBeEqualTo negativeDimsUrl
}

@Test
fun `Given a non-positive max pixel budget Should return the url unchanged`() {
val originalUrl = createStreamCdnImageLink(originalWidth = 4000, originalHeight = 2000)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,8 @@ public object ChatUI {
*/
@Deprecated(
"Use streamCdnImageResizer (defaults to a StreamCdnMaxPixelsImageResizer capping images to 2MP). " +
"For custom behavior, provide your own StreamCdnImageResizer.",
ReplaceWith("streamCdnImageResizer"),
"For custom behavior, provide your own StreamCdnImageResizer. This percentage-based config has no " +
"one-token replacement — migrate manually.",
)
@JvmStatic
public var streamCdnImageResizing: StreamCdnImageResizing = StreamCdnImageResizing.defaultStreamCdnImageResizing()
Expand Down
Loading