HttpRequestPort.kt

  1. package com.hexagonkt.http.model

  2. import com.hexagonkt.core.urlOf
  3. import com.hexagonkt.http.formatQueryString
  4. import java.net.URL
  5. import java.security.cert.X509Certificate

  6. // TODO 'formParameters' are a kind of 'part' and both are handled as part of the 'body'
  7. //  they could be handled as a special kind of type in body processing (List<HttpPartPort>)
  8. interface HttpRequestPort : HttpMessage {
  9.     val method: HttpMethod                        // "GET"
  10.     val protocol: HttpProtocol                    // "http"
  11.     val host: String                              // "example.com"
  12.     val port: Int                                 // 80
  13.     val path: String                              // "/foo" servlet path + path info
  14.     val queryParameters: QueryParameters
  15.     val parts: List<HttpPart>                     // hash of multipart parts
  16.     val formParameters: FormParameters
  17.     val accept: List<ContentType>
  18.     val authorization: Authorization?

  19.     val certificateChain: List<X509Certificate>
  20.     val contentLength: Long                       // length of request.body (or 0)

  21.     fun with(
  22.         body: Any = this.body,
  23.         headers: Headers = this.headers,
  24.         contentType: ContentType? = this.contentType,
  25.         method: HttpMethod = this.method,
  26.         protocol: HttpProtocol = this.protocol,
  27.         host: String = this.host,
  28.         port: Int = this.port,
  29.         path: String = this.path,
  30.         queryParameters: QueryParameters = this.queryParameters,
  31.         parts: List<HttpPart> = this.parts,
  32.         formParameters: FormParameters = this.formParameters,
  33.         cookies: List<Cookie> = this.cookies,
  34.         accept: List<ContentType> = this.accept,
  35.         authorization: Authorization? = this.authorization,
  36.         certificateChain: List<X509Certificate> = this.certificateChain,
  37.     ): HttpRequestPort

  38.     operator fun plus(header: Header): HttpRequestPort =
  39.         with(headers = headers + header)

  40.     operator fun plus(queryParameter: QueryParameter): HttpRequestPort =
  41.         with(queryParameters = queryParameters + queryParameter)

  42.     operator fun plus(part: HttpPart): HttpRequestPort =
  43.         with(parts = parts + part)

  44.     operator fun plus(formParameter: FormParameter): HttpRequestPort =
  45.         with(formParameters = formParameters + formParameter)

  46.     operator fun plus(cookie: Cookie): HttpRequestPort =
  47.         with(cookies = cookies + cookie)

  48.     operator fun plus(headers: Headers): HttpRequestPort =
  49.         with(headers = this.headers + headers)

  50.     operator fun plus(queryParameters: QueryParameters): HttpRequestPort =
  51.         with(queryParameters = this.queryParameters + queryParameters)

  52.     operator fun plus(parts: List<HttpPart>): HttpRequestPort =
  53.         with(parts = this.parts + parts)

  54.     operator fun plus(formParameters: FormParameters): HttpRequestPort =
  55.         with(formParameters = this.formParameters + formParameters)

  56.     fun certificate(): X509Certificate? =
  57.         certificateChain.firstOrNull()

  58.     fun partsMap(): Map<String, HttpPart> =
  59.         parts.associateBy { it.name }

  60.     fun url(): URL =
  61.         when {
  62.             queryParameters.isEmpty() && port == 80 -> "${protocol.schema}://$host/$path"
  63.             queryParameters.isEmpty() -> "${protocol.schema}://$host:$port/$path"
  64.             else -> "${protocol.schema}://$host:$port/$path?${formatQueryString(queryParameters)}"
  65.         }
  66.         .let(::urlOf)

  67.     fun userAgent(): String? =
  68.         headers["user-agent"]?.value as? String

  69.     fun referer(): String? =
  70.         headers["referer"]?.value as? String

  71.     fun origin(): String? =
  72.         headers["origin"]?.value as? String

  73.     fun authorization(): Authorization? =
  74.         (headers["authorization"]?.value as? String)
  75.             ?.split(" ", limit = 2)
  76.             ?.let { Authorization(it.first(), it.last()) }
  77. }