Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upload of files >2GB to WebDAV fails #531

Closed
2 tasks done
SailReal opened this issue Apr 18, 2024 · 0 comments
Closed
2 tasks done

Upload of files >2GB to WebDAV fails #531

SailReal opened this issue Apr 18, 2024 · 0 comments
Labels
storage:webdav type:bug Something isn't working
Milestone

Comments

@SailReal
Copy link
Member

SailReal commented Apr 18, 2024

Please agree to the following

Summary

When I try to upload a >2GB file to a WebDAV vault, it fails.

System Setup

- Android: x
- Cryptomator: 1.10.0

Cloud Type

WebDAV

Steps to Reproduce

  1. Create a file with around 2048MB, e.g. dd if=/dev/zero of=filename bs=1M count=2049
  2. Upload this file to any WebDAV based vault

Expected Behavior

File gets uploaded

Actual Behavior

Error is thrown during upload

Reproducibility

Always

Relevant Log Output

D	20240417195529.899	OkHttp	--> PUT https://webdav.example.com/folder1/CR3/d/7X/QQLXM7M2LRF4E7SKEKEUGIK5DF5ONX/w0xGtrecX7-TeJe5SKkzvFlx-RSzIVw9VSvHg3SlgKvPSYJN7_8NgFuj.c9r http/1.1 (0-byte body)
V	20240417195529.899	Progress	UPLOAD 0%
D	20240417195529.900	OkHttp	Content-Type: application/octet-stream
D	20240417195529.900	OkHttp	Content-Length: 0
D	20240417195529.900	OkHttp	--> END PUT
V	20240417195529.901	Progress	org.cryptomator.domain.usecases.cloud.UploadState@4d0b239: 0%
D	20240417195529.904	OkHttp	<-- HTTP FAILED: java.net.ProtocolException: expected 0 bytes but received 8192
V	20240417195529.915	Progress	UPLOAD 0%
D	20240417195530.341	UploadFilesUseCase	failed 6d3108fc
D	20240417195530.483	ExceptionHandler	Unexpected error
org.cryptomator.domain.exception.FatalBackendException: java.net.ProtocolException: expected 0 bytes but received 8192
	at org.cryptomator.data.cloud.webdav.network.WebDavClient.writeFile(WebDavClient.kt:170)
	at org.cryptomator.data.cloud.webdav.network.ConnectionHandlerHandlerImpl.writeFile(ConnectionHandlerHandlerImpl.kt:31)
	at org.cryptomator.data.cloud.webdav.WebDavImpl.write(WebDavImpl.kt:136)
	at org.cryptomator.data.cloud.webdav.WebDavCloudContentRepository$Intercepted.write(WebDavCloudContentRepository.kt:165)
	at org.cryptomator.data.cloud.webdav.WebDavCloudContentRepository$Intercepted.write(WebDavCloudContentRepository.kt:95)
	at org.cryptomator.data.cloud.InterceptingCloudContentRepository.write(InterceptingCloudContentRepository.kt:155)
	at org.cryptomator.data.repository.DispatchingCloudContentRepository.write(DispatchingCloudContentRepository.kt:149)
	at org.cryptomator.data.cloud.crypto.CryptoImplDecorator.writeFromTmpFile(CryptoImplDecorator.kt:262)
	at org.cryptomator.data.cloud.crypto.CryptoImplDecorator.writeShortNameFile(CryptoImplDecorator.kt:453)
	at org.cryptomator.data.cloud.crypto.CryptoImplVaultFormat7.write(CryptoImplVaultFormat7.kt:460)
	at org.cryptomator.data.cloud.crypto.CryptoCloudContentRepository.write(CryptoCloudContentRepository.kt:90)
	at org.cryptomator.data.cloud.crypto.CryptoCloudContentRepository.write(CryptoCloudContentRepository.kt:21)
	at org.cryptomator.data.repository.DispatchingCloudContentRepository.write(DispatchingCloudContentRepository.kt:149)
	at org.cryptomator.domain.usecases.cloud.UploadFiles.writeCloudFile(UploadFiles.java:117)
	at org.cryptomator.domain.usecases.cloud.UploadFiles.upload(UploadFiles.java:94)
	at org.cryptomator.domain.usecases.cloud.UploadFiles.upload(UploadFiles.java:82)
	at org.cryptomator.domain.usecases.cloud.UploadFiles.upload(UploadFiles.java:74)
	at org.cryptomator.domain.usecases.cloud.UploadFiles.execute(UploadFiles.java:61)
	at org.cryptomator.domain.usecases.cloud.UploadFilesUseCase$Launcher$2.subscribe(UploadFilesUseCase.java:119)
	at io.reactivex.internal.operators.flowable.FlowableFromPublisher.subscribeActual(FlowableFromPublisher.java:29)
	at io.reactivex.Flowable.subscribe(Flowable.java:14935)
	at io.reactivex.Flowable.subscribe(Flowable.java:14882)
	at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
	at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker$BooleanRunnable.run(ExecutorScheduler.java:288)
	at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker.run(ExecutorScheduler.java:253)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
	at java.lang.Thread.run(Thread.java:1012)
Caused by: java.net.ProtocolException: expected 0 bytes but received 8192
	at okhttp3.internal.connection.Exchange$RequestBodySink.write(Exchange.kt:214)
	at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.kt:255)
	at okio.RealBufferedSink.writeAll(RealBufferedSink.kt:194)
	at org.cryptomator.data.cloud.webdav.network.InputStreamSourceBasedRequestBody.writeTo(InputStreamSourceBasedRequestBody.kt:26)
	at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.kt:59)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
	at org.cryptomator.data.cloud.webdav.network.WebDavCompatibleHttpClient$Companion.provideCacheInterceptor$lambda$1(WebDavCompatibleHttpClient.kt:97)
	at org.cryptomator.data.cloud.webdav.network.WebDavCompatibleHttpClient$Companion.$r8$lambda$FEXxZ7SrPDCRzX39O94E81VyuVA(Unknown Source:0)
	at org.cryptomator.data.cloud.webdav.network.WebDavCompatibleHttpClient$Companion$$ExternalSyntheticLambda1.intercept(Unknown Source:0)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
	at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:34)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
	at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
	at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
	at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
	at org.cryptomator.data.cloud.webdav.network.WebDavCompatibleHttpClient$Companion.provideOfflineCacheInterceptor$lambda$0(WebDavCompatibleHttpClient.kt:91)
	at org.cryptomator.data.cloud.webdav.network.WebDavCompatibleHttpClient$Companion.$r8$lambda$mK1oDRmeIibu1Q57fFrYEwIb5dg(Unknown Source:0)
	at org.cryptomator.data.cloud.webdav.network.WebDavCompatibleHttpClient$Companion$$ExternalSyntheticLambda0.intercept(Unknown Source:0)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
	at org.cryptomator.data.cloud.webdav.network.WebDavCompatibleHttpClient$UserAgentInterceptor.intercept(WebDavCompatibleHttpClient.kt:153)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
	at com.burgstaller.okhttp.AuthenticationCacheInterceptor.intercept(AuthenticationCacheInterceptor.java:49)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
	at org.cryptomator.data.cloud.okhttplogging.HttpLoggingInterceptor.getResponseLoggingExceptions(HttpLoggingInterceptor.kt:51)
	at org.cryptomator.data.cloud.okhttplogging.HttpLoggingInterceptor.getAndLogResponse(HttpLoggingInterceptor.kt:42)
	at org.cryptomator.data.cloud.okhttplogging.HttpLoggingInterceptor.proceedWithLogging(HttpLoggingInterceptor.kt:28)
	at org.cryptomator.data.cloud.okhttplogging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:18)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
	at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
	at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154)
	at org.cryptomator.data.cloud.webdav.network.WebDavRedirectHandler.executeFollowingRedirects(WebDavRedirectHandler.kt:21)
	at org.cryptomator.data.cloud.webdav.network.WebDavCompatibleHttpClient.execute(WebDavCompatibleHttpClient.kt:44)
	at org.cryptomator.data.cloud.webdav.network.WebDavCompatibleHttpClient.execute(WebDavCompatibleHttpClient.kt:39)
	at org.cryptomator.data.cloud.webdav.network.WebDavClient.writeFile(WebDavClient.kt:158)
	... 27 more

ErrorCode: 611A:JB59

Anything else?

is the problem. inputStream.available() returns an integer, if the uploaded file is bigger than 2048 MB it overflows and returns 0 which means we set the Content-Length: 0 but still try to upload the file which leads to the protocol exception.

The fix is to change this line to something like return if (inputStream.available() == 0) -1 else inputStream.available().toLong(), Content-Length: -1 means the length is unknown to the client, see https://github.com/square/okhttp/blob/577d621585f7525d3e98a9161bc26d2965686538/okhttp/src/main/kotlin/okhttp3/RequestBody.kt#L39-L44

@SailReal SailReal added type:bug Something isn't working storage:webdav labels Apr 18, 2024
@SailReal SailReal added this to the 1.11.0 milestone Apr 18, 2024
@SailReal SailReal modified the milestones: 1.11.0, 1.10.1 Apr 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
storage:webdav type:bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant