Why am I getting 403 Forbidden Request Error? - android

I'm trying to download a pdf file using Dart programming language and Flutter framework.
If I send a GET request with my Browser or Postman everything works fine. However when I try using:
await http.readBytes("https://www.nato.int/structur/recruit/documents/Close%20Protection%20Agent,%20Close%20Protection%20Unit.pdf")
I get Request to ... failed with status 403: Forbidden.
I'm using this import
import 'package:http/http.dart' as http;
Why requesting from browser works and dynamically I get this error. If my url is bad encoded how should I encode it ? Isn't it already properly encoded ?
Thanks in advance!

The issue seems to be caused by using http.readBytes(). What you can do here is wait for a response from http.post() and write the response to the device's storage.
final response = await http.post(uri);
Directory tempDir = await getTemporaryDirectory();
String tempPath = tempDir.path;
File file = File('$tempPath/yourFile.pdf');
await file.writeAsBytes(response.bodyBytes);

Related

my flutter app is unable to get or post https request

I am building a flutter app, everything is alright if I use http requests but when it come to https, I am unable to get or post https request, debugger gives no error, even it does not print response of the request. I tried, flutter clean and rebuild app so many times even clearing my mobile device cache etc. it does not work
I am working and testing on android device
Code
import 'dart:convert';
import 'package:http/http.dart' as http;
var url = Uri.parse('https://my.api-end-point.com:port/auth');
Map requestHeaders = <String, String>{
'Content-type': 'application/json',
'Accept': 'application/json'
};
Map body = <String, String>{'email': email, "password": password};
var response = await http.post(url, headers: requestHeaders, body: json.encode(body));
var res = jsonDecode(response.body);
print(res);
** Test **
working also on postman
any help will be appreciated!
Have you tried hitting the same api using postman?
may be there is an issue with the api itself since the console returns no errors

How do I get http content from a https website?

I get "Http failure response for https://www.google.com: 0 Unknown Error" when I request from Secured url.
I am trying to test my ionic/angular mobile app. When I tried with http requests I had problem with Android 9, but with Android 7 was working fine. Anyhow I need to set my backend to public https server. So now I'm testing with https request and none of 7 and 9 Android versions works.
I am using Angular 7 ,
"#ionic/angular": "^4.6.1",
"#ionic-native/core": "^5.0.0",
"rxjs": "~6.5.1"
I made these small functions in order to make my problem simpler.
inside my html file i have this code:
myFile.html
<ion-button
(click)="onStartTest()"
>Click me</ion-button>
<p id="testme"></p>
myFile.page.ts
onStartTest() {
this.taskService.onTest().subscribe(result => {
document.getElementById('testme').innerText = 'result ' + result;
console.log(result);
}, error => {
document.getElementById('testme').innerText = error.message;
console.log('Problem ', error.message);
});
}
myTask.service.ts
onTest() {
return this.http.get('https://www.google.com').pipe(
catchError(err => {
return throwError(err);
})
);
}
At first I tried my server's URL but I changed it to "https://www.google.com" just to verify that the backend is correct.
Also I have an interceptors.ts file that I am using it for authentication, but I am not logged in when I execute the onStartTest() function, but im gonna share it anw.
interceptors.ts
import {Injectable} from '#angular/core';
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '#angular/common/http';
import {Observable} from 'rxjs';
#Injectable()
export class TokenInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = localStorage.getItem('auth_token');
let newHeaders = req.headers;
if (token) {
console.log(token);
newHeaders = newHeaders.set('Authorization', 'Token ' + token);
const modified = req.clone({
headers: newHeaders
});
return next.handle(modified);
} else {
newHeaders = newHeaders.set('Content-Type', 'application/json');
const modified = req.clone({
headers: newHeaders
});
return next.handle(modified);
}
}
}
I think these are the necessary files to share for this problem.
I also tested the url of google with Postman just to be sure that I should get a status 200
I am also aware that there is an "add_header" directive (nginx) that adds 'Allow-access-control-origin' when the response code is 20x or 30x. According to my screenshot with Postman, google is responding with 200 status, but my app still gets status 0 error.
Ignore the first Error. It's a function I use with http when the app begins. Right now im testing https.
I tried superficially to use ionic-native library HTTP but my app totally crashed.
I also execute the command ionic serve --ssl but still nothing.
I read somewhere that for secured connection I need a certificate, but I understood that this is a server's work.
I tried to request from Dark Sky from Vanilla JavaScript and it works fine. So there is something wrong with angular/ionic side and not server's.
What am I missing? I really need to fix this problem soon!
I want to send a secured request to an https url and get the appropriate response.
Your main problem is that you are trying make an API to an unsecure call (http) location (http://192....../mobile/tasks) from a secure origin (https://localhost:8100).
This is clearly indicated in your error message and this is not allowed, and has been answered before
Your second problem is that, for testing purposes, you are trying to call a 3rd party https ressource from your website. This only works if the 3rd party ressource implement CORS, which is not the case for Google and api.darksky.net. Sending a GET request with Postman is useless, as Postman will not check for CORS headers before displaying the response. If you want to use Postman to check CORS, send an OPTIONS request to these ressources and you'll see that there are no CORS headers
So the answer is in MDN - CORS
For security reasons, browsers restrict cross-origin HTTP requests
initiated from scripts. For example, XMLHttpRequest and the Fetch API
follow the same-origin policy. This means that a web application using
those APIs can only request resources from the same origin the
application was loaded from, unless the response from other origins
includes the right CORS headers.
This means the back-end I was using needed some more configuration since I was using 'same-origin' policy script. I thought we had it because when we tried from the browser's console to fetch the request it was working fine, but on mobile it wasn't. We had a custom CORS configuration but we changed it to the django-cors-headers. Since we switched to django-cors-headers I could get correctly the response from HTTP and HTTPs requests.
The other answer and comments were really useful to focus to the right direction.

Axios post on Android device give me Network Error

I have an axios call to a presigned url in s3 for upload, this work well in IOS but trow "Netowork Error" in android.
The code is pretty simple but without any other information (the response is empty) I do not kwno how to solve this.
axios.post(presignedPostData.url, formData, config)
.then(function (response) {
})
.catch(function (err) { console.log('S3err',err, err.response) })
I use react-native with expo, the axios call work in ios and also in the web version.
UPDATE
The problem seems relative to formdata, if for example I remove the formdata obviously my post not work but the error (missing pre-conditions...) and the status (412) code are ok, but with formdata I've not error description nor status code..
UPDATE 2: the formdata, autogenerated from s3.createPresignedPost (they work in ios and web)
{"_parts":[["Content-Type","video/mp4"],["key","src-058ef4d0-0d49-11ea-8478-3b47e74a5983.mp4"],["acl","public-read"],["bucket","my.bucket"],["X-Amz-Algorithm","AWS4-HMAC-SHA256"],["X-Amz-Credential","mycredentials"],["Policy","mypolicy"],["X-Amz-Signature","mysignature"],["file",{"cancelled":false,"width":1280,"type":"video","uri":"file:///data/user/0/host.exp.exponent/cache/ExperienceData/%myapp%252Fmyapp/ImagePicker/8d68fafa-5c47-4436-9323-dc0d8702dc5d.mp4","rotation":90,"height":720,"duration":1280}]]}
Also tested with fetch (in place of axios), same problem.
UPDATE 3
If I use FyleSystem
`import * as FileSystem from 'expo-file-system';
//mediaArray['file'] = file;
mediaArray['fileALT'] = FileSystem.cacheDirectory+name
I'm able to du the upload with code 204 but the file uploaded isn't right. Maybe there is a permission problem on imagepicker. Still not working the process but with this new informations maybe someone can have an idea.
the problem seem to be solved, I'm looking to upload video, the file picker add "video" as type, this works on IOS and WEB but not in ANDROID, to get work also in android the type had to be more specific, for example "video/mp4" for .mp4 video o "video/mov" for mov video etc.. I hope that this help someone to achieve mutlipart/form-data in android.

react native Fetch Network request failed on android

I'm trying to receive some simple json from mocky.
React native fetch function:
getMemberDomainList = async (name) => {
try {
let response = await fetch('https://5c9cc9ed3be4e30014a7d287.mockapi.io/api/domain', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
});
let responseJson = await response.json();
return responseJson;
} catch (error) {
console.error(error);
}
}
I have tested the address in chrome on windows, it returns the expected mock data. But when the function is called on my android phone I get this error
Error from remote debugger
...\node_modules\react-native\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:2348 TypeError: Network request failed
at XMLHttpRequest.xhr.onerror (...\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:4337)
at XMLHttpRequest.dispatchEvent (...\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:10760)
at XMLHttpRequest.setReadyState (...\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:10511)
at XMLHttpRequest.__didCompleteResponse (...\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:10343)
at ...\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:10449
at RCTDeviceEventEmitter.emit (...\Libraries\Components\DrawerAndroid\DrawerLayoutAndroid.android.js:11)
at MessageQueue.__callFunction (...\Libraries\ART\ReactNativeART.js:362)
at blob:http://localhost:8081/79251787-d190-4650-8040-23d091c08738:2334
at MessageQueue.__guard (...\Libraries\ART\ReactNativeART.js:312)
at MessageQueue.callFunctionReturnFlushedQueue (...\Libraries\ART\ReactNativeART.js:139)
I'm also running a WebView in my app, which is pointing to a web url, it loads perfectly so I am sure that the phone has internet permission and access etc.
In the latest android versions http requests are not allowed by default. Take a look at this post for further information about allowing http request: How to allow all Network connection types HTTP and HTTPS in Android (9) Pie?
Can't get mockapi.io to work. But the error is not persistent when using services such as:
https://jsonplaceholder.typicode.com/todos/1
Might not be an android or react native related problem after all. Also had issues with mockapi.io in postman, though it works fine in chrome.
If you are using emulator then check whether internet is working or not in this emulation using browser. If not check this: Android emulator not able to access the internet
I have also face this problem in emulator but when I generate a release app and install in a real device(andoid 9) then it works fine.
Please check backend response status.
If backend is sending contents using 205 status - 205 RESET CONTENT
Android system recognize it as an error - HTTP 205 had non-zero Content-Length: 25.
You can check the status code on postman.
So, in this case, the error should be fixed on backend.
It should send contents with 200 status code.

Unity Android java.io.FileNotFoundException

I made a game with Unity3D which is working on my own android phone fine, but it seems not working on other phones. I don't have access to those phones, but this is what I was told.
More detail: My game is an android app and needs to send data to a server to be stored. The URL is something like this "https://example.com/register". The server is hosted on the google app engine. When a user attempts to send the data he gets an error back which is something like this "java.io.FileNotFoundException https://example.com/register". I checked the logs in my server, there is no record regarding a request from that user. I read somewhere that it's because of htaccess and WWW class and you can't call an URL with htaccess data in it! But there is no htaccess to that page in my server. The page simply receives the data and store them, no authentication needed.
Would be great if anyone has any other idea why some devices get this error and some don't.
string url = "https://my-app-name.appspot.com/register";
WWWForm form = new WWWForm();
form.AddField("playerEmail", playerEmail);
form.AddField("registrationId", registrationId);
form.AddField("playerName", playerName);
form.AddField("playerPass", playerPass);
WWW www = new WWW(url, form);
yield return www;
the server-side then use those provided data and return a simple string.
<?php
$player_name = $_POST['playerName'];
$player_pass = $_POST['playerPass'];
$player_email = $_POST['playerEmail'];
$gcm_registration_id = $_POST['registrationId'];
//store data in the Datastore.
echo "success";
?>
app.yaml
application: my-app-name
version: 1
runtime: php55
api_version: 1
threadsafe: false
handlers:
- url: /register
script: register.php
I also had this problem. The takeaway I had was
Java.io.filenotfound exception is bogus error. It's not anything to do with file io - it's the request failing at the server.
To find the actual error in unity - look at the www requestHeaders - this will give you back the response headers from the request from the server - mine was a 500, but it could be a 400+ type error (especially if you're using authentication).
You can do this by doing a
foreach(var header in request.responseHeaders)
....
If anyone wants I can post my diagnostic code to help out.

Categories

Resources