jetty-reactive-httpclient
jetty-reactive-httpclient copied to clipboard
Add support of multipart form data
Provide utility method
Request.Content.fromParts(Publisher<Part>)
where Part
public interface Part {
/**
* Return the name of the part in the multipart form.
* @return the name of the part, never {@code null} or empty
*/
String name();
/**
* Return the headers associated with the part.
*/
HttpHeaders headers();
/**
* Return the content for this part.
* <p>Note that for a {@link FormFieldPart} the content may be accessed
* more easily via {@link FormFieldPart#value()}.
*/
Flux<DataBuffer> content();
/**
* Return a mono that, when subscribed to, deletes the underlying storage
* for this part.
* @since 5.3.13
*/
default Mono<Void> delete() {
return Mono.empty();
}
}
Can you clarify whether Part
is a class from some other library, or I should provide one in this project?
I would also need a use case.
Is this similar to HttpClient
's MultiPartRequestContent
, but reactive?
Took this Part interface from Spring. Don't know if there is analogue interface in Jetty. I'd like to add this functionality to jetty based reactive feign module
Is this similar to HttpClient's MultiPartRequestContent, but reactive?
Exactly
Upvoting this
We have https://github.com/eclipse/jetty.project/blob/f98b345a28fcefbf1fa8e16dc4b44605b68f2c62/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPart.java#L122 which is vaguely similar.
However, I do not think we make available a stream of those parts, only the collection of all Parts
once read. It should be possible to stream the parts, but the tricky issue will be that we would need to deliver the part before it's content was complete, and then allow the recipient to stream the content.
If we do this, it would likely be in the form of a jetty-12 style demand interface, but that is trivially convertible to a Publisher.
@lachlan-roberts thoughts?
@gregw I don't think this issue is asking to be able to stream the parts which have been received, but to publish parts to be sent into a Request.Content
.
But I think this is easily done. I think this should work?
static Content fromParts(Flow.Publisher<MultiPart.Part> publisher)
{
MultiPartRequestContent content = new MultiPartRequestContent();
publisher.subscribe(new Flow.Subscriber<>()
{
private Flow.Subscription _subscription;
@Override
public void onSubscribe(Flow.Subscription subscription)
{
_subscription = subscription;
_subscription.request(1);
}
@Override
public void onNext(MultiPart.Part item)
{
content.addPart(item);
_subscription.request(1);
}
@Override
public void onError(Throwable throwable)
{
content.fail(throwable);
}
@Override
public void onComplete()
{
content.close();
}
});
return content;
}
@lachlan-roberts yes the idea is correct, but we don't have MultiPart.Part
in Jetty 10/11, only in 12.
So perhaps we add this in the 4.x series of this project, based on Jetty 12.
@gregw I don't think this issue is asking to be able to stream the parts which have been received, but to publish parts to be sent into a
Request.Content
.
By "stream the parts" I mean publish them through a Flow
.
Are you sure this is a publish parts sent, rather than to be subscribed to parts received? Actually surely we need both?
@gregw this is the reactive client, so we need the "reactive" to both send and receive, although the receive part must be done by the application, so we can only provide utilities to take a reactive response body and turn it into reactive parts.