Skip to content

Commit

Permalink
Use UUID for multipart/form-data boundaries
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanBratanov committed Jan 29, 2024
1 parent f72b960 commit d920871
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 26 deletions.
18 changes: 10 additions & 8 deletions src/main/java/io/github/stefanbratanov/jvm/openai/AudioClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,8 @@ private HttpRequest createSpeechPostRequest(SpeechRequest request) {
}

private HttpRequest createTranscriptPostRequest(TranscriptionRequest request) {
long boundary = System.currentTimeMillis();
MultipartBodyPublisher.Builder multipartBodyPublisherBuilder =
MultipartBodyPublisher.newBuilder(boundary)
MultipartBodyPublisher.newBuilder()
.filePart("file", request.file())
.textPart("model", request.model());
request
Expand All @@ -135,17 +134,18 @@ private HttpRequest createTranscriptPostRequest(TranscriptionRequest request) {
.ifPresent(
temperature -> multipartBodyPublisherBuilder.textPart("temperature", temperature));

MultipartBodyPublisher multipartBodyPublisher = multipartBodyPublisherBuilder.build();

return newHttpRequestBuilder(
Constants.CONTENT_TYPE_HEADER, "multipart/form-data; boundary=" + boundary)
Constants.CONTENT_TYPE_HEADER, multipartBodyPublisher.getContentTypeHeader())
.uri(baseUrl.resolve(Endpoint.TRANSCRIPTION.getPath()))
.POST(multipartBodyPublisherBuilder.build())
.POST(multipartBodyPublisher)
.build();
}

private HttpRequest createTranslationPostRequest(TranslationRequest request) {
long boundary = System.currentTimeMillis();
MultipartBodyPublisher.Builder multipartBodyPublisherBuilder =
MultipartBodyPublisher.newBuilder(boundary)
MultipartBodyPublisher.newBuilder()
.filePart("file", request.file())
.textPart("model", request.model());
request.prompt().ifPresent(prompt -> multipartBodyPublisherBuilder.textPart("prompt", prompt));
Expand All @@ -154,10 +154,12 @@ private HttpRequest createTranslationPostRequest(TranslationRequest request) {
.ifPresent(
temperature -> multipartBodyPublisherBuilder.textPart("temperature", temperature));

MultipartBodyPublisher multipartBodyPublisher = multipartBodyPublisherBuilder.build();

return newHttpRequestBuilder(
Constants.CONTENT_TYPE_HEADER, "multipart/form-data; boundary=" + boundary)
Constants.CONTENT_TYPE_HEADER, multipartBodyPublisher.getContentTypeHeader())
.uri(baseUrl.resolve(Endpoint.TRANSLATION.getPath()))
.POST(multipartBodyPublisherBuilder.build())
.POST(multipartBodyPublisher)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,15 @@ public final class FilesClient extends OpenAIClient {
* @throws OpenAIException in case of API errors
*/
public File uploadFile(UploadFileRequest request) {
long boundary = System.currentTimeMillis();
MultipartBodyPublisher multipartBodyPublisher =
MultipartBodyPublisher.newBuilder(boundary)
MultipartBodyPublisher.newBuilder()
.filePart("file", request.file())
.textPart("purpose", request.purpose())
.build();

HttpRequest httpRequest =
newHttpRequestBuilder(
Constants.CONTENT_TYPE_HEADER, "multipart/form-data; boundary=" + boundary)
Constants.CONTENT_TYPE_HEADER, multipartBodyPublisher.getContentTypeHeader())
.uri(baseUrl.resolve(Endpoint.FILES.getPath()))
.POST(multipartBodyPublisher)
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,8 @@ private HttpRequest createImagePostRequest(CreateImageRequest request) {
}

private HttpRequest editImagePostRequest(EditImageRequest request) {
long boundary = System.currentTimeMillis();
MultipartBodyPublisher.Builder multipartBodyPublisherBuilder =
MultipartBodyPublisher.newBuilder(boundary)
MultipartBodyPublisher.newBuilder()
.filePart("image", request.image())
.textPart("prompt", request.prompt());
request.mask().ifPresent(mask -> multipartBodyPublisherBuilder.filePart("mask", mask));
Expand All @@ -114,17 +113,18 @@ private HttpRequest editImagePostRequest(EditImageRequest request) {
multipartBodyPublisherBuilder.textPart("response_format", responseFormat));
request.user().ifPresent(user -> multipartBodyPublisherBuilder.textPart("user", user));

MultipartBodyPublisher multipartBodyPublisher = multipartBodyPublisherBuilder.build();

return newHttpRequestBuilder(
Constants.CONTENT_TYPE_HEADER, "multipart/form-data; boundary=" + boundary)
Constants.CONTENT_TYPE_HEADER, multipartBodyPublisher.getContentTypeHeader())
.uri(baseUrl.resolve(Endpoint.IMAGE_EDIT.getPath()))
.POST(multipartBodyPublisherBuilder.build())
.POST(multipartBodyPublisher)
.build();
}

private HttpRequest createImageVariationPostRequest(CreateImageVariationRequest request) {
long boundary = System.currentTimeMillis();
MultipartBodyPublisher.Builder multipartBodyPublisherBuilder =
MultipartBodyPublisher.newBuilder(boundary).filePart("image", request.image());
MultipartBodyPublisher.newBuilder().filePart("image", request.image());
request.model().ifPresent(model -> multipartBodyPublisherBuilder.textPart("model", model));
request
.responseFormat()
Expand All @@ -135,10 +135,12 @@ private HttpRequest createImageVariationPostRequest(CreateImageVariationRequest
request.size().ifPresent(size -> multipartBodyPublisherBuilder.textPart("size", size));
request.user().ifPresent(user -> multipartBodyPublisherBuilder.textPart("user", user));

MultipartBodyPublisher multipartBodyPublisher = multipartBodyPublisherBuilder.build();

return newHttpRequestBuilder(
Constants.CONTENT_TYPE_HEADER, "multipart/form-data; boundary=" + boundary)
Constants.CONTENT_TYPE_HEADER, multipartBodyPublisher.getContentTypeHeader())
.uri(baseUrl.resolve(Endpoint.IMAGE_VARIATION.getPath()))
.POST(multipartBodyPublisherBuilder.build())
.POST(multipartBodyPublisher)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Flow;

class MultipartBodyPublisher implements HttpRequest.BodyPublisher {

private final String boundary;
private final List<byte[]> multipartBodyParts;

private MultipartBodyPublisher(List<byte[]> multipartBodyParts) {
private MultipartBodyPublisher(String boundary, List<byte[]> multipartBodyParts) {
this.boundary = boundary;
this.multipartBodyParts = multipartBodyParts;
}

Expand Down Expand Up @@ -48,21 +51,25 @@ public void cancel() {
});
}

static Builder newBuilder(long boundary) {
return new Builder(boundary);
String getContentTypeHeader() {
return "multipart/form-data; boundary=" + boundary;
}

static Builder newBuilder() {
return new Builder();
}

static class Builder {

private static final String CRLF = "\r\n";

private final long boundary;
private final String boundary;
private final String separator;

private final List<byte[]> multipartBodyParts = new ArrayList<>();

Builder(long boundary) {
this.boundary = boundary;
Builder() {
boundary = UUID.randomUUID().toString();
separator = "--" + boundary + CRLF + "Content-Disposition: form-data; name=";
}

Expand Down Expand Up @@ -102,7 +109,7 @@ Builder filePart(String key, Path value) {

MultipartBodyPublisher build() {
multipartBodyParts.add(("--" + boundary + "--").getBytes());
return new MultipartBodyPublisher(multipartBodyParts);
return new MultipartBodyPublisher(boundary, multipartBodyParts);
}
}
}

0 comments on commit d920871

Please sign in to comment.