Flutter Chopper library cache http response - flutter

in my mobile application i'm using Chopper http library and i would like to cache http response with this library, my server return this headers with responses:
<-- 200 http://www.www.www/api/v1/dashboard/allData
content-type: application/json
cache-control: max-age=600, private
transfer-encoding: chunked
date: Mon, 07 Sep 2020 05:47:00 GMT
server: Apache
i added this interceptor to chopper interceptors:
final client = ChopperClient(
client: http.IOClient(
HttpClient()..connectionTimeout = const Duration(seconds: 60),
),
baseUrl: webUri,
services: [
_$WebApi(),
],
converter: const JsonConverter(),
interceptors: [
const HeadersInterceptor({'Content-Type': 'application/json','Cache-Control':'private, max-age=600'}),
HttpLoggingInterceptor(),
]);
now i expect cache work fine for my application, this solution is correct?

Related

REST API call is unauthorized

I am trying to make a REST API call from my .Net MAUI mobile app.
First I log in, and get a JwtSecurityToken:
JwtSecurityToken JwtToken = new JwtSecurityToken(authenticationResult.IdToken);
Then I try to use it to make a REST API call:
HttpClient client = new ();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", JwtToken.RawData);
HttpResponseMessage response = await client.GetAsync(url).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
This gives me an exception
Response status code does not indicate success: 401 (Unauthorized).
What is wrong or missing here?
ADDED:
Here is the respose:
{StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
client-request-id: 162ea393-a9b2-4e6b-9786-d6e18d18afb1
Date: Sun, 25 Dec 2022 20:42:26 GMT
request-id: 162ea393-a9b2-4e6b-9786-d6e18d18afb1
Strict-Transport-Security: max-age=31536000
Transfer-Encoding: chunked
Vary: Accept-Encoding
WWW-Authenticate: Bearer realm="", authorization_uri="https://login.microsoftonline.com/common/oauth2/authorize", client_id="00000003-0000-0000-c000-000000000000"
X-Android-Received-Millis: 1672000947348
X-Android-Response-Source: NETWORK 401
X-Android-Selected-Protocol: http/1.1
X-Android-Sent-Millis: 1672000947271
x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"North Central US","Slice":"E","Ring":"3","ScaleUnit":"005","RoleInstance":"CH01EPF000051D6"}}
Content-Type: application/json
}, Trailing Headers:
{
}}
If you are developing your own API, you can then set this flag to true:
.AddJwtBearer(options =>
{
options.IncludeErrorDetails = true;
...
Then you will see a reason in the response why it failed:
HTTP/1.1 401 Unauthorized
Date: Sun, 02 Aug 2020 11:19:06 GMT
WWW-Authenticate: Bearer error="invalid_token", error_description="The signature is invalid"

API Gate away Is Blocked even when CORS is enabled

I'm trying to make an api to upload images to cloudinary like this
fd.append('photos', file);
fd.append('upload_preset',
CLOUDINARY_UPLOAD_PRESET);
axios({
url: CLOUDINARY_API,
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
"Access-Control-Allow-Origin": "*",
'Access-Control-Allow-Headers': 'Origin',
'Access-Control-Allow-Credentials': true
},
data: fd
}).then(function(res) {
console.log(res);
}).catch(function(err) {
console.error(err);
})
})
but i recieve this error from the browser
Access to XMLHttpRequest at 'https://api.cloudinary.com/v1_1/******/mh/upload' from origin 'http://127.0.0.1:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.Blockquote
You will need to remove the three "Access-Control-Allow-*" headers from the request you are sending.
The headers Cloudinary allows for cross-origin requests don't include those headers which you are sending and therefore the browser throws this error.
Below are the headers that are allowed for cross-origin uploads (under Access-Control-Allow-Headers):
curl -sD - -X OPTIONS https://api.cloudinary.com/v1_1/demo/image/upload
HTTP/1.1 200 OK
Access-Control-Allow-Headers: Cache-Control, Content-Disposition, Content-MD5, Content-Range, Content-Type, DPR, Viewport-Width, X-CSRF-Token, X-Prototype-Version, X-Requested-With, X-Unique-Upload-Id
Access-Control-Allow-Methods: PUT, POST, GET, OPTIONS
Access-Control-Max-Age: 1728000
Cache-Control: no-cache
Content-Type: text/plain; charset=utf-8
Date: Sat, 19 Dec 2020 09:49:48 GMT
Server: cloudinary
Status: 200 OK
Vary: Accept-Encoding
X-Request-Id: d1af2a2f8a986d9ebbd1f14399dd409d
X-UA-Compatible: IE=Edge,chrome=1
X-XSS-Protection: 1; mode=block
Content-Length: 0
Connection: keep-alive
EDIT: In addition, Cloudinary API doesn't have a parameter called "photos". The file to upload is sent in the "file" parameter.
Therefore, you would need to replace fd.append('photos', file); with fd.append('file', file);.

(questions about POST requests) Is there a way to send a POST request and then get back the retrieved resource in the event of a 302 externally?

This is a bit confusing but I'm going to try my best to explain it properly, I'll really appreciate an answer to this.
Suppose I've got the endpoint "example.com/login" that displays an HTML page with a login form that upon submitting sends a POST request to "example.com/login" (yes itself) with the credentials (shown below) and then upon successful authentication displays another HTML page (example.com/user/records) that shows your details (for e.g your data records and stuff).
What I plan on doing is accessing the HTML page that shows that data by sending a POST request externally using Javascript with the credentials and then somehow just receiving the HTML for the data records page as a string response as we'd normally get through a GET request (is this even possible?).
upon sending said request it shows this in the network tab:
(Remote Address has been modified to replace all numbers with 0)
Request URL: https://example.com/login
Request Method: POST
Status Code: 302
Remote Address: 000.000.000.000:000
Referrer Policy: strict-origin-when-cross-origin
Response Headers:
cache-control: no-store, no-cache, must-revalidate
content-type: text/html; charset=UTF-8
date: Mon, 30 Nov 2020 22:43:08 GMT
expires: Thu, 19 Nov 1981 08:52:00 GMT
location: https://example.com/user/records
pragma: no-cache
server: Apache
Request Headers:
:authority: example.com
:method: POST
:path: /login
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
accept-encoding: gzip, deflate, br
accept-language: en
cache-control: max-age=0
content-length: 47
content-type: application/x-www-form-urlencoded
cookie: roundcube_cookies=enabled; timezone=Asia/Baghdad; resetpasscookie=kUcAf8R5ue5VsOVM; webmailsession=%3af5nnuvNuUHvJaAWn%2c73236ca3fe2776acd45d97c7fffdfd79; whostmgrsession=%3alTiPVRgz7acX0SQG%2c97f0382efe30423a72f3caefec64192f; cpsession=%3arm4IkcjwHaihjbFR%2c859b30622f8d57aebed715dea4d2791e; ci_session=2vofur1iqi6sgrurb1s2dtb5f0tfggi8
origin: https://example.com
referer: https://example.com/login
sec-fetch-dest: document
sec-fetch-mode: navigate
sec-fetch-site: same-origin
sec-fetch-user: ?1
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36
Form Data:
ci_csrf_token:
username: abc
password: 123
first concern: Where on Earth did those cookies even come from?? (if they're set by the server then is there a way I can still do what I plan on doing?)
I just copied that request from the options directly as a Node fetch request and ran it in Visual Studio Code externally (not connected to that website in any way right now) and got this:
(an account with details username: abc, password: 123 exists suppose - I've just replaced the credentials)
Response {
size: 0,
timeout: 0,
[Symbol(Body internals)]: {
body: PassThrough {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 5,
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: true,
[Symbol(kCapture)]: false,
[Symbol(kTransformState)]: [Object]
},
disturbed: false,
error: null
},
[Symbol(Response internals)]: {
url: 'https://example.com/login',
status: 200,
statusText: 'OK',
headers: Headers { [Symbol(map)]: [Object: null prototype] },
counter: 2
}
} Headers {
[Symbol(map)]: [Object: null prototype] {
date: [ 'Mon, 30 Nov 2020 22:54:12 GMT' ],
server: [ 'Apache' ],
expires: [ 'Thu, 19 Nov 1981 08:52:00 GMT' ],
'cache-control': [ 'no-store, no-cache, must-revalidate' ],
pragma: [ 'no-cache' ],
'set-cookie': [
'ci_session=06ujfc27fpp73a01nia1dp3pehsskep5; expires=Tue, 01-Dec-2020 00:54:12 GMT; Max-Age=7200; path=/; HttpOnly'
],
upgrade: [ 'h2,h2c' ],
connection: [ 'Upgrade, close' ],
'transfer-encoding': [ 'chunked' ],
'content-type': [ 'text/html; charset=UTF-8' ]
}
}
2nd concern) Why was I greeted with code 200 here, and 302 on the browser?
Anyways, I planned on authenticating myself by copying the post request that would've been sent through the login form and supplying various correct credentials so I could access their details using Javascript externally, and then manipulate them.
If this can't work then is there any other way to do this? Or if it can, then how?
I realized it could be solved in some cases by providing {"redirect": "follow"} to the options when using fetch.

What is fetch's redirect and authorization headers expected behavior? (Safari has different behavior from other Mac browsers)

In short, when using an authorization header with the fetch api and a redirect is followed Chrome, FireFox, and Opera (on a Mac) include the authorization header in the second request. However, Safari (12.0.1) does not. From the fetch api spec and issue #553 my understanding is that the header should be included. Is this a correct understanding of how fetch is supposed to work?
Here's the simplified code I'm using with a workaround for Safari but I'd like to know if there's something I'm doing wrong that's causing the behavior with Safari or if there is a better workaround.
export async function loadData(token) {
const opts = {headers: {Authorization: `Bearer ${token}`}, credentials: 'include', redirect: 'follow'};
let response = await fetch('/api/data', opts);
// Work around for Safari not including headers in redirected request
if (response.status === 401 && response.redirected) {
response = await fetch(response.url, opts);
}
if (response.ok) {
return response.json();
}
return null;
}
Quick edit some additional info about the redirect. The redirected location is to the same origin and is a 302:
content-length: 118
content-type: text/plain; charset=utf-8
date: Mon, 26 Nov 2018 20:12:18 GMT
location: /api/data/current-version
server: nginx
status: 302
strict-transport-security: max-age=15768000
vary: Accept

While trying to access RedHat BRMS kie server, i am not able to use POST/PUT methods through rest client

Trying to access POST data through rest client, getting 405.
The response headers states Allow: GET, OPTIONS, HEAD.
So how can I make my rest container accept POST/PUT methods?
EndPoint http://localhost:8080/kie-server/services/rest/server Request Headers used -
Content-Type: application/json
authorization: Basic !#$#%&$$(((
Accept: application/json
X-KIE-ContentType: JSON RESPONSE HEADERS
Server: Apache-Coyote/1.1
Allow: GET, OPTIONS, HEAD
Content-Type: text/html;charset=utf-8
Content-Length: 1088
Date: Thu, 01 Sep 2016 08:43:33 GMT
Tried using Advanced rest client,curl and java code but Same results :(
Referred - https://access.redhat.com/documentation/en-US/Red_Hat_JBoss_BRMS/6.3/html/Getting_Started_Guide/chap-Hello_World_rule_example.html
I think you have to change the Endpoint (URL). I would suggest
http://localhost:8080/kie-server/services/rest/server/containers/instances/("nameOfYourDeployment")
Or try without instances.
In Rest Client provide the following set of values:
URL:
http://localhost:8080/kie-server/services/rest/server/containers/instances/<name-of-your-container>
HEADER:
Accept: application/json
Content-Type: application/json
select method type POST and your JSON request payload
When you hit the API it will ask you for the username and password provide the credentials.
fou can send
payload
as:
{
"commands": [
{
"insert": {
"out-identifier": "Input",
"return-object": "true",
"object": {
"<complete-package-name>.<class-name>": {
"variable-1" : "value-1",
"variable-2" : "value-2"
}
}
}
},
{
"fire-all-rules": {
"outIdentifier": "output"
}
}
]
}