File Transfer Plugin Code 3

504 views
Skip to first unread message

Nicholas Ingrassellino

unread,
Jan 16, 2016, 12:00:37 PM1/16/16
to phonegap
I am having an issue with the File Transfer plugin on Android.

On iOS it works fine but on Android I get a code 3 every time. I have both
options.headers = { Connection: "close" };
and
options.chunkedMode = false;
set but it seems to make no difference.

Jesse Monroy

unread,
Jan 17, 2016, 5:27:24 PM1/17/16
to phonegap
@Nicholas,
What are your target platforms?
Android 4,5,6?
iOS 7,8,9?

I assume you are using the same server for both.

Jesse

Nicholas Ingrassellino

unread,
Jan 18, 2016, 10:58:10 AM1/18/16
to phonegap
iOS v7.1+
Android v4.1+

The specific Android version I am testing most on is v5.0.1.

Same server for both.

Kerri Shotts

unread,
Jan 18, 2016, 11:40:49 AM1/18/16
to phonegap
Care to share more code? There's nowhere near enough information here to offer much assistance.

Also, is your connection SSL or not? If SSL, are you using self-signed certificates? If not, what CA are you using?

Also, check your log (adb logcat) -- there may be more useful information being logged to the console.


Nicholas Ingrassellino

unread,
Jan 18, 2016, 1:45:35 PM1/18/16
to phonegap
What other code would you need? That is all the code that relates to the file transfer plugin.

I have tried both with and without SSL (currently working without to simplify matters). It happens either way. The SSL CA is from thawte and is properly setup (a WebSocket connection also goes to the same server).

adb logcat is very verbose. I did a Google search on how to filter by application but nothing seems to work (I either get everything or nothing).

Kerri Shotts

unread,
Jan 18, 2016, 3:19:18 PM1/18/16
to phonegap
Piping the adb logcat output to grep should help:

adb logcat | grep ...

Also -- what plugins (and versions) do you have installed? What does your config.xml file look like?

As to the code -- we only have your code that sets your options. Nothing about calling the plugin, so we have to imagine what that might look like. We can assume it's correct, but who knows -- maybe it's not.

Nicholas Ingrassellino

unread,
Jan 18, 2016, 4:09:35 PM1/18/16
to phonegap
Oh, jeez. I could have sworn I posted the entirety code. My bad.

function send_file() {
var options = new FileUploadOptions();
options.fileName = "attachment";
options.mimeType = mime_type;
options.headers = { Connection: "close" };
options.chunkedMode = false;
var ft = new FileTransfer();
ft.upload(
video_path,
encodeURI(uri),
function(result) {},
function(error) {
setTimeout(
function() {
send_file(video_path);
},
1000
);
},
options
);
};

send_file(video_path);

Got logcat working. There are no messages (error or otherwise) when the code 3 occurs.

My config.xml is:
<?xml version="1.0" encoding="utf-8"?>

<widget id="X.Y.Z" version="1.0" versionCode="3101" xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<name>XYZ</name>
<description>XYZ</description>
<author email="sup...@xyz.com" href="http://www.xyz.com/">XYZ</author>
<preference name="permissions" value="none" />
<preference name="orientation" value="portrait" />
<preference name="target-device" value="universal" />
<preference name="fullscreen" value="false" />
<preference name="webviewbounce" value="false" />
<preference name="prerendered-icon" value="true" />
<preference name="stay-in-webview" value="false" />
<preference name="deployment-target" value="7.1" />
<preference name="ios-statusbarstyle" value="default" />
<preference name="detect-data-types" value="true" />
<preference name="exit-on-suspend" value="false" />
<preference name="show-splash-screen-spinner" value="false" />
<preference name="auto-hide-splash-screen" value="false" />
<preference name="disable-cursor" value="false" />
<preference name="android-minSdkVersion" value="16" />
<preference name="android-installLocation" value="auto" />
<icon src="icon.png" />
<icon gap:density="ldpi" gap:platform="android" src="resource/icon/android/icon-36-ldpi.png" />
<icon gap:density="mdpi" gap:platform="android" src="resource/icon/android/icon-48-mdpi.png" />
<icon gap:density="hdpi" gap:platform="android" src="resource/icon/android/icon-72-hdpi.png" />
<icon gap:density="xhdpi" gap:platform="android" src="resource/icon/android/icon-96-xhdpi.png" />
<icon gap:platform="blackberry" src="resource/icon/blackberry/icon-80.png" />
<icon gap:platform="blackberry" gap:state="hover" src="resource/icon/blackberry/icon-80.png" />
<icon gap:platform="ios" height="57" src="resource/icon/ios/icon-57.png" width="57" />
<icon gap:platform="ios" height="72" src="resource/icon/ios/icon-72.png" width="72" />
<icon gap:platform="ios" height="76" src="resource/icon/ios/icon-76.png" width="76" />
<icon gap:platform="ios" height="120" src="resource/icon/ios/icon-120.png" width="120" />
<icon gap:platform="ios" height="152" src="resource/icon/ios/icon-152.png" width="152" />
<icon gap:platform="ios" height="114" src="resource/icon/ios/icon-57-2x.png" width="114" />
<icon gap:platform="ios" height="144" src="resource/icon/ios/icon-72-2x.png" width="144" />
<icon gap:platform="webos" src="resource/icon/webos/icon-64.png" />
<icon gap:platform="winphone" src="resource/icon/windows-phone/icon-48.png" />
<icon gap:platform="winphone" gap:role="background" src="resource/icon/windows-phone/icon-173.png" />
<gap:splash gap:density="ldpi" gap:platform="android" src="resource/screen/android/screen-ldpi-portrait.png" />
<gap:splash gap:density="mdpi" gap:platform="android" src="resource/screen/android/screen-mdpi-portrait.png" />
<gap:splash gap:density="hdpi" gap:platform="android" src="resource/screen/android/screen-hdpi-portrait.png" />
<gap:splash gap:density="xhdpi" gap:platform="android" src="resource/screen/android/screen-xhdpi-portrait.png" />
<gap:splash gap:platform="blackberry" src="resource/screen/blackberry/screen-225.png" />
<gap:splash gap:platform="ios" height="480" src="resource/screen/ios/screen-iphone-portrait.png" width="320" />
<gap:splash gap:platform="ios" height="960" src="resource/screen/ios/screen-iphone-portrait-2x.png" width="640" />
<gap:splash gap:platform="ios" height="1024" src="resource/screen/ios/screen-ipad-portrait.png" width="768" />
<gap:splash gap:platform="ios" height="768" src="resource/screen/ios/screen-ipad-landscape.png" width="1024" />
<gap:splash gap:platform="ios" height="320" src="resource/screen/ios/screen-iphone-landscape.png" width="480" />
<gap:splash gap:platform="ios" height="640" src="resource/screen/ios/screen-iphone-landscape-2x.png" width="960" />
<gap:splash gap:platform="ios" height="2008" src="resource/screen/ios/screen-ipad-portrait-2x.png" width="1536" />
<gap:splash gap:platform="ios" height="1496" src="resource/screen/ios/screen-ipad-landscape-2x.png" width="2048" />
<gap:splash gap:platform="ios" height="1136" src="resource/screen/ios/screen-iphone-portrait-568h-2x.png" width="640" />
<gap:splash gap:platform="winphone" src="resource/screen/windows-phone/screen-portrait.jpg" />
<gap:config-file platform="ios" parent="CFBundleShortVersionString">
<string>1.0</string>
</gap:config-file>
<gap:config-file platform="ios" parent="UIStatusBarHidden">
<true />
</gap:config-file>
<gap:config-file platform="ios" parent="UIViewControllerBasedStatusBarAppearance">
<false />
</gap:config-file>
<gap:config-file platform="ios" parent="UIBackgroundModes" overwrite="true">
<array>
<string>location</string>
</array>
</gap:config-file>
<gap:plugin name="org.apache.cordova.splashscreen" source="npm"/>
<gap:plugin name="cordova-plugin-camera" source="npm"/>
<gap:plugin name="cordova-plugin-media-capture" source="npm"/>
<gap:plugin name="cordova-plugin-file" source="npm"/>
<gap:plugin name="cordova-plugin-file-transfer" source="npm"/>
<gap:plugin name="cordova-plugin-geolocation" source="npm"/>
<gap:plugin name="cordova-plugin-inappbrowser" source="npm"/>
<gap:plugin name="de.appplant.cordova.plugin.background-mode"/>
<gap:plugin name="com.ququplay.websocket.websocket"/>
<gap:plugin name="cordova-plugin-dialogs" source="npm"/>
<gap:plugin name="cordova-plugin-spinnerdialog" source="npm" />
<gap:plugin name="cordova-plugin-whitelist" source="npm" /> 
<access origin="*" />
<allow-navigation href="*" />
<allow-intent href="*" />
</widget>

Nicholas Ingrassellino

unread,
Jan 20, 2016, 10:40:21 AM1/20/16
to phonegap
I am so stuck on this. I can not seem to find any other information either from the Android device nor online. Everyone else who had a similar problem just did the chunkedMode/connection:close combination and that worked for them. I am really up the creek without a paddle on this one.

Kerri Shotts

unread,
Jan 20, 2016, 3:08:24 PM1/20/16
to phonegap
How are you building the app? It looks to me like you're using PhoneGap Build -- in which case, http://community.phonegap.com/nitobi might be more appropriate.

Other thoughts:

1) Are you building Release or Debug?

2) Have you checked your server logs to see if an error is being generated there? Also, check your network connections on the server to see if your app is making any connection at all.

3) What sizes of files have you tried to upload? Have you tried small files? Does even a very small file fail to upload?

4) What does mime type and uri look like?

5) When grepping in adb logcat, look for "FileTransfer"; the plugin logs errors using that tag. See https://github.com/apache/cordova-plugin-file-transfer/blob/master/src/android/FileTransfer.java#L540 for the logging code when errors occur.



On Wednesday, January 20, 2016 at 9:40:21 AM UTC-6, Nicholas Ingrassellino wrote:
I am so stuck on this. I can not seem to find any other information either from the Android device nor online. Everyone else who had a similar problem just did the chunkedMode/connection:close combination and that worked for them. I am really up the creek without a paddle on this one.
...

Nicholas Ingrassellino

unread,
Jan 20, 2016, 4:31:29 PM1/20/16
to phonegap
  1. Both Debug and Release give me the same error (again, iOS works fine).
  2. My server is not generating any errors. It sees the connect and then sees it close (it does not close it).
  3. I have tried both small files (~1 second clips, ~256KB) and longer files.
  4. The mime type is video/mp4.

adb logcat | grep -i "FileTransfer" gives me
D/FileTransfer(30275): upload file:///storage/emulated/0/DCIM/Camera/20160120_162616.mp4 to http://10.0.0.7:8090/attachment_upload/4d224c3e9edabe85af0941d7319aa85e5d4c3aaf2fbf66351587bd0dd084962dd8558945f718d5adec35ee5ef27ef6d17c00ee4d71f419006ed92b87f4f95128
D
/FileTransfer(30275): fileKey: file
D
/FileTransfer(30275): fileName: attachment
D
/FileTransfer(30275): mimeType: video/mp4
D
/FileTransfer(30275): params: {}
D
/FileTransfer(30275): trustEveryone: false
D
/FileTransfer(30275): chunkedMode: true
D
/FileTransfer(30275): headers: {"Connection":"close"}
D
/FileTransfer(30275): objectId: 1
D
/FileTransfer(30275): httpMethod: POST
W
/PluginManager(30275): THREAD WARNING: exec() call to FileTransfer.upload blocked the main thread for 18ms. Plugin should use CordovaInterface.getThreadPool().
D
/FileTransfer(30275): Content Length: 3494002
D
/FileTransfer(30275): Uploaded 114792 of 3494002 bytes
D
/FileTransfer(30275): Uploaded 229480 of 3494002 bytes
W
/FileTransfer(30275): Error getting HTTP status code from connection.
W
/FileTransfer(30275): java.net.SocketException: sendto failed: EPIPE (Broken pipe)
W
/FileTransfer(30275): at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:546)
W
/FileTransfer(30275): at libcore.io.IoBridge.sendto(IoBridge.java:515)
W
/FileTransfer(30275): at java.net.PlainSocketImpl.write(PlainSocketImpl.java:504)
W
/FileTransfer(30275): at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:37)
W
/FileTransfer(30275): at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:266)
W
/FileTransfer(30275): at com.android.okio.Okio$1.write(Okio.java:73)
W
/FileTransfer(30275): at com.android.okio.RealBufferedSink.flush(RealBufferedSink.java:154)
W
/FileTransfer(30275): at com.android.okhttp.internal.http.HttpConnection.flush(HttpConnection.java:130)
W
/FileTransfer(30275): at com.android.okhttp.internal.http.HttpTransport.flushRequest(HttpTransport.java:80)
W
/FileTransfer(30275): at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:793)
W
/FileTransfer(30275): at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:388)
W
/FileTransfer(30275): at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:332)
W
/FileTransfer(30275): at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:500)
W
/FileTransfer(30275): at org.apache.cordova.filetransfer.FileTransfer.createFileTransferError(FileTransfer.java:645)
W
/FileTransfer(30275): at org.apache.cordova.filetransfer.FileTransfer.access$600(FileTransfer.java:69)
W
/FileTransfer(30275): at org.apache.cordova.filetransfer.FileTransfer$1.run(FileTransfer.java:545)
W
/FileTransfer(30275): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W
/FileTransfer(30275): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W
/FileTransfer(30275): at java.lang.Thread.run(Thread.java:818)
W
/FileTransfer(30275): Caused by: android.system.ErrnoException: sendto failed: EPIPE (Broken pipe)
W
/FileTransfer(30275): at libcore.io.Posix.sendtoBytes(Native Method)
W
/FileTransfer(30275): at libcore.io.Posix.sendto(Posix.java:176)
W
/FileTransfer(30275): at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:278)
W
/FileTransfer(30275): at libcore.io.IoBridge.sendto(IoBridge.java:513)
W
/FileTransfer(30275): ... 17 more
E
/FileTransfer(30275): {"code":3,"source":"file:\/\/\/storage\/emulated\/0\/DCIM\/Camera\/20160120_162616.mp4","target":"http:\/\/10.0.0.7:8090\/attachment_upload\/4d224c3e9edabe85af0941d7319aa85e5d4c3aaf2fbf66351587bd0dd084962dd8558945f718d5adec35ee5ef27ef6d17c00ee4d71f419006ed92b87f4f95128","http_status":0,"exception":"sendto failed: EPIPE (Broken pipe)"}
E
/FileTransfer(30275): java.net.SocketException: sendto failed: EPIPE (Broken pipe)
E
/FileTransfer(30275): at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:546)
E
/FileTransfer(30275): at libcore.io.IoBridge.sendto(IoBridge.java:515)
E
/FileTransfer(30275): at java.net.PlainSocketImpl.write(PlainSocketImpl.java:504)
E
/FileTransfer(30275): at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:37)
E
/FileTransfer(30275): at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:266)
E
/FileTransfer(30275): at com.android.okio.Okio$1.write(Okio.java:73)
E
/FileTransfer(30275): at com.android.okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:116)
E
/FileTransfer(30275): at com.android.okio.RealBufferedSink.write(RealBufferedSink.java:44)
E
/FileTransfer(30275): at com.android.okhttp.internal.http.HttpConnection$FixedLengthSink.write(HttpConnection.java:314)
E
/FileTransfer(30275): at com.android.okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:116)
E
/FileTransfer(30275): at com.android.okio.RealBufferedSink$1.write(RealBufferedSink.java:131)
E
/FileTransfer(30275): at org.apache.cordova.filetransfer.FileTransfer$1.run(FileTransfer.java:471)
E
/FileTransfer(30275): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
E
/FileTransfer(30275): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
E
/FileTransfer(30275): at java.lang.Thread.run(Thread.java:818)
E
/FileTransfer(30275): Caused by: android.system.ErrnoException: sendto failed: EPIPE (Broken pipe)
E
/FileTransfer(30275): at libcore.io.Posix.sendtoBytes(Native Method)
E
/FileTransfer(30275): at libcore.io.Posix.sendto(Posix.java:176)
E
/FileTransfer(30275): at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:278)
E
/FileTransfer(30275): at libcore.io.IoBridge.sendto(IoBridge.java:513)
E
/FileTransfer(30275): ... 13 more
E
/FileTransfer(30275): Failed after uploading 327784 of 3494002 bytes.

Nicholas Ingrassellino

unread,
Jan 20, 2016, 4:33:03 PM1/20/16
to phonegap
My error messages seem to have gotten cut off. Here is a pastebin.

W
/FileTransfer(30275): at java.<span style="co

Nicholas Ingrassellino

unread,
Jan 22, 2016, 3:50:00 PM1/22/16
to phonegap

Kerri Shotts

unread,
Jan 23, 2016, 12:47:02 PM1/23/16
to phonegap
So I see several relevant lines in your log files. I'm going to paste them below, along with inline notes:

D/FileTransfer(30275): Content Length: 3494002
D/FileTransfer(30275): Uploaded 114792 of 3494002 bytes
D/FileTransfer(30275): Uploaded 229480 of 3494002 bytes

So, clearly, we have an established connection and are uploading data. This is good. It means your server isn't unreachable, and it is accepting data from us. BUT:

W/FileTransfer(30275): Error getting HTTP status code from connection.
W/FileTransfer(30275): java.net.SocketException: sendto failed: EPIPE (Broken pipe)

E/FileTransfer(30275): {"code":3,"source":"file:\/\/\/storage\/emulated\/0\/DCIM\/Camera\/20160120_162616.mp4","target":"http:\/\/10.0.0.7:8090\/attachment_upload\/4d224c3e9edabe85af0941d7319aa85e5d4c3aaf2fbf66351587bd0dd084962dd8558945f718d5adec35ee5ef27ef6d17c00ee4d71f419006ed92b87f4f95128","http_status":0,"exception":"sendto failed: EPIPE (Broken pipe)"}
E/FileTransfer(30275): java.net.SocketException: sendto failed: EPIPE (Broken pipe)

For some reason, the server breaks the connection. Once broken, we can't write to the connection anymore, hence broken pipe. It doesn't look like an HTTP error has been returned, either.

E/FileTransfer(30275): Failed after uploading 327784 of 3494002 bytes.

We didn't manage to transfer much data: looks like not quite 10% of the total file size.

Homework:

- Try uploading a file SMALLER than 320KiB. See if that succeeds. If it fails, note how much does get uploaded (is it always 10%?)
- Check your server logs. Clearly we're getting through to the server, but something is breaking after the upload starts. There might be an error in the logs indicating /why/ the server broke the connection.

There is good and bad news here: the good is that we can clearly communicate with the server -- which is often exceedingly difficult to debug when no connections are getting through. The bad is that I'm laying odds on a server configuration being the problem... Which makes it hard for /us/ to help a lot, since we don't know how your server is configured. Some code there might help (are you using Node? PHP? What does your upload script look like? Configuration settings?).

Hope all that helps some.

Reply all
Reply to author
Forward
0 new messages