HelidonRequestAdapter.kt

  1. package com.hexagonkt.http.server.helidon

  2. import com.hexagonkt.core.media.MediaType
  3. import com.hexagonkt.core.media.MediaTypeGroup
  4. import com.hexagonkt.http.model.*
  5. import com.hexagonkt.http.model.Headers
  6. import io.helidon.http.HeaderNames
  7. import io.helidon.http.Method
  8. import io.helidon.http.media.multipart.MultiPart
  9. import io.helidon.webserver.http.ServerRequest
  10. import java.security.cert.X509Certificate
  11. import kotlin.jvm.optionals.getOrNull

  12. class HelidonRequestAdapter(
  13.     methodName: Method,
  14.     req: ServerRequest,
  15. ) : HttpRequestPort {

  16.     override val certificateChain: List<X509Certificate> by lazy {
  17.         req.remotePeer().tlsCertificates().getOrNull()
  18.             ?.toList()
  19.             ?.map { it as X509Certificate }
  20.             ?: emptyList()
  21.     }

  22.     override val accept: List<ContentType> by lazy {
  23.         req.headers().acceptedTypes().map {
  24.             val mt = it.mediaType()
  25.             val t = mt.type().uppercase()
  26.             val st = mt.subtype()
  27.             ContentType(MediaType(MediaTypeGroup.valueOf(t), st))
  28.         }
  29.     }

  30.     override val contentLength: Long by lazy {
  31.         req.headers().get(HeaderNames.CONTENT_LENGTH).get().toLong()
  32.     }

  33.     override val queryParameters: QueryParameters by lazy {
  34.         QueryParameters(
  35.             req.query().names().map {
  36.                 QueryParameter(it, req.query().all(it))
  37.             }
  38.         )
  39.     }

  40.     override val parts: List<HttpPart> by lazy {
  41.         try {
  42.             val multiPart = req.content().`as`(MultiPart::class.java)
  43.             var parts = emptyList<HttpPart>()
  44.             // TODO Fails when parsing multiple parts !?
  45.             multiPart.forEach { p ->
  46.                 val name = p.name()
  47.                 val bytes = p.inputStream().readAllBytes()
  48.                 val fileName = p.fileName().getOrNull()
  49.                     ?.let { HttpPart(name, bytes, it) }
  50.                     ?: HttpPart(name, String(bytes))

  51.                 parts = parts + fileName
  52.             }
  53.             parts
  54.         }
  55.         catch (e: Exception) {
  56.             emptyList()
  57.         }
  58.     }

  59.     override val formParameters: FormParameters by lazy {
  60.         val fields = parts
  61.             .filter { it.submittedFileName == null }
  62.             .map { FormParameter(it.name, it.bodyString()) }

  63.         FormParameters(fields)
  64.     }

  65.     override val method: HttpMethod by lazy {
  66.         HttpMethod.valueOf(methodName.text())
  67.     }

  68.     override val protocol: HttpProtocol by lazy {
  69.         HttpProtocol.valueOf(req.prologue().protocol())
  70.     }

  71.     override val host: String by lazy {
  72.         req.remotePeer().host()
  73.     }

  74.     override val port: Int by lazy {
  75.         req.remotePeer().port()
  76.     }

  77.     override val path: String by lazy {
  78.         req.path().path()
  79.     }

  80.     override val cookies: List<Cookie> by lazy {
  81.         req.headers().cookies().toMap().map { (k, v) -> Cookie(k, v.first()) }
  82.     }

  83.     override val body: Any by lazy {
  84.         req.content().inputStream().readAllBytes()
  85.     }

  86.     override val headers: Headers by lazy {
  87.         Headers(req.headers().map { Header(it.name(), it.allValues()) })
  88.     }

  89.     override val contentType: ContentType? by lazy {
  90.         req.headers().contentType().map {
  91.             val mt = it.mediaType()
  92.             val t = mt.type().uppercase()
  93.             val st = mt.subtype()
  94.             ContentType(MediaType(MediaTypeGroup.valueOf(t), st))
  95.         }
  96.         .orElse(null)
  97.     }

  98.     override val authorization: Authorization? by lazy { authorization() }

  99.     override fun with(
  100.         body: Any,
  101.         headers: Headers,
  102.         contentType: ContentType?,
  103.         method: HttpMethod,
  104.         protocol: HttpProtocol,
  105.         host: String,
  106.         port: Int,
  107.         path: String,
  108.         queryParameters: QueryParameters,
  109.         parts: List<HttpPart>,
  110.         formParameters: FormParameters,
  111.         cookies: List<Cookie>,
  112.         accept: List<ContentType>,
  113.         authorization: Authorization?,
  114.         certificateChain: List<X509Certificate>
  115.     ): HttpRequestPort =
  116.         throw UnsupportedOperationException()
  117. }