Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@ android/.gradle/*
android/gradle/*
android/*.iml
android/local.properties
android/.settings
android/.project
2 changes: 2 additions & 0 deletions FS.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ type DownloadResult = {

type UploadFileOptions = {
toUrl: string; // URL to upload file to
binaryStreamOnly?: boolean; // Allow for binary data stream for file to be uploaded without extra headers, Default is 'false'
files: UploadFileItem[]; // An array of objects with the file information to be uploaded.
headers?: Headers; // An object of headers to be passed to the server
fields?: Fields; // An object of fields to be passed to the server
Expand Down Expand Up @@ -565,6 +566,7 @@ var RNFS = {
jobId: jobId,
toUrl: options.toUrl,
files: options.files,
binaryStreamOnly: options.binaryStreamOnly || false,
headers: options.headers || {},
fields: options.fields || {},
method: options.method || 'POST'
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,7 @@ Read more about background downloads in the [Background Downloads Tutorial (iOS)
```
type UploadFileOptions = {
toUrl: string; // URL to upload file to
binaryStreamOnly?: boolean// Allow for binary data stream for file to be uploaded without extra headers, Default is 'false'
files: UploadFileItem[]; // An array of objects with the file information to be uploaded.
headers?: Headers; // An object of headers to be passed to the server
fields?: Fields; // An object of fields to be passed to the server
Expand Down
1 change: 1 addition & 0 deletions RNFSManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,7 @@ + (BOOL)requiresMainQueueSetup
NSNumber* jobId = options[@"jobId"];
params.toUrl = options[@"toUrl"];
params.files = options[@"files"];
params.binaryStreamOnly = options[@"binaryStreamOnly"];
NSDictionary* headers = options[@"headers"];
NSDictionary* fields = options[@"fields"];
NSString* method = options[@"method"];
Expand Down
3 changes: 2 additions & 1 deletion Uploader.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ typedef void (^UploadProgressCallback)(NSNumber*, NSNumber*);
@property (copy) NSDictionary* headers;
@property (copy) NSDictionary* fields;
@property (copy) NSString* method;
@property (copy) UploadCompleteCallback completeCallback; // Upload has finished (data written)
@property (assign) BOOL binaryStreamOnly;
@property (copy) UploadCompleteCallback completeCallback; // Upload has finished (data written)
@property (copy) UploadErrorCallback errorCallback; // Something gone wrong
@property (copy) UploadBeginCallback beginCallback; // Upload has started
@property (copy) UploadProgressCallback progressCallback; // Upload is progressing
Expand Down
38 changes: 22 additions & 16 deletions Uploader.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ - (void)uploadFiles:(RNFSUploadParams*)params
NSURL *url = [NSURL URLWithString:_params.toUrl];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
[req setHTTPMethod:method];
BOOL binaryStreamOnly = _params.binaryStreamOnly;

// set headers
NSString *formBoundaryString = [self generateBoundaryString];
Expand Down Expand Up @@ -56,9 +57,9 @@ - (void)uploadFiles:(RNFSUploadParams*)params
[reqBody appendData:[val dataUsingEncoding:NSUTF8StringEncoding]];
[reqBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
}

NSArray *files = _params.files;
// add files
for (NSDictionary *file in _params.files) {
for (NSDictionary *file in files) {
NSString *name = file[@"name"];
NSString *filename = file[@"filename"];
NSString *filepath = file[@"filepath"];
Expand All @@ -74,24 +75,29 @@ - (void)uploadFiles:(RNFSUploadParams*)params
}

NSData *fileData = [NSData dataWithContentsOfFile:filepath];

[reqBody appendData:formBoundaryData];
[reqBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", name.length ? name : filename, filename] dataUsingEncoding:NSUTF8StringEncoding]];

if (filetype) {
[reqBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", filetype] dataUsingEncoding:NSUTF8StringEncoding]];
} else {
[reqBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", [self mimeTypeForPath:filename]] dataUsingEncoding:NSUTF8StringEncoding]];
if (!binaryStreamOnly) {
[reqBody appendData:formBoundaryData];
[reqBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", name.length ? name : filename, filename] dataUsingEncoding:NSUTF8StringEncoding]];

if (filetype) {
[reqBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", filetype] dataUsingEncoding:NSUTF8StringEncoding]];
} else {
[reqBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", [self mimeTypeForPath:filename]] dataUsingEncoding:NSUTF8StringEncoding]];
}
[reqBody appendData:[[NSString stringWithFormat:@"Content-Length: %ld\r\n\r\n", (long)[fileData length]] dataUsingEncoding:NSUTF8StringEncoding]];
}

[reqBody appendData:[[NSString stringWithFormat:@"Content-Length: %ld\r\n\r\n", (long)[fileData length]] dataUsingEncoding:NSUTF8StringEncoding]];

[reqBody appendData:fileData];
[reqBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
if (!binaryStreamOnly) {
[reqBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
}
}

// add end boundary
NSData* end = [[NSString stringWithFormat:@"--%@--\r\n", formBoundaryString] dataUsingEncoding:NSUTF8StringEncoding];
[reqBody appendData:end];
if (!binaryStreamOnly) {
// add end boundary
NSData* end = [[NSString stringWithFormat:@"--%@--\r\n", formBoundaryString] dataUsingEncoding:NSUTF8StringEncoding];
[reqBody appendData:end];
}

// send request
[req setHTTPBody:reqBody];
Expand Down
6 changes: 4 additions & 2 deletions android/src/main/java/com/rnfs/RNFSManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,7 @@ public void uploadFiles(final ReadableMap options, final Promise promise) {
ReadableMap headers = options.getMap("headers");
ReadableMap fields = options.getMap("fields");
String method = options.getString("method");
boolean binaryStreamOnly = options.getBoolean("binaryStreamOnly");
ArrayList<ReadableMap> fileList = new ArrayList<>();
UploadParams params = new UploadParams();
for(int i =0;i<files.size();i++){
Expand All @@ -792,8 +793,9 @@ public void uploadFiles(final ReadableMap options, final Promise promise) {
params.src = url;
params.files =fileList;
params.headers = headers;
params.method=method;
params.fields=fields;
params.method = method;
params.fields = fields;
params.binaryStreamOnly = binaryStreamOnly;
params.onUploadComplete = new UploadParams.onUploadComplete() {
public void onUploadComplete(UploadResult res) {
if (res.exception == null) {
Expand Down
1 change: 1 addition & 0 deletions android/src/main/java/com/rnfs/UploadParams.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public interface onUploadBegin{
}
public URL src;
public ArrayList<ReadableMap> files;
public boolean binaryStreamOnly;
public String name;
public ReadableMap headers;
public ReadableMap fields;
Expand Down
55 changes: 36 additions & 19 deletions android/src/main/java/com/rnfs/Uploader.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,16 @@ private void upload(UploadParams params, UploadResult result) throws Exception {
BufferedReader responseStreamReader = null;
String name, filename, filetype;
try {
Object[] files = params.files.toArray();
boolean binaryStreamOnly = params.binaryStreamOnly;

connection = (HttpURLConnection) params.src.openConnection();
connection.setDoOutput(true);
ReadableMapKeySetIterator headerIterator = params.headers.keySetIterator();
connection.setRequestMethod(params.method);
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
if (!binaryStreamOnly) {
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
}
while (headerIterator.hasNextKey()) {
String key = headerIterator.nextKey();
String value = params.headers.getString(key);
Expand All @@ -79,7 +84,7 @@ private void upload(UploadParams params, UploadResult result) throws Exception {
metaData += twoHyphens + boundary + crlf + "Content-Disposition: form-data; name=\"" + key + "\"" + crlf + crlf + value +crlf;
}
stringData += metaData;
fileHeader = new String[params.files.toArray().length];
fileHeader = new String[files.length];
for (ReadableMap map : params.files) {
try {
name = map.getString("name");
Expand All @@ -91,34 +96,45 @@ private void upload(UploadParams params, UploadResult result) throws Exception {
filetype = getMimeType(map.getString("filepath"));
}
File file = new File(map.getString("filepath"));
String fileHeaderType = twoHyphens + boundary + crlf +
"Content-Disposition: form-data; name=\"" + name + "\"; filename=\"" + filename + "\"" + crlf +
"Content-Type: " + filetype + crlf;
long fileLength = file.length();
totalFileLength += fileLength ;
if(params.files.toArray().length - 1 == fileCount){
totalFileLength += tail.length();
totalFileLength += fileLength;
if (!binaryStreamOnly) {
String fileHeaderType = twoHyphens + boundary + crlf +
"Content-Disposition: form-data; name=\"" + name + "\"; filename=\"" + filename + "\"" + crlf +
"Content-Type: " + filetype + crlf;
;
if (files.length - 1 == fileCount){
totalFileLength += tail.length();
}

String fileLengthHeader = "Content-length: " + fileLength + crlf;
fileHeader[fileCount] = fileHeaderType + fileLengthHeader + crlf;
stringData += fileHeaderType + fileLengthHeader + crlf;
}
String fileLengthHeader = "Content-length: " + fileLength + crlf;
fileHeader[fileCount] = fileHeaderType + fileLengthHeader + crlf;
stringData += fileHeaderType + fileLengthHeader + crlf;
fileCount++;
}
fileCount = 0;
mParams.onUploadBegin.onUploadBegin();
long requestLength = totalFileLength + stringData.length() + params.files.toArray().length * crlf.length();
connection.setRequestProperty("Content-length", "" +(int) requestLength);
connection.setFixedLengthStreamingMode((int)requestLength);
if (!binaryStreamOnly) {
long requestLength = totalFileLength;
requestLength += stringData.length() + files.length * crlf.length();
connection.setRequestProperty("Content-length", "" +(int) requestLength);
connection.setFixedLengthStreamingMode((int)requestLength);
}
connection.connect();

request = new DataOutputStream(connection.getOutputStream());
request.writeBytes(metaData);
if (!binaryStreamOnly) {
request.writeBytes(metaData);
}

byteSentTotal = 0;
Runtime run = Runtime.getRuntime();

for (ReadableMap map : params.files) {
request.writeBytes(fileHeader[fileCount]);
if (!binaryStreamOnly) {
request.writeBytes(fileHeader[fileCount]);
}
File file = new File(map.getString("filepath"));
int fileLength = (int) file.length();
int bytes_read = 0;
Expand All @@ -131,9 +147,11 @@ private void upload(UploadParams params, UploadResult result) throws Exception {
while ((bytes_read = bufInput.read(buffer)) != -1) {
request.write(buffer, 0, bytes_read);
byteSentTotal += bytes_read;
mParams.onUploadProgress.onUploadProgress((int) totalFileLength - tail.length(), byteSentTotal);
mParams.onUploadProgress.onUploadProgress((int) totalFileLength, byteSentTotal);
}
if (!binaryStreamOnly) {
request.writeBytes(crlf);
}
request.writeBytes(crlf);
fileCount++;
bufInput.close();
}
Expand Down Expand Up @@ -188,5 +206,4 @@ protected String getMimeType(String path) {
protected void stop() {
mAbort.set(true);
}

}
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ type DownloadResult = {

type UploadFileOptions = {
toUrl: string // URL to upload file to
binaryStreamOnly?: boolean // Allow for binary data stream for file to be uploaded without extra headers, Default is 'false'
files: UploadFileItem[] // An array of objects with the file information to be uploaded.
headers?: Headers // An object of headers to be passed to the server
fields?: Fields // An object of fields to be passed to the server
Expand Down