Skip to content

Commit

Permalink
moved methods from being extension methods to part of HttpMessage
Browse files Browse the repository at this point in the history
  • Loading branch information
daviddenton committed May 3, 2017
1 parent 66a6ff1 commit 765d8e9
Show file tree
Hide file tree
Showing 15 changed files with 46 additions and 40 deletions.
5 changes: 5 additions & 0 deletions build.sh
@@ -0,0 +1,5 @@
#!/bin/bash

set -e

./gradlew clean build
Expand Up @@ -4,7 +4,6 @@ import org.reekwest.http.core.Response
import org.reekwest.http.core.Status.Companion.BAD_REQUEST
import org.reekwest.http.core.Status.Companion.NOT_FOUND
import org.reekwest.http.core.Status.Companion.OK
import org.reekwest.http.core.bodyString
import org.reekwest.http.core.with
import org.reekwest.http.formats.Json
import org.reekwest.http.lens.Failure
Expand All @@ -29,7 +28,7 @@ class SimpleJson<ROOT : NODE, out NODE : Any>(private val json: Json<ROOT, NODE>

override fun notFound(): Response = Response(NOT_FOUND)

override fun badRequest(failures: Iterable<Failure>) = Response(BAD_REQUEST).bodyString(failures.joinToString())
override fun badRequest(failures: Iterable<Failure>) = Response(BAD_REQUEST).body(failures.joinToString())

private fun render(basePath: BasePath, route: ServerRoute) =
route.pathBinder.core.method.toString() + ":" + route.describeFor(basePath) to
Expand Down
Expand Up @@ -8,7 +8,6 @@ import org.reekwest.http.core.Request.Companion.get
import org.reekwest.http.core.Response
import org.reekwest.http.core.Status.Companion.OK
import org.reekwest.http.core.Status.Companion.UNAUTHORIZED
import org.reekwest.http.core.body
import org.reekwest.http.lens.Query
import org.reekwest.http.lens.int

Expand Down
Expand Up @@ -10,7 +10,6 @@ import org.reekwest.http.core.Method.GET
import org.reekwest.http.core.Request
import org.reekwest.http.core.Request.Companion.get
import org.reekwest.http.core.Response.Companion.ok
import org.reekwest.http.core.bodyString
import org.reekwest.http.routing.by
import org.reekwest.http.routing.routes

Expand All @@ -21,8 +20,8 @@ class JettyServerTest {
@Before
fun before() {
server = routes(
GET to "/" by { _: Request -> ok().bodyString("Hello World") },
GET to "/request-headers" by { request: Request -> ok().bodyString(request.headerValues("foo").joinToString(", ")) }
GET to "/" by { _: Request -> ok().body("Hello World") },
GET to "/request-headers" by { request: Request -> ok().body(request.headerValues("foo").joinToString(", ")) }
).startJettyServer(block = false)
}

Expand Down
Expand Up @@ -9,7 +9,6 @@ import org.reekwest.http.core.cookie.CookieAttribute.Companion.HTTP_ONLY
import org.reekwest.http.core.cookie.CookieAttribute.Companion.MAX_AGE
import org.reekwest.http.core.cookie.CookieAttribute.Companion.PATH
import org.reekwest.http.core.cookie.CookieAttribute.Companion.SECURE
import org.reekwest.http.core.replaceHeader
import org.reekwest.http.unquoted
import java.time.LocalDateTime
import java.time.ZoneId
Expand Down
33 changes: 23 additions & 10 deletions reekwest/src/main/kotlin/org/reekwest/http/core/http.kt
Expand Up @@ -17,6 +17,14 @@ sealed class HttpMessage {

abstract fun header(name: String, value: String?): HttpMessage

abstract fun replaceHeader(name: String, value: String?): HttpMessage

abstract fun removeHeader(name: String): HttpMessage

abstract fun body(body: Body?): HttpMessage

abstract fun body(body: String): HttpMessage

fun headerValues(name: String): List<String?> = headers.filter { it.first.equals(name, true) }.map { it.second }

fun bodyString(): String = body.string()
Expand Down Expand Up @@ -55,6 +63,13 @@ data class Request(val method: Method, val uri: Uri, override val headers: Heade
fun queries(name: String): List<String?> = uri.queries().findMultiple(name)

override fun header(name: String, value: String?) = copy(headers = headers.plus(name to value))
override fun replaceHeader(name: String, value: String?) = copy(headers = headers.remove(name).plus(name to value))

override fun removeHeader(name: String) = copy(headers = headers.remove(name))

override fun body(body: Body?) = copy(body = body)

override fun body(body: String) = copy(body = body.toBody())

override fun toMessage() = listOf("$method $uri $version", headers.toMessage(), bodyString()).joinToString("\r\n")

Expand All @@ -73,22 +88,20 @@ data class Response(val status: Status, override val headers: Headers = listOf()
fun found(headers: Headers = listOf(), body: Body? = null) = Response(Status.FOUND, headers, body)
}

override fun header(name: String, value: String?): Response = copy(headers = headers.plus(name to value))

override fun toMessage(): String = listOf("$version $status", headers.toMessage(), bodyString()).joinToString("\r\n")
override fun header(name: String, value: String?) = copy(headers = headers.plus(name to value))

override fun toString(): String = toMessage()
}
override fun replaceHeader(name: String, value: String?) = copy(headers = headers.remove(name).plus(name to value))

fun <T : HttpMessage> T.replaceHeader(name: String, value: String?): T = copy(headers = headers.remove(name).plus(name to value))
override fun removeHeader(name: String) = copy(headers = headers.remove(name))

fun <T : HttpMessage> T.removeHeader(name: String): T = copy(headers = headers.remove(name))
override fun body(body: Body?) = copy(body = body)

fun <T : HttpMessage> T.body(body: Body?): T = copy(body = body)
override fun body(body: String) = copy(body = body.toBody())

fun <T : HttpMessage> T.body(body: String): T = copy(body = body.toBody())
override fun toMessage(): String = listOf("$version $status", headers.toMessage(), bodyString()).joinToString("\r\n")

fun <T : HttpMessage> T.bodyString(body: String): T = body(body)
override fun toString(): String = toMessage()
}

fun <T : HttpMessage> T.copy(headers: Parameters = this.headers, body: Body? = this.body): T = when (this) {
is Request -> this.copy(headers = headers, body = body) as T
Expand Down
6 changes: 2 additions & 4 deletions reekwest/src/test/kotlin/org/reekwest/http/CurlTest.kt
Expand Up @@ -5,9 +5,7 @@ import com.natpryce.hamkrest.equalTo
import org.junit.Test
import org.reekwest.http.core.Request.Companion.get
import org.reekwest.http.core.Request.Companion.post
import org.reekwest.http.core.body
import org.reekwest.http.core.body.toBody
import org.reekwest.http.core.bodyString
import org.reekwest.http.core.toCurl

class CurlTest {
Expand Down Expand Up @@ -44,14 +42,14 @@ class CurlTest {

@Test
fun `escapes body string`() {
val curl = get("http://httpbin.org").bodyString("my \"quote\"").toCurl()
val curl = get("http://httpbin.org").body("my \"quote\"").toCurl()
assertThat(curl, equalTo("""curl -X GET --data "my \"quote\"" "http://httpbin.org""""))
}

@Test
fun `limits the entity if it's too large`() {
val largeBody = (0..500).joinToString(" ")
val curl = get("http://httpbin.org").bodyString(largeBody).toCurl()
val curl = get("http://httpbin.org").body(largeBody).toCurl()
val data = "data \"([^\"]+)\"".toRegex().find(curl)?.groupValues?.get(1)!!
assertThat(data.length, equalTo(256 + "[truncated]".length))
}
Expand Down
Expand Up @@ -19,14 +19,14 @@ class HttpHandlerTest {

@Test
fun query_parameters() {
val handler = { request: Request -> ok().bodyString("Hello, ${request.query("name")}") }
val handler = { request: Request -> ok().body("Hello, ${request.query("name")}") }
val response = handler(get("/").query("name", "John Doe"))
assertThat(response, equalTo(ok().bodyString("Hello, John Doe")))
assertThat(response, equalTo(ok().body("Hello, John Doe")))
}

@Test
fun form_handling() {
val handler = { request: Request -> ok().bodyString("Hello, ${request.form("name")}") }
val handler = { request: Request -> ok().body("Hello, ${request.form("name")}") }
val form = listOf("name" to "John Doe")

val response = handler(post("irrelevant").body(form.toBody()))
Expand Down
Expand Up @@ -4,11 +4,10 @@ import com.natpryce.hamkrest.assertion.assertThat
import com.natpryce.hamkrest.equalTo
import org.junit.Test
import org.reekwest.http.core.Response.Companion.ok
import org.reekwest.http.core.bodyString

class StringBodyTest {
@Test
fun can_use_string_as_entity() {
assertThat(ok().bodyString("abc").bodyString(), equalTo("abc"))
assertThat(ok().body("abc").bodyString(), equalTo("abc"))
}
}
Expand Up @@ -12,7 +12,6 @@ import org.reekwest.http.core.Response.Companion.movedPermanently
import org.reekwest.http.core.Response.Companion.movedTemporarily
import org.reekwest.http.core.Response.Companion.ok
import org.reekwest.http.core.Response.Companion.serverError
import org.reekwest.http.core.body
import org.reekwest.http.core.then

class ClientFiltersTest {
Expand Down
3 changes: 1 addition & 2 deletions reekwest/src/test/kotlin/org/reekwest/http/lens/BodyTest.kt
Expand Up @@ -4,7 +4,6 @@ import com.natpryce.hamkrest.assertion.assertThat
import com.natpryce.hamkrest.equalTo
import org.junit.Test
import org.reekwest.http.core.Request.Companion.get
import org.reekwest.http.core.bodyString
import org.reekwest.http.core.toBody

class BodyTest {
Expand Down Expand Up @@ -39,7 +38,7 @@ class BodyTest {
@Test
fun `can create a one way custom Body type`() {
val customBody = Body.string.map(::MyCustomBodyType).required()
assertThat(customBody(emptyRequest.bodyString("hello world!")), equalTo(MyCustomBodyType("hello world!")))
assertThat(customBody(emptyRequest.body("hello world!")), equalTo(MyCustomBodyType("hello world!")))
}
}

Expand Down
Expand Up @@ -11,7 +11,6 @@ import org.reekwest.http.core.Request.Companion.post
import org.reekwest.http.core.Response.Companion.ok
import org.reekwest.http.core.Status.Companion.METHOD_NOT_ALLOWED
import org.reekwest.http.core.Status.Companion.NOT_FOUND
import org.reekwest.http.core.bodyString

class RoutedHandlerTest {

Expand All @@ -28,7 +27,7 @@ class RoutedHandlerTest {
@Test
fun method_not_allowed() {
val routes = routes(
GET to "/a/{route}" by { _: Request -> ok().bodyString("matched") }
GET to "/a/{route}" by { _: Request -> ok().body("matched") }
)

val response = routes(post("/a/something"))
Expand All @@ -39,7 +38,7 @@ class RoutedHandlerTest {
@Test
fun matches_uri_template_and_method() {
val routes = routes(
GET to "/a/{route}" by { _: Request -> ok().bodyString("matched") }
GET to "/a/{route}" by { _: Request -> ok().body("matched") }
)

val response = routes(get("/a/something"))
Expand All @@ -50,8 +49,8 @@ class RoutedHandlerTest {
@Test
fun matches_uses_first_match() {
val routes = routes(
GET to "/a/{route}" by { _: Request -> ok().bodyString("matched a") },
GET to "/a/{route}" by { _: Request -> ok().bodyString("matched b") }
GET to "/a/{route}" by { _: Request -> ok().body("matched a") },
GET to "/a/{route}" by { _: Request -> ok().body("matched b") }
)

val response = routes(get("/a/something"))
Expand All @@ -62,7 +61,7 @@ class RoutedHandlerTest {
@Test
fun path_parameters_are_available_in_request() {
val routes = routes(
GET to "/{a}/{b}/{c}" by { req: Request -> ok().bodyString("matched ${req.path("a")}, ${req.path("b")}, ${req.path("c")}") }
GET to "/{a}/{b}/{c}" by { req: Request -> ok().body("matched ${req.path("a")}, ${req.path("b")}, ${req.path("c")}") }
)

val response = routes(get("/x/y/z"))
Expand Down
2 changes: 1 addition & 1 deletion release.sh
Expand Up @@ -13,7 +13,7 @@ function upgrade {

upgrade `./tools/jq -r .reekwest.old version.json` $NEW_VERSION

./gradlew --debug -PreleaseVersion=$NEW_VERSION clean build \
./gradlew -PreleaseVersion=$NEW_VERSION clean build \
:reekwest:bintrayUpload \
:reekwest-client-apache:bintrayUpload \
:reekwest-server-jetty:bintrayUpload \
Expand Down
3 changes: 1 addition & 2 deletions src/test/kotlin/cookbook/container_integration.kt
Expand Up @@ -4,12 +4,11 @@ import org.reekwest.http.apache.ApacheHttpClient
import org.reekwest.http.core.Request
import org.reekwest.http.core.Request.Companion.get
import org.reekwest.http.core.Response.Companion.ok
import org.reekwest.http.core.bodyString
import org.reekwest.http.jetty.asJettyServer

fun main(args: Array<String>) {

val app = { request: Request -> ok().bodyString("Hello, ${request.query("name")}!") }
val app = { request: Request -> ok().body("Hello, ${request.query("name")}!") }

val jettyServer = app.asJettyServer(9000)

Expand Down
3 changes: 1 addition & 2 deletions src/test/kotlin/cookbook/server_as_a_function.kt
Expand Up @@ -4,11 +4,10 @@ import org.reekwest.http.core.HttpHandler
import org.reekwest.http.core.Request
import org.reekwest.http.core.Request.Companion.get
import org.reekwest.http.core.Response.Companion.ok
import org.reekwest.http.core.bodyString

fun main(args: Array<String>) {

val app: HttpHandler = { request: Request -> ok().bodyString("Hello, ${request.query("name")}!") }
val app: HttpHandler = { request: Request -> ok().body("Hello, ${request.query("name")}!") }

val request = get("/").query("name", "John Doe")

Expand Down

0 comments on commit 765d8e9

Please sign in to comment.