Skip to content

Instantly share code, notes, and snippets.

@behrangsa
Created December 2, 2019 11:34
Show Gist options
  • Save behrangsa/f645a9a8951936e9223381d5bf34bac5 to your computer and use it in GitHub Desktop.
Save behrangsa/f645a9a8951936e9223381d5bf34bac5 to your computer and use it in GitHub Desktop.
package xyz.behrang.uploader;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublisher;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class package xyz.behrang.uploader;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublisher;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
final var threadCount = 2;
final var threads = new ArrayList<Thread>();
for (int i = 0; i < threadCount; i++) {
threads.add(new Thread(new Uploader()));
}
threads.forEach(Thread::start);
threads.forEach(t -> {
try {
t.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
}
}
class Uploader implements Runnable {
@Override
public void run() {
try {
final var client =
HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.version(HttpClient.Version.HTTP_1_1)
.build();
final var body = new HashMap<>();
body.put("document", Paths.get("/home/behrangsa/Data/arxiv/arXiv_pdf_0001_001.tar"));
final var request =
HttpRequest.newBuilder()
.uri(URI.create("http://localhost:8080/file-server/sync/upload"))
.header("Content-Type", "multipart/form-data; boundary=foobarbaz")
.timeout(Duration.ofSeconds(10))
.POST(ofMimeMultipartData(body, "foobarbaz"))
.build();
final var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
// Copied from https://github.com/ralscha/blog2019/blob/master/java11httpclient/client/src/main/java/ch/rasc/httpclient/File.java#L69-L92
public static BodyPublisher ofMimeMultipartData(Map<Object, Object> data, String boundary) throws IOException {
final var byteArrays = new ArrayList<byte[]>();
final var separator = ("--" + boundary + "\r\nContent-Disposition: form-data; name=").getBytes(StandardCharsets.UTF_8);
for (final var entry : data.entrySet()) {
byteArrays.add(separator);
if (entry.getValue() instanceof Path) {
var path = (Path) entry.getValue();
String mimeType = Files.probeContentType(path);
byteArrays.add(("\"" + entry.getKey() + "\"; filename=\"" + path.getFileName()
+ "\"\r\nContent-Type: " + mimeType + "\r\n\r\n").getBytes(StandardCharsets.UTF_8));
byteArrays.add(Files.readAllBytes(path));
byteArrays.add("\r\n".getBytes(StandardCharsets.UTF_8));
} else {
byteArrays.add(("\"" + entry.getKey() + "\"\r\n\r\n" + entry.getValue() + "\r\n").getBytes(StandardCharsets.UTF_8));
}
}
byteArrays.add(("--" + boundary + "--").getBytes(StandardCharsets.UTF_8));
return BodyPublishers.ofByteArrays(byteArrays);
}
} {
public static void main(String[] args) {
final var threadCount = 2;
final var threads = new ArrayList<Thread>();
for (int i = 0; i < threadCount; i++) {
threads.add(new Thread(new Uploader()));
}
threads.forEach(Thread::start);
threads.forEach(t -> {
try {
t.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
}
}
class Uploader implements Runnable {
@Override
public void run() {
try {
final var client =
HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.version(HttpClient.Version.HTTP_1_1)
.build();
final var body = new HashMap<>();
body.put("document", Paths.get("/home/behrangsa/Data/arxiv/arXiv_pdf_0001_001.tar"));
final var request =
HttpRequest.newBuilder()
.uri(URI.create("http://localhost:8080/file-server/sync/upload"))
.header("Content-Type", "multipart/form-data; boundary=foobarbaz")
.timeout(Duration.ofSeconds(10))
.POST(ofMimeMultipartData(body, "foobarbaz"))
.build();
final var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
// Copied from https://github.com/ralscha/blog2019/blob/master/java11httpclient/client/src/main/java/ch/rasc/httpclient/File.java#L69-L92
public static BodyPublisher ofMimeMultipartData(Map<Object, Object> data, String boundary) throws IOException {
final var byteArrays = new ArrayList<byte[]>();
final var separator = ("--" + boundary + "\r\nContent-Disposition: form-data; name=").getBytes(StandardCharsets.UTF_8);
for (final var entry : data.entrySet()) {
byteArrays.add(separator);
if (entry.getValue() instanceof Path) {
var path = (Path) entry.getValue();
String mimeType = Files.probeContentType(path);
byteArrays.add(("\"" + entry.getKey() + "\"; filename=\"" + path.getFileName()
+ "\"\r\nContent-Type: " + mimeType + "\r\n\r\n").getBytes(StandardCharsets.UTF_8));
byteArrays.add(Files.readAllBytes(path));
byteArrays.add("\r\n".getBytes(StandardCharsets.UTF_8));
} else {
byteArrays.add(("\"" + entry.getKey() + "\"\r\n\r\n" + entry.getValue() + "\r\n").getBytes(StandardCharsets.UTF_8));
}
}
byteArrays.add(("--" + boundary + "--").getBytes(StandardCharsets.UTF_8));
return BodyPublishers.ofByteArrays(byteArrays);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment