diff --git a/build.gradle b/build.gradle index 463f4ec..caca0e9 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,7 @@ dependencies { compile 'org.eclipse.jetty:jetty-server:9.4.27.v20200227' compile 'org.eclipse.jetty:jetty-servlet:9.4.27.v20200227' - compile 'com.github.DaikonWeb:daikon-core:1.4.0' + compile 'com.github.DaikonWeb:daikon-core:1.4.1' testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.2' diff --git a/src/main/kotlin/daikon/HttpRequest.kt b/src/main/kotlin/daikon/HttpRequest.kt index 3a1774e..d6b0465 100644 --- a/src/main/kotlin/daikon/HttpRequest.kt +++ b/src/main/kotlin/daikon/HttpRequest.kt @@ -1,15 +1,16 @@ package daikon import daikon.core.Method +import daikon.core.Part import daikon.core.PathParams import daikon.core.Request import java.net.URLDecoder.decode -import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets.UTF_8 import javax.servlet.http.HttpServletRequest class HttpRequest(private val request: HttpServletRequest) : Request { private val body by lazy { request.inputStream.readBytes() } + private val multipartBody by lazy { request.parts } private lateinit var pathParams: PathParams override fun withPathParams(value: String): HttpRequest { @@ -34,6 +35,14 @@ class HttpRequest(private val request: HttpServletRequest) : Request { override fun body() = body.toString(UTF_8) + override fun multipart(name: String): Part { + val part = multipartBody.single { it.name == name } + val file = part.inputStream.readBytes() + val partName = part.submittedFileName ?: part.name + + return Part(partName, part.contentType, file) + } + override fun header(name: String): String = request.getHeader(name) override fun hasHeader(name: String) = request.headerNames.toList().contains(name) diff --git a/src/main/kotlin/daikon/HttpServer.kt b/src/main/kotlin/daikon/HttpServer.kt index 5bb7cd8..d2cf3d3 100644 --- a/src/main/kotlin/daikon/HttpServer.kt +++ b/src/main/kotlin/daikon/HttpServer.kt @@ -8,6 +8,7 @@ import org.eclipse.jetty.servlet.ServletHolder import org.eclipse.jetty.util.log.Log import java.time.LocalDateTime.now import java.time.temporal.ChronoUnit.MILLIS +import javax.servlet.MultipartConfigElement class HttpServer(private val port: Int = 4545, initializeActions: DaikonServer.() -> Unit = {}): DaikonServer(initializeActions) { @@ -22,7 +23,9 @@ class HttpServer(private val port: Int = 4545, initializeActions: DaikonServer.( val beginStarting = now() server = Server(port) context.addAttribute("port", port) - handler.addServlet(ServletHolder(RoutingServlet(routingHandler)), "/*") + val servletHolder = ServletHolder(RoutingServlet(routingHandler)) + servletHolder.registration.setMultipartConfig(MultipartConfigElement("/tmp")) + handler.addServlet(servletHolder, "/*") server.handler = handler server.start() val endStarting = now() diff --git a/src/test/kotlin/daikon/RequestTest.kt b/src/test/kotlin/daikon/RequestTest.kt index f7be570..3c959ee 100644 --- a/src/test/kotlin/daikon/RequestTest.kt +++ b/src/test/kotlin/daikon/RequestTest.kt @@ -1,8 +1,11 @@ package daikon import daikon.core.HttpStatus.INTERNAL_SERVER_ERROR_500 +import daikon.core.Request import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test +import topinambur.FieldPart +import topinambur.FilePart import topinambur.http class RequestTest { @@ -215,4 +218,44 @@ class RequestTest { assertThat(local("/").http.post().body).isEqualTo("POST") } } + + @Test + fun `receive a file`() { + HttpServer() + .post("/*") { req: Request, res -> + val file = req.multipart("firstData") + + res.write(file.content) + } + .start() + .use { + val response = local("/").http.post( + data = mapOf("firstData" to FilePart("file", "txt", "testo da convertire".toByteArray())) + ) + + assertThat(response.body).isEqualTo("testo da convertire") + } + } + + @Test + fun `receive a file and a field`() { + HttpServer() + .post("/*") { req: Request, res -> + val file = req.multipart("firstData") + val field = req.multipart("secondData") + + res.write("""${file.content.toString(Charsets.UTF_8)} | ${field.content.toString(Charsets.UTF_8)}""") + } + .start() + .use { + val response = local("/").http.post( + data = mapOf( + "firstData" to FilePart("file", "txt", "testo da convertire".toByteArray()), + "secondData" to FieldPart("valore") + ) + ) + + assertThat(response.body).isEqualTo("testo da convertire | valore") + } + } } \ No newline at end of file