Skip to content

Commit

Permalink
Cache parsing of content-type header (#3011)
Browse files Browse the repository at this point in the history
  • Loading branch information
kyri-petrou authored Aug 12, 2024
1 parent 765c8bd commit acd6445
Showing 1 changed file with 14 additions and 1 deletion.
15 changes: 14 additions & 1 deletion zio-http/shared/src/main/scala/zio/http/Header.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import java.net.URI
import java.nio.charset.{Charset, UnsupportedCharsetException}
import java.time.ZonedDateTime
import java.util.Base64
import java.util.concurrent.ConcurrentHashMap

import scala.annotation.tailrec
import scala.collection.mutable
Expand Down Expand Up @@ -2543,12 +2544,21 @@ object Header {
}

object ContentType extends HeaderType {
private final val CacheInitialSize = 64
private final val CacheMaxSize = 8192

private val cache: ConcurrentHashMap[String, Either[String, ContentType]] =
new ConcurrentHashMap[String, Either[String, ContentType]](CacheInitialSize)

override type HeaderValue = ContentType

override def name: String = "content-type"

def parse(s: String): Either[String, ContentType] = codec.decode(s)
def parse(s: String): Either[String, ContentType] = {
// Guard against malicious registering of invalid content types
if (cache.size >= CacheMaxSize) cache.clear()
cache.computeIfAbsent(s, parseFn)
}

def render(contentType: ContentType): String = codec.encode(contentType).toOption.get

Expand Down Expand Up @@ -2608,6 +2618,9 @@ object Header {
)
}

private val parseFn: java.util.function.Function[String, Either[String, ContentType]] =
codec.decode(_)

private[Header] sealed trait Parameter {
self =>

Expand Down

0 comments on commit acd6445

Please sign in to comment.