Flutter/Dart: How upload binary file to Dropbox? - flutter

I'm trying to upload a binary file to Dropbox using https://github.com/dart-lang/http. Following https://dropbox.github.io/dropbox-api-v2-explorer/#files_upload, my code is:
import 'package:http/http.dart' as http;
Map<String,String> headers = {
'Authorization': 'Bearer MY_TOKEN',
'Content-type': 'application/octet-stream',
'Dropbox-API-Arg': '{"path": "/file", "mode": "overwrite"}',
};
final resp = await http.post(
Uri.parse("https://content.dropboxapi.com/2/files/upload"),
body: "--data-binary #\'/my/binary/file\'",
headers: headers);
file gets uploaded, but unfortunately this only contains the text --data-binary #'/my/binary/file' (i.e. not the actual file).
Am I missing something/doing something incorrectly?

Sending binary data directly as the body worked:
import 'package:http/http.dart' as http;
final file = File('/my/binary/file');
Uint8List data = await file.readAsBytes();
Map<String,String> headers = {
'Authorization': 'Bearer MY_TOKEN',
'Content-type': 'application/octet-stream',
'Dropbox-API-Arg': '{"path": "/file", "mode": "overwrite"}',
};
final resp = await http.post(
Uri.parse("https://content.dropboxapi.com/2/files/upload"),
body: data,
headers: headers);

Since you pass
body: "--data-binary #\'/my/binary/file\'",
as the body of your POST request, exactly this is the data to get send to the server. The body is raw data, that just gets passed along to the server and in no way interpreted by dart.
Have a look at Dart's MultipartRequest. Or for general information:SO on multipart requests.

Related

DioErrorType.response: Http status error [415] when Sending FormData via Dio Flutter

I am trying to send dio form data with files to an api but this error comes up.
Dio dio = Dio(
BaseOptions(
baseUrl: baseUrl,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer ${APIVariables.token}',
},
),
);
FormData formData = FormData.fromMap({
"id": complaint.id,
"title": complaint.title,
"description": complaint.description,
"complainedPosition": complaint.complainedPosition,
"deptId": complaint.departmentId,
"typeId": complaint.typeId,
"priortyId": complaint.priorityId,
"files": complaint.files
.map((file) async => await MultipartFile.fromFile(file.path,
filename: basename(file.path)))
.toList(),
});
Response response = await dio.post(
'Complaint',
data: formData,
),
how can I send files with options by correct way and show progress that has uploading percentage, and get response after completion?
First import http parser:
import 'package:http_parser/http_parser.dart';
You need add the content type also for your files like this:
"files": complaint.files
.map((file) async => await MultipartFile.fromFile(file.path,
filename: basename(file.path),contentType: MediaType('image', 'jpeg')))
I don't know what is your files type, change MediaType('image', 'jpeg') if your files media type is different

Flutter Boundary Regex not accepted

I have to make a post call to upload a image. Getting an error due to the boundary values in the header. (Regex not matched)
var requestUrl = API_URL;
// INITIALIZE MULTIPART REQUEST
http.MultipartRequest request;
// PREPARE HEADER VALUES
request = new http.MultipartRequest("POST", Uri.parse(requestUrl));
Map<String, String> headers = {
'Content-Type': 'multipart/form-data',
'Accept': 'multipart/form-data',
'Authorization': 'Bearer '+accessToken,};
request.headers.addAll(headers);
// DECLARE FILE NAME WEB
String imageType = "image." + this.xfile!.mimeType.toString().split('/').last;
// ADD TO REQUEST
request.files.add(http.MultipartFile.fromBytes('image', await this.xfile!.readAsBytes(), filename:imageType ));
// SEND REQUEST
http.StreamedResponse responseAttachmentSTR = await request.send();
I deployed the codes to the server. Apparently this causes a 403 Forbidden error, when I try to upload an image.
Through debugging, it was because of the regex in the Header (Boundary):
boundary=dart-http-boundary-poYEiL0Ungmxkla.2lkZeC6Mub.-Fupw5T_MmJpxColFVjXf-qr
What can I do about this?

How to download a .pdf file from an URL with POST Request having a body and headers in Flutter?

I am trying to download a .pdf file from an URL having a POST request with body in Flutter.
I am using Dio plugin for network calls.
Here is what I tried to do so far:
Dio dio = Dio();
late Response response;
Future<APIResponse> downloadFile({token}) async {
await dio
.post('https://www.example.com/sample/download',
data: {
{"month": "January", "year": "2022"}
},
options: Options(
headers: {
'Authorization': 'Bearer $token',
},
))
.then((value) {
if (value.statusCode == 200) {
response = value;
// here I need the file to be downloaded
// specific folder would be /downloads folder in Internal Storage
}
});
return APIResponse.fromJson(response.data);
}
But Dio doesn't have POST method with download option, as far as I have checked.
This is what is given in Dio docs:
For downloading a file:
response = await dio.download('https://www.google.com/', './xx.html');
But here we cannot add request body or headers.
Also I need to download the file to a specific folder in the device such as /downloads folder in internal storage.
When download is successful, we can open the file right from that screen.
How to proceed? I am very new to Flutter.
You can use options parameter. You also can add cookie or other parameters.
response = await dio.download(
'https://www.google.com/', './xx.html',
options: Options(
headers: {'cookie': 'any_cookie'},
method: 'POST',
),
);

Flutter HTTP calls using authorization fails but works in postman

I am using Flutter 1.20.4, http 0.12.2 package and I am having an issue where my HTTP calls are successful in Postman but fail in a flutter. I came across a number of articles talking about issue with lower case HTTP headers and some older servers. I don't have that issue as I have tested postman with lower case. I have checked my bearer token on jwt.io and issuer matches the domain I am using. Any call made from flutter that uses authorization will return as "not authenticated" so it would come up with HTTP 302 (redirect to login by identity provider). Any ideas?
My code looks like this:
import 'package:http/http.dart' as http;
...
var getProfileUrl = _identityApi + '/api/profile/get'; // TODO: CHANGE THIS
var accessToken = await _secureStorage.read(key: 'bearerToken');
var response = await http.get(getProfileUrl, headers: {
HttpHeaders.contentTypeHeader: 'application/json',
HttpHeaders.acceptHeader: 'application/json',
HttpHeaders.authorizationHeader: 'Bearer $accessToken'
});
POSTMAN:
FLUTTER:
try this
import 'package:http/http.dart' as http;
...
Map<String,String> _headers={
'content-type': 'application/json',
'accept: 'application/json',
'authorization': 'Bearer $accessToken'
};
var getProfileUrl = _identityApi + '/api/profile/get'; // TODO: CHANGE THIS
var accessToken = await _secureStorage.read(key: 'bearerToken');
var response = await http.get(getProfileUrl, headers: _headers);

How to send a token in a request in flutter?

I am making a flutter application, and i have written a server in django. When i send a token to my server for authentication then my server sends me an error of undefined token. Without token all requests works fine, but when i add a token then it gives me an error
{detail: Authentication credentials were not provided.}
But When i add token in modheader, my server works fine
Authorization: Token bff0e7675d6d80bd692f1be811da63e4182e4a5f
This is my flutter code
const url = 'MY_API_URL';
var authorization = 'Token bff0e7675d6d80bd692f1be811da63e4182e4a5f';
final response = await http.get(
url,
headers: {
'Content-Type': 'application/json',
'Authorization': authorization,
}
);
final responseData = json.decode(response.body);
print('responseData');
print(responseData);
try this:
Map<String, String> headers = {
HttpHeaders.contentTypeHeader: 'application/json',
HttpHeaders.acceptHeader: 'application/json',
HttpHeaders.authorizationHeader: 'Token bff0e7675d6d80bd692f1be811da63e4182e4a5f'
};
& use them in request
final response = await http.get(
url,
headers: headers,
);
As I don't know to work on your API so I can't tell you the exact answer.
Check that, Is your backend taking authorization by header or body or
I'll suggest you first make authorization by tools like postman then
if that succeeds then try to implement that in your app.