Skip to content
Snippets Groups Projects

feat: Add SpringerDownloadService

Merged Mathieu.Vonlanthen requested to merge MVO-download-springer into master
3 files
+ 123
0
Compare changes
  • Side-by-side
  • Inline
Files
3
package ch.unige.aou.service;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import ch.unige.solidify.util.StringTool;
@Service
public class SpringerDownloadService {
private static final int MAX_REDIRECT = 10;
public void download(URI uri, Path path) {
final WebClient client = WebClient.create();
ResponseEntity<Void> responseEntity;
URI location = uri;
Map<String, String> cookies = new HashMap<>();
int nbRedirect = 0;
// Follow redirects
do {
responseEntity = getClientResponse(client, location, cookies);
URI newLocation = responseEntity.getHeaders().getLocation();
if(newLocation != null) {
location = newLocation;
}
List<String> receivedCookies = responseEntity.getHeaders().get("Set-Cookie");
if(receivedCookies != null) {
for (String cookieToMerge : receivedCookies) {
final String cookieNameValue = cookieToMerge.substring(0, cookieToMerge.indexOf(';'));
final String cookieName = cookieNameValue.substring(0, cookieNameValue.indexOf('='));
final String cookieValue = cookieNameValue.substring(cookieNameValue.indexOf('=') + 1);
cookies.put(cookieName, cookieValue);
}
}
nbRedirect++;
} while(responseEntity.getStatusCode().is3xxRedirection() && nbRedirect < MAX_REDIRECT);
// Trigger download
Flux<DataBuffer> dataBufferFlux = client.get()
.uri(location)
.headers(this.getCookieConsumer(cookies))
.retrieve()
.bodyToFlux(DataBuffer.class);
DataBufferUtils.write(dataBufferFlux, path, StandardOpenOption.CREATE).block();
}
private ResponseEntity<Void> getClientResponse(WebClient client, URI uri, Map<String, String> cookies) {
return client.get()
.uri(uri)
.headers(this.getCookieConsumer(cookies))
.retrieve()
.onStatus(status -> true, response -> Mono.empty())
.toBodilessEntity()
.block();
}
private String getCookieString(Map<String, String> cookies) {
StringBuilder cookieString = new StringBuilder();
for(Map.Entry<String, String> cookieNameValue : cookies.entrySet()) {
cookieString.append(cookieNameValue.getKey())
.append("=")
.append(cookieNameValue.getValue())
.append("; ");
}
return cookieString.toString();
}
private Consumer<HttpHeaders> getCookieConsumer(Map<String,String> cookies) {
return headers -> {
final String cookieString = this.getCookieString(cookies);
if (!StringTool.isNullOrEmpty(cookieString)) {
headers.set("Cookie", cookieString);
}
};
}
}
Loading