<commit_before>package io.aconite.server.handlers

import io.aconite.BodyBuffer
import io.aconite.Buffer
import io.aconite.Request
import io.aconite.Response
import io.aconite.server.*
import io.vertx.core.Handler
import io.vertx.core.Vertx
import io.vertx.ext.web.RoutingContext
import kotlinx.coroutines.experimental.CoroutineDispatcher
import kotlinx.coroutines.experimental.async
import kotlin.coroutines.experimental.CoroutineContext

class VertxHandler(private val vertx: Vertx, private val server: AconiteServer): Handler<RoutingContext> {
    val coroutineCtx = VertxCoroutineContext()

    inner class VertxCoroutineContext: CoroutineDispatcher() {
        override fun dispatch(context: CoroutineContext, block: Runnable) {
            vertx.runOnContext { block.run() }
        }
    }

    class VertxBuffer(private val buffer: io.vertx.core.buffer.Buffer): Buffer {
        override val bytes by lazy { buffer.bytes!! }
        override val string by lazy { buffer.toString() }
    }

    override fun handle(routingCtx: RoutingContext) {
        async(coroutineCtx) {
            try {
                val request = makeRequest(routingCtx)
                val response = server.accept(routingCtx.request().uri(), request)
                if (response != null) {
                    makeResponse(routingCtx, response)
                } else {
                    routingCtx.next()
                }
            } catch (ex: Throwable) {
                ex.printStackTrace()
            }
        }
    }

    private fun makeRequest(ctx: RoutingContext): Request {
        return Request(
                method = ctx.request().rawMethod(),
                path = ctx.pathParams(),
                headers = ctx.request().headers()
                        .asSequence()
                        .map { Pair(it.key, it.value) }
                        .toMap(),
                query = ctx.request().params()
                        .asSequence()
                        .map { Pair(it.key, it.value) }
                        .toMap(),
                body = BodyBuffer(
                        content = VertxBuffer(ctx.body),
                        contentType = ctx.request().getHeader("Content-Type") ?: ""
                )
        )
    }

    private fun makeResponse(ctx: RoutingContext, response: Response) {
        ctx.response().apply {
            for ((k, v) in response.headers)
                putHeader(k, v)
            statusCode = response.code
            response.body?.let { putHeader("Content-Type", it.contentType) }
            end(io.vertx.core.buffer.Buffer.buffer(response.body?.content?.bytes))
        }
    }
}<commit_msg>Add static method for run vertx server in one line<commit_after>package io.aconite.server.handlers

import io.aconite.BodyBuffer
import io.aconite.Buffer
import io.aconite.Request
import io.aconite.Response
import io.aconite.server.*
import io.vertx.core.Handler
import io.vertx.core.Vertx
import io.vertx.ext.web.Router
import io.vertx.ext.web.RoutingContext
import io.vertx.ext.web.handler.BodyHandler
import kotlinx.coroutines.experimental.CoroutineDispatcher
import kotlinx.coroutines.experimental.async
import kotlin.coroutines.experimental.CoroutineContext

class VertxHandler(private val vertx: Vertx, private val server: AconiteServer): Handler<RoutingContext> {
    val coroutineCtx = VertxCoroutineContext()

    companion object {
        fun runServer(server: AconiteServer, port: Int) {
            val vertx = Vertx.vertx()
            val router = Router.router(vertx)
            val handler = VertxHandler(vertx, server)
            router.route().handler(BodyHandler.create())
            router.route().handler(handler)
            vertx.createHttpServer()
                    .requestHandler(router::accept)
                    .listen(port)
        }
    }

    inner class VertxCoroutineContext: CoroutineDispatcher() {
        override fun dispatch(context: CoroutineContext, block: Runnable) {
            vertx.runOnContext { block.run() }
        }
    }

    class VertxBuffer(private val buffer: io.vertx.core.buffer.Buffer): Buffer {
        override val bytes by lazy { buffer.bytes!! }
        override val string by lazy { buffer.toString() }
    }

    override fun handle(routingCtx: RoutingContext) {
        async(coroutineCtx) {
            try {
                val request = makeRequest(routingCtx)
                val response = server.accept(routingCtx.request().uri(), request)
                if (response != null) {
                    makeResponse(routingCtx, response)
                } else {
                    routingCtx.next()
                }
            } catch (ex: Throwable) {
                ex.printStackTrace()
            }
        }
    }

    private fun makeRequest(ctx: RoutingContext): Request {
        return Request(
                method = ctx.request().rawMethod(),
                path = ctx.pathParams(),
                headers = ctx.request().headers()
                        .asSequence()
                        .map { Pair(it.key, it.value) }
                        .toMap(),
                query = ctx.request().params()
                        .asSequence()
                        .map { Pair(it.key, it.value) }
                        .toMap(),
                body = BodyBuffer(
                        content = VertxBuffer(ctx.body),
                        contentType = ctx.request().getHeader("Content-Type") ?: ""
                )
        )
    }

    private fun makeResponse(ctx: RoutingContext, response: Response) {
        ctx.response().apply {
            for ((k, v) in response.headers)
                putHeader(k, v)
            statusCode = response.code
            response.body?.let { putHeader("Content-Type", it.contentType) }
            end(io.vertx.core.buffer.Buffer.buffer(response.body?.content?.bytes))
        }
    }
}
{'fraction_non_alphanumeric': 0.1015916017609211, 'fraction_numerical': 0.0, 'mean_word_length': 1.8276687410244137, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4152214', 'n_tokens_mistral': 1590, 'n_tokens_neox': 1554, 'n_words': 319}