GoogleHttpFunction.kt
- package com.hexagontk.serverless.http.google
- import com.hexagontk.http.handlers.bodyToBytes
- import com.google.cloud.functions.HttpFunction
- import com.google.cloud.functions.HttpRequest
- import com.google.cloud.functions.HttpResponse
- import com.hexagontk.core.media.TEXT_PLAIN
- import com.hexagontk.core.toText
- import com.hexagontk.http.handlers.HttpContext
- import com.hexagontk.http.handlers.HttpHandler
- import com.hexagontk.http.model.*
- import com.hexagontk.http.parseContentType
- import java.net.URI
- class GoogleHttpFunction(private val handler: HttpHandler): HttpFunction {
- override fun service(request: HttpRequest, response: HttpResponse) {
- val handlerRequest = createRequest(request)
- val handlerContext = handler.process(handlerRequest)
- writeResponse(response, handlerContext)
- }
- private fun createRequest(request: HttpRequest): com.hexagontk.http.model.HttpRequest {
- val uri = URI(request.uri)
- val qp =
- request.queryParameters?.flatMap { (k, v) -> v.map { Parameter(k, it) } } ?: emptyList()
- val h = request.headers?.flatMap { (k, v) -> v.map { Header(k, it) } } ?: emptyList()
- val contentType = request.contentType.map { parseContentType(it) }.orElse(null)
- val accept = request.headers["accept"]?.map { parseContentType(it) } ?: emptyList()
- val authorization = request.headers["authorization"]
- ?.first()
- ?.split(" ", limit = 2)
- ?.let { Authorization(it.first(), it.last()) }
- // TODO Fix parts upload
- val parts = emptyList<HttpPart>()
- // if (request.contentType.orElse("").contains("multipart")) {
- // request.parts.map { (k, v) ->
- // HttpPart(
- // name = k,
- // body = v.inputStream.readAllBytes(),
- // headers = Headers(),
- // contentType = v.contentType?.map { parseContentType(it) }?.orElse(null),
- // size = v.contentLength,
- // submittedFileName = v.fileName.orElse(null),
- // )
- // }
- // }
- // else emptyList()
- return HttpRequest(
- method = HttpMethod.valueOf(request.method),
- protocol = HttpProtocol.valueOf(uri.scheme.uppercase()),
- host = uri.host,
- port = uri.port,
- path = request.path,
- queryParameters = Parameters(qp),
- headers = Headers(h),
- body = request.inputStream.readAllBytes() ?: ByteArray(0),
- parts = parts,
- contentType = contentType,
- accept = accept,
- contentLength = request.contentLength,
- authorization = authorization,
- )
- }
- private fun writeResponse(response: HttpResponse, context: HttpContext) {
- val handlerResponse = context.response
- handlerResponse.contentType?.text?.let(response::setContentType)
- handlerResponse.headers.forEach { response.appendHeader(it.name, it.text) }
- response.setStatusCode(handlerResponse.status)
- try {
- response.outputStream.write(bodyToBytes(handlerResponse.body))
- }
- catch (e: Exception) {
- response.setContentType(TEXT_PLAIN.fullType)
- response.setStatusCode(500)
- response.outputStream.write(bodyToBytes(e.toText()))
- }
- }
- }