Merge branch 'CB-6503'

This commit is contained in:
Ian Clelland 2015-06-08 15:24:03 -04:00
commit de55dc7f84
4 changed files with 73 additions and 34 deletions

View File

@ -57,7 +57,7 @@ Although in the global scope, they are not available until after the `deviceread
# FileTransfer
The `FileTransfer` object provides a way to upload files using an HTTP
multi-part POST request, and to download files as well.
multi-part POST or PUT request, and to download files as well.
## Properties
@ -91,7 +91,8 @@ __Parameters__:
- __mimeType__: The mime type of the data to upload. Defaults to `image/jpeg`. (DOMString)
- __params__: A set of optional key/value pairs to pass in the HTTP request. (Object)
- __chunkedMode__: Whether to upload the data in chunked streaming mode. Defaults to `true`. (Boolean)
- __headers__: A map of header name/header values. Use an array to specify more than one value. (Object)
- __headers__: A map of header name/header values. Use an array to specify more than one value. On iOS, FireOS, and Android, if a header named Content-Type is present, multipart form data will NOT be used. (Object)
- __httpMethod__: The HTTP method to use e.g. POST or PUT. Defaults to `POST`. (DOMString)
- __trustAllHosts__: Optional parameter, defaults to `false`. If set to `true`, it accepts all security certificates. This is useful since Android rejects self-signed security certificates. Not recommended for production use. Supported on Android and iOS. _(boolean)_

View File

@ -315,8 +315,12 @@ public class FileTransfer extends CordovaPlugin {
// Use a post method.
conn.setRequestMethod(httpMethod);
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
// if we specified a Content-Type header, don't do multipart form upload
boolean multipartFormUpload = (headers == null) || !headers.has("Content-Type");
if (multipartFormUpload) {
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
}
// Set the cookies on the response
String cookie = AmazonCookieManager.getInstance().getCookie(target);
if (cookie != null) {
@ -362,7 +366,9 @@ public class FileTransfer extends CordovaPlugin {
int stringLength = beforeDataBytes.length + tailParamsBytes.length;
if (readResult.length >= 0) {
fixedLength = (int)readResult.length + stringLength;
fixedLength = (int)readResult.length;
if (multipartFormUpload)
fixedLength += stringLength;
progress.setLengthComputable(true);
progress.setTotal(fixedLength);
}
@ -393,10 +399,12 @@ public class FileTransfer extends CordovaPlugin {
}
context.currentOutputStream = sendStream;
}
if (multipartFormUpload) {
//We don't want to change encoding, we just want this to write for all Unicode.
sendStream.write(beforeDataBytes);
totalBytes += beforeDataBytes.length;
}
// create a buffer of maximum size
int bytesAvailable = readResult.inputStream.available();
int bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);
@ -425,9 +433,11 @@ public class FileTransfer extends CordovaPlugin {
context.sendPluginResult(progressResult);
}
if (multipartFormUpload) {
// send multipart form data necessary after file data...
sendStream.write(tailParamsBytes);
totalBytes += tailParamsBytes.length;
}
sendStream.flush();
} finally {
safeClose(readResult.inputStream);

View File

@ -341,7 +341,12 @@ public class FileTransfer extends CordovaPlugin {
// Use a post method.
conn.setRequestMethod(httpMethod);
// if we specified a Content-Type header, don't do multipart form upload
boolean multipartFormUpload = (headers == null) || !headers.has("Content-Type");
if (multipartFormUpload) {
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
}
// Set the cookies on the response
String cookie = getCookies(target);
@ -389,7 +394,9 @@ public class FileTransfer extends CordovaPlugin {
int stringLength = beforeDataBytes.length + tailParamsBytes.length;
if (readResult.length >= 0) {
fixedLength = (int)readResult.length + stringLength;
fixedLength = (int)readResult.length;
if (multipartFormUpload)
fixedLength += stringLength;
progress.setLengthComputable(true);
progress.setTotal(fixedLength);
}
@ -420,9 +427,12 @@ public class FileTransfer extends CordovaPlugin {
}
context.connection = conn;
}
if (multipartFormUpload) {
//We don't want to change encoding, we just want this to write for all Unicode.
sendStream.write(beforeDataBytes);
totalBytes += beforeDataBytes.length;
}
// create a buffer of maximum size
int bytesAvailable = readResult.inputStream.available();
@ -452,9 +462,11 @@ public class FileTransfer extends CordovaPlugin {
context.sendPluginResult(progressResult);
}
if (multipartFormUpload) {
// send multipart form data necessary after file data...
sendStream.write(tailParamsBytes);
totalBytes += tailParamsBytes.length;
}
sendStream.flush();
} finally {
safeClose(readResult.inputStream);

View File

@ -183,8 +183,12 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
[req setHTTPShouldHandleCookies:NO];
}
// if we specified a Content-Type header, don't do multipart form upload
BOOL multipartFormUpload = [headers objectForKey:@"Content-Type"] == nil;
if (multipartFormUpload) {
NSString* contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", kFormBoundary];
[req setValue:contentType forHTTPHeaderField:@"Content-Type"];
}
[self applyRequestHeaders:headers toRequest:req];
NSData* formBoundaryData = [[NSString stringWithFormat:@"--%@\r\n", kFormBoundary] dataUsingEncoding:NSUTF8StringEncoding];
@ -220,7 +224,11 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
DLog(@"fileData length: %d", [fileData length]);
NSData* postBodyAfterFile = [[NSString stringWithFormat:@"\r\n--%@--\r\n", kFormBoundary] dataUsingEncoding:NSUTF8StringEncoding];
long long totalPayloadLength = [postBodyBeforeFile length] + [fileData length] + [postBodyAfterFile length];
long long totalPayloadLength = [fileData length];
if (multipartFormUpload) {
totalPayloadLength += [postBodyBeforeFile length] + [postBodyAfterFile length];
}
[req setValue:[[NSNumber numberWithLongLong:totalPayloadLength] stringValue] forHTTPHeaderField:@"Content-Length"];
if (chunkedMode) {
@ -231,7 +239,8 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
[self.commandDelegate runInBackground:^{
if (CFWriteStreamOpen(writeStream)) {
NSData* chunks[] = {postBodyBeforeFile, fileData, postBodyAfterFile};
if (multipartFormUpload) {
NSData* chunks[] = { postBodyBeforeFile, fileData, postBodyAfterFile };
int numChunks = sizeof(chunks) / sizeof(chunks[0]);
for (int i = 0; i < numChunks; ++i) {
@ -240,6 +249,9 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
break;
}
}
} else {
WriteDataToStream(fileData, writeStream);
}
} else {
NSLog(@"FileTransfer: Failed to open writeStream");
}
@ -247,9 +259,13 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
CFRelease(writeStream);
}];
} else {
if (multipartFormUpload) {
[postBodyBeforeFile appendData:fileData];
[postBodyBeforeFile appendData:postBodyAfterFile];
[req setHTTPBody:postBodyBeforeFile];
} else {
[req setHTTPBody:fileData];
}
}
return req;
}