use of ch.cyberduck.core.http.DelayedHttpEntityCallable in project cyberduck by iterate-ch.
the class BoxWriteFeature method write.
@Override
public HttpResponseOutputStream<File> write(final Path file, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException {
final DelayedHttpEntityCallable<File> command = new DelayedHttpEntityCallable<File>() {
@Override
public File call(final AbstractHttpEntity entity) throws BackgroundException {
try {
final HttpPost request;
if (status.isExists()) {
request = new HttpPost(String.format("%s/files/%s/content?fields=%s", client.getBasePath(), fileid.getFileId(file, new DisabledListProgressListener()), String.join(",", BoxAttributesFinderFeature.DEFAULT_FIELDS)));
} else {
request = new HttpPost(String.format("%s/files/content?fields=%s", client.getBasePath(), String.join(",", BoxAttributesFinderFeature.DEFAULT_FIELDS)));
}
final Checksum checksum = status.getChecksum();
if (Checksum.NONE != checksum) {
switch(checksum.algorithm) {
case sha1:
request.addHeader(HttpHeaders.CONTENT_MD5, checksum.hash);
}
}
final ByteArrayOutputStream content = new ByteArrayOutputStream();
new JSON().getContext(null).writeValue(content, new FilescontentAttributes().name(file.getName()).parent(new FilescontentAttributesParent().id(fileid.getFileId(file.getParent(), new DisabledListProgressListener()))).contentModifiedAt(status.getTimestamp() != null ? new DateTime(status.getTimestamp()) : null));
final MultipartEntityBuilder multipart = MultipartEntityBuilder.create();
multipart.addBinaryBody("attributes", content.toByteArray());
final ByteArrayOutputStream out = new ByteArrayOutputStream();
entity.writeTo(out);
multipart.addBinaryBody("file", out.toByteArray(), null == status.getMime() ? ContentType.APPLICATION_OCTET_STREAM : ContentType.create(status.getMime()), file.getName());
request.setEntity(multipart.build());
if (status.isExists()) {
if (StringUtils.isNotBlank(status.getRemote().getETag())) {
request.addHeader(new BasicHeader(HttpHeaders.IF_MATCH, status.getRemote().getETag()));
} else {
log.warn(String.format("Missing remote attributes in transfer status to read current ETag for %s", file));
}
}
final Files files = session.getClient().execute(request, new BoxClientErrorResponseHandler<Files>() {
@Override
public Files handleEntity(final HttpEntity entity) throws IOException {
return new JSON().getContext(null).readValue(entity.getContent(), Files.class);
}
});
if (log.isDebugEnabled()) {
log.debug(String.format("Received response %s for upload of %s", files, file));
}
if (files.getEntries().stream().findFirst().isPresent()) {
return files.getEntries().stream().findFirst().get();
}
throw new NotfoundException(file.getAbsolute());
} catch (HttpResponseException e) {
throw new DefaultHttpResponseExceptionMappingService().map(e);
} catch (IOException e) {
throw new DefaultIOExceptionMappingService().map("Upload {0} failed", e, file);
}
}
@Override
public long getContentLength() {
return -1L;
}
};
return this.write(file, status, command);
}
use of ch.cyberduck.core.http.DelayedHttpEntityCallable in project cyberduck by iterate-ch.
the class BoxChunkedWriteFeature method write.
@Override
public HttpResponseOutputStream<File> write(final Path file, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException {
final DelayedHttpEntityCallable<File> command = new DelayedHttpEntityCallable<File>() {
@Override
public File call(final AbstractHttpEntity entity) throws BackgroundException {
try {
final HttpRange range = HttpRange.withStatus(new TransferStatus().withLength(status.getLength()).withOffset(status.getOffset()));
final String uploadSessionId = status.getParameters().get(BoxLargeUploadService.UPLOAD_SESSION_ID);
final String overall_length = status.getParameters().get(BoxLargeUploadService.OVERALL_LENGTH);
if (log.isDebugEnabled()) {
log.debug(String.format("Send range %s for file %s", range, file));
}
final HttpPut request = new HttpPut(String.format("%s/files/upload_sessions/%s", client.getBasePath(), uploadSessionId));
// Must not overlap with the range of a part already uploaded this session.
request.addHeader(new BasicHeader(HttpHeaders.CONTENT_RANGE, String.format("bytes %d-%d/%d", range.getStart(), range.getEnd(), Long.valueOf(overall_length))));
request.addHeader(new BasicHeader("Digest", String.format("sha=%s", status.getChecksum())));
request.setEntity(entity);
final UploadedPart uploadedPart = session.getClient().execute(request, new BoxClientErrorResponseHandler<UploadedPart>() {
@Override
public UploadedPart handleEntity(final HttpEntity entity1) throws IOException {
return new JSON().getContext(null).readValue(entity1.getContent(), UploadedPart.class);
}
});
if (log.isDebugEnabled()) {
log.debug(String.format("Received response %s for upload of %s", uploadedPart, file));
}
return new File().size(status.getLength()).sha1(uploadedPart.getPart().getSha1());
} catch (HttpResponseException e) {
throw new DefaultHttpResponseExceptionMappingService().map(e);
} catch (IOException e) {
throw new DefaultIOExceptionMappingService().map("Upload {0} failed", e, file);
}
}
@Override
public long getContentLength() {
return -1L;
}
};
return this.write(file, status, command);
}
use of ch.cyberduck.core.http.DelayedHttpEntityCallable in project cyberduck by iterate-ch.
the class S3WriteFeature method write.
@Override
public HttpResponseOutputStream<StorageObject> write(final Path file, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException {
final S3Object object = this.getDetails(file, status);
final DelayedHttpEntityCallable<StorageObject> command = new DelayedHttpEntityCallable<StorageObject>() {
@Override
public StorageObject call(final AbstractHttpEntity entity) throws BackgroundException {
try {
final RequestEntityRestStorageService client = session.getClient();
final Path bucket = containerService.getContainer(file);
client.putObjectWithRequestEntityImpl(bucket.isRoot() ? StringUtils.EMPTY : bucket.getName(), object, entity, status.getParameters());
if (log.isDebugEnabled()) {
log.debug(String.format("Saved object %s with checksum %s", file, object.getETag()));
}
} catch (ServiceException e) {
throw new S3ExceptionMappingService().map("Upload {0} failed", e, file);
}
if (status.getTimestamp() != null) {
object.addMetadata(S3TimestampFeature.METADATA_MODIFICATION_DATE, String.valueOf(status.getTimestamp()));
}
return object;
}
@Override
public long getContentLength() {
return status.getLength();
}
};
return this.write(file, status, command);
}
use of ch.cyberduck.core.http.DelayedHttpEntityCallable in project cyberduck by iterate-ch.
the class StoregateWriteFeature method write.
@Override
public HttpResponseOutputStream<FileMetadata> write(final Path file, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException {
final DelayedHttpEntityCallable<FileMetadata> command = new DelayedHttpEntityCallable<FileMetadata>() {
@Override
public FileMetadata call(final AbstractHttpEntity entity) throws BackgroundException {
// Initiate a resumable upload
String location;
try {
location = start(file, status);
} catch (InteroperabilityException e) {
if (null == status.getLockId()) {
throw e;
}
location = start(file, status.withLockId(null));
}
final StoregateApiClient client = session.getClient();
try {
// Upload the file
final HttpPut put = new HttpPut(location);
put.setEntity(entity);
final String header;
if (status.getLength() == 0) {
// Touch
header = "*/0";
} else {
final HttpRange range = HttpRange.byLength(0, status.getLength());
header = String.format("%d-%d/%d", range.getStart(), range.getEnd(), status.getLength());
}
put.addHeader(HttpHeaders.CONTENT_RANGE, String.format("bytes %s", header));
final HttpResponse putResponse = client.getClient().execute(put);
try {
switch(putResponse.getStatusLine().getStatusCode()) {
case HttpStatus.SC_OK:
case HttpStatus.SC_CREATED:
final FileMetadata result = new JSON().getContext(FileMetadata.class).readValue(new InputStreamReader(putResponse.getEntity().getContent(), StandardCharsets.UTF_8), FileMetadata.class);
fileid.cache(file, result.getId());
return result;
default:
throw new StoregateExceptionMappingService(fileid).map(new ApiException(putResponse.getStatusLine().getStatusCode(), putResponse.getStatusLine().getReasonPhrase(), Collections.emptyMap(), EntityUtils.toString(putResponse.getEntity())));
}
} catch (BackgroundException e) {
// Cancel upload on error reply
cancel(file, location);
throw e;
} finally {
EntityUtils.consume(putResponse.getEntity());
}
} catch (IOException e) {
// Cancel upload on I/O failure
cancel(file, location);
throw new HttpExceptionMappingService().map("Upload {0} failed", e, file);
}
}
@Override
public long getContentLength() {
return status.getLength();
}
};
return this.write(file, status, command);
}
use of ch.cyberduck.core.http.DelayedHttpEntityCallable in project cyberduck by iterate-ch.
the class B2WriteFeature method write.
@Override
public HttpResponseOutputStream<BaseB2Response> write(final Path file, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException {
// Submit store call to background thread
final DelayedHttpEntityCallable<BaseB2Response> command = new DelayedHttpEntityCallable<BaseB2Response>() {
/**
* @return The SHA-1 returned by the server for the uploaded object
*/
@Override
public BaseB2Response call(final AbstractHttpEntity entity) throws BackgroundException {
try {
final Checksum checksum = status.getChecksum();
if (status.isSegment()) {
final B2GetUploadPartUrlResponse uploadUrl = session.getClient().getUploadPartUrl(status.getParameters().get("fileId"));
return session.getClient().uploadLargeFilePart(uploadUrl, status.getPart(), entity, checksum.hash);
} else {
if (null == urls.get()) {
final B2GetUploadUrlResponse uploadUrl = session.getClient().getUploadUrl(fileid.getVersionId(containerService.getContainer(file), new DisabledListProgressListener()));
if (log.isDebugEnabled()) {
log.debug(String.format("Obtained upload URL %s for file %s", uploadUrl, file));
}
urls.set(uploadUrl);
return this.upload(uploadUrl, entity, checksum);
} else {
final B2GetUploadUrlResponse uploadUrl = urls.get();
if (log.isDebugEnabled()) {
log.debug(String.format("Use cached upload URL %s for file %s", uploadUrl, file));
}
try {
return this.upload(uploadUrl, entity, checksum);
} catch (IOException | B2ApiException e) {
// Upload many files to the same upload_url until that URL gives an error
log.warn(String.format("Remove cached upload URL after failure %s", e));
urls.remove();
// Retry
return this.upload(uploadUrl, entity, checksum);
}
}
}
} catch (B2ApiException e) {
throw new B2ExceptionMappingService(fileid).map("Upload {0} failed", e, file);
} catch (IOException e) {
throw new DefaultIOExceptionMappingService().map("Upload {0} failed", e, file);
}
}
private BaseB2Response upload(final B2GetUploadUrlResponse uploadUrl, final AbstractHttpEntity entity, final Checksum checksum) throws B2ApiException, IOException {
final Map<String, String> fileinfo = new HashMap<>(status.getMetadata());
if (null != status.getTimestamp()) {
fileinfo.put(X_BZ_INFO_SRC_LAST_MODIFIED_MILLIS, String.valueOf(status.getTimestamp()));
}
final B2FileResponse response = session.getClient().uploadFile(uploadUrl, containerService.getKey(file), entity, checksum.algorithm == HashAlgorithm.sha1 ? checksum.hash : "do_not_verify", status.getMime(), fileinfo);
fileid.cache(file, response.getFileId());
return response;
}
@Override
public long getContentLength() {
return status.getLength();
}
};
return this.write(file, status, command);
}
Aggregations