-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow body readers to read form uploads (#11011)
* Allow body readers to read form uploads * Correct route info * Improve
- Loading branch information
Showing
8 changed files
with
152 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
http-server-netty/src/test/groovy/io/micronaut/http/server/netty/CustomFileUploadSpec.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package io.micronaut.http.server.netty | ||
|
||
import io.micronaut.context.ApplicationContext | ||
import io.micronaut.context.annotation.Requires | ||
import io.micronaut.core.annotation.Nullable | ||
import io.micronaut.core.type.Argument | ||
import io.micronaut.core.type.Headers | ||
import io.micronaut.http.HttpRequest | ||
import io.micronaut.http.MediaType | ||
import io.micronaut.http.annotation.Body | ||
import io.micronaut.http.annotation.Consumes | ||
import io.micronaut.http.annotation.Controller | ||
import io.micronaut.http.annotation.Post | ||
import io.micronaut.http.annotation.Produces | ||
import io.micronaut.http.body.MessageBodyReader | ||
import io.micronaut.http.client.HttpClient | ||
import io.micronaut.http.client.multipart.MultipartBody | ||
import io.micronaut.http.codec.CodecException | ||
import io.micronaut.runtime.server.EmbeddedServer | ||
import jakarta.inject.Singleton | ||
import org.junit.Assert | ||
import org.jvnet.mimepull.Header | ||
import org.jvnet.mimepull.MIMEMessage | ||
import spock.lang.Specification | ||
|
||
import java.nio.charset.StandardCharsets | ||
import java.util.stream.Collectors | ||
|
||
class CustomFileUploadSpec extends Specification { | ||
|
||
def 'custom file upload'() { | ||
given: | ||
def ctx = ApplicationContext.run(['spec.name': 'CustomFileUploadSpec']) | ||
def server = ctx.getBean(EmbeddedServer) | ||
server.start() | ||
def client = ctx.createBean(HttpClient, server.URI).toBlocking() | ||
|
||
when: | ||
def response = client.exchange(HttpRequest.POST( | ||
'/multipart/file-upload', | ||
MultipartBody.builder().addPart('MyName', 'myFile', 'foo'.bytes).build()) | ||
.contentType(MediaType.MULTIPART_FORM_DATA_TYPE), String) | ||
then: | ||
response.body() == 'Uploaded content-disposition: form-data; name="MyName"; filename="myFile", content-length: 3, content-type: application/octet-stream, content-transfer-encoding: binary foo' | ||
|
||
cleanup: | ||
client.close() | ||
server.stop() | ||
} | ||
|
||
@Controller('/multipart') | ||
@Requires(property = 'spec.name', value = 'CustomFileUploadSpec') | ||
@Produces(MediaType.TEXT_PLAIN) | ||
static class MultipartController { | ||
@Post(value = '/file-upload', consumes = MediaType.MULTIPART_FORM_DATA) | ||
String completeFileUpload(@Body MyFileUpload data) { | ||
return "Uploaded " + data.value() | ||
} | ||
|
||
} | ||
|
||
record MyFileUpload(String value) { | ||
} | ||
|
||
@Singleton | ||
@Consumes("multipart/form-data") | ||
static class MyFileUpdateReader implements MessageBodyReader<MyFileUpload> { | ||
|
||
@Override | ||
MyFileUpload read(Argument<MyFileUpload> type, MediaType mediaType, Headers httpHeaders, InputStream inputStream) throws CodecException { | ||
MIMEMessage mimeMessage = new MIMEMessage(inputStream, mediaType.getParameters().get("boundary").orElse("")) | ||
mimeMessage.parseAll() | ||
def attachments = mimeMessage.getAttachments() | ||
Assert.assertEquals(1, attachments.size()) | ||
def part = attachments.get(0) | ||
def headers = part.getAllHeaders().stream().map { Header h -> h.name + ": " + h.value }.collect(Collectors.joining(", ")) | ||
return new MyFileUpload(headers + " " + new String(part.read().readAllBytes(), StandardCharsets.UTF_8)) | ||
} | ||
} | ||
|
||
record Metadata(@Nullable String foo) {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters