Skip to content

Commit

Permalink
Merge pull request #13583 from iterate-ch/bugfix/GH-13568
Browse files Browse the repository at this point in the history
Review handling of 412 reply on upload
  • Loading branch information
dkocher authored Oct 16, 2023
2 parents 107985a + 8a05f11 commit 61add2b
Showing 1 changed file with 19 additions and 23 deletions.
42 changes: 19 additions & 23 deletions webdav/src/main/java/ch/cyberduck/core/dav/DAVWriteFeature.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import ch.cyberduck.core.Path;
import ch.cyberduck.core.VoidAttributesAdapter;
import ch.cyberduck.core.exception.BackgroundException;
import ch.cyberduck.core.exception.ConflictException;
import ch.cyberduck.core.exception.UnsupportedException;
import ch.cyberduck.core.features.Lock;
import ch.cyberduck.core.features.Write;
Expand All @@ -34,7 +35,6 @@

import org.apache.http.Header;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpStatus;
import org.apache.http.entity.AbstractHttpEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
Expand Down Expand Up @@ -70,8 +70,19 @@ public DAVWriteFeature(final DAVSession session, final boolean expect) {

@Override
public HttpResponseOutputStream<Void> write(final Path file, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException {
final List<Header> headers = this.getHeaders(file, status);
return this.write(file, headers, status);
try {
return this.write(file, this.getHeaders(file, status), status);
}
catch(ConflictException e) {
if(expect) {
if(null != status.getLockId()) {
// Handle 412 Precondition Failed with expired token
log.warn(String.format("Retry failure %s with lock id %s removed", e, status.getLockId()));
return this.write(file, this.getHeaders(file, status.withLockId(null)), status);
}
}
throw e;
}
}

protected List<Header> getHeaders(final Path file, final TransferStatus status) throws UnsupportedException {
Expand Down Expand Up @@ -102,7 +113,8 @@ protected List<Header> getHeaders(final Path file, final TransferStatus status)
return headers;
}

private HttpResponseOutputStream<Void> write(final Path file, final List<Header> headers, final TransferStatus status) throws BackgroundException {
private HttpResponseOutputStream<Void> write(final Path file, final List<Header> headers, final TransferStatus status)
throws BackgroundException {
// Submit store call to background thread
final DelayedHttpEntityCallable<Void> command = new DelayedHttpEntityCallable<Void>(file) {
/**
Expand All @@ -111,25 +123,9 @@ private HttpResponseOutputStream<Void> write(final Path file, final List<Header>
@Override
public Void call(final AbstractHttpEntity entity) throws BackgroundException {
try {
try {
session.getClient().put(new DAVPathEncoder().encode(file), entity, headers, new ETagResponseHandler());
return null;
}
catch(SardineException e) {
if(null != status.getLockId()) {
switch(e.getStatusCode()) {
case HttpStatus.SC_PRECONDITION_FAILED:
// Handle 412 Precondition Failed with expired token
log.warn(String.format("Retry failure %s with lock id %s removed", e, status.getLockId()));
headers.removeIf(header -> HttpHeaders.IF.equals(header.getName()));
session.getClient().put(new DAVPathEncoder().encode(file), entity, headers, new ETagResponseHandler());
// No remote attributes from server returned after upload
return null;

}
}
throw e;
}
session.getClient().put(new DAVPathEncoder().encode(file), entity,
headers, new ETagResponseHandler());
return null;
}
catch(SardineException e) {
throw new DAVExceptionMappingService().map("Upload {0} failed", e, file);
Expand Down

0 comments on commit 61add2b

Please sign in to comment.