How to handle long time request in Angular 4? - c#

I am having thouble with a request, in Angular 4, that takes really long.
The backend is in .Net Core 2.0 that connects to an Oracle DB. It should wait for a long query to run in the database to get the data and send it to the client. However, it seems that the client is unable to wait until the end of the process (the return of all records), what I get is the error:
Failed to load resource: the server responded with a status of 502
(Bad Gateway)
This error occurs when a CGI application does not return a valid set
of HTTP headers, or when a proxy or gateway was unable to send the
request to a parent gateway. You may need to get a network trace or
contact the proxy server administrator, if it is not a CGI problem.
It is not a Timeout error, as I thought it'd be.
Here is the code of my request:
exportExcel(dadosConsulta: DadosConsultaModel) : Promise<any>{
let url ="/api/Relatorios/exportToExcel";
return this.http
.post(url, JSON.stringify(dadosConsulta),{ headers: this.headers })
.timeout(500000)
.toPromise()
.then(data => data.json())
.catch(this.handleError);
}
How can I prevent this from happening?

I worked with oracle, long time request querys, and observables and didn't have that problem.
Something like this
login(account: string, password: string, user: string): Observable <any> {
let body = new URLSearchParams();
body.set('account', account);
body.set('password', password);
body.set('user', user);
return this.http.post(this.globalVars.apiUrl + 'login', body)
.map((res: any) => {
let result = res.json().data.result;
let data = res.json().data;
this.client.auth = {
authCode: result.authCode,
token: result.token,
};
this.firstLogin = data.firstLogin;
return this.client;
})
.catch((error: any) => {
console.log('error', error._body);
return Observable.throw(error._body);
})
.timeoutWith(25000, Observable.throw(new Error('Connection Error')))
}}

The problem was actually coming from IIS, and to solve this I had to add a web.config to my project (which is not created by default) and modify the 'aspNetCore' tag like this:
<aspNetCore **requestTimeout="00:20:00"** processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
Got it from this post: Timeouts with long running ASP.NET MVC Core Controller HTTPPost Method

Related

StatusCode of: "HttpVersionNotSupported" on a Https Request

I'm getting the following when trying to make a Call to a firebase Database Exclusively on IOS I dont get the error on android builds.
StatusCode HttpVersionNotSupported
or
ResponseData "<html>\r\n<head><title>505 HTTP Version Not Supported</title></head>\r\n<body>\r\n<center><h1>505 HTTP Version Not Supported</h1></center>\r\n<hr><center>nginx</center>\r\n</body>\r\n</html>\r\n"
Heres the Code im running:
return (await firebase
.Child(ChildName)
.OnceAsync<Userlogin>()).Select(item =>
new Userlogin
{
user_login = item.Object.user_login,
passwords = item.Object.passwords
}).ToList();
Here is my Request URL:
public FirebaseClient firebase = new FirebaseClient("https://myappname.firebaseio.com/");
The server is telling me that it does not accept the request because its either coming from Http or the version of http is out of date.
How do I either:
-Update the HTTP
-Force Https
On the IOS side of Xamarin Forms
Stack Trace to help a bit:
StackTrace " at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode () [0x0001b] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs:168 \n at Firebase.Databa at Firebase.Database.Http.HttpClientExtensions.GetObjectCollectionAsync[T] (System.Net.Http.HttpClient client, System.String requestUri, Newtonsoft.Json.JsonSerializerSettings jsonSerializerSettings) [0x00134] in <d27c522a7ecc437a9802ee0b4650ca23>:0 "
I also want to add that my plist.file also has a https as the url request
Edit:
Issue is moved to: How to deserialize firebase fetch
The issue was Http setting in project, the lingering issue is a deserialisation issue. Will be closing this soon.

C# API call from MarketStack and print values - Error 403

I would like to make a successful API call, then print the values in order to see if it works. My main goal is to analyze the data, after I can make a successful API call, and build a systematic strategy for trading.
System.Net.Http.HttpRequestException: "Response status code does not indicate success: 403 (Forbidden)
namespace marketstacktest
{
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Hello World!");
var options = Options.Create(new MarketstackOptions() { ApiToken = "secretTokenHere" });
var marketstackService = new MarketstackService(options, NullLogger<MarketstackService>.Instance);
var appleSymbol = "AAPL";
var fromDate = DateTime.Now.AddDays(-200);
var toDate = DateTime.Now;
//error at the await System.Net.Http.HttpRequestException: "Response status code does not indicate success: 403 (Forbidden)."
List<Marketstack.Entities.Stocks.StockBar> stock = await marketstackService.GetStockEodBars(appleSymbol, fromDate, toDate);
foreach (var stock_i in stock)
{
Console.WriteLine($"close: {stock_i.Close}");
}
}
}
}
In the API manual, which is directly linked from the github, it gives information about all of the error codes. The relevant ones here are these two:
Code
Type
Description
403
https_access_restricted
HTTPS access is not supported on the current subscription plan.
403
function_access_restricted
The given API endpoint is not supported on the current subscription plan.
Their class library on github is just wrapping a json REST api. Every call to the API is just an http request, returning data as json objects. The 403 error indicates that your request was accepted as a valid request, but intentionally rejected by the server for some reason. And according to the docs, the error was because your account is not allowed access to either https or to the type of request.
Their free-tier subscription only includes end-of-day data, which is what you requested, so it wouldn't make sense for that not to be allowed. So, your app is almost certainly making an https call.
I went to the examples at the very beginning of their quick start guide, and chose the end-of-day example to match your app, and clicked on the link. It worked, and gave a bunch of json records. But, the request they made was using 'http' not 'https'.
Changing the requst to 'https' elicited a 403 response with this content (formatted for readability):
{
"error":
{
"code": "https_access_restricted",
"message": "Access Restricted - Your current Subscription Plan does not support HTTPS Encryption."
}
}
At this point we have enough to be almost certain that this is your issue. The final thing is to go look up how to turn https requests off in their class library. To avoid having to go through the code, I checked the help at the bottom of the page one more time, and found this (formatted for readability):
var options = Options.Create(new MarketstackOptions(){
ApiToken = apiKey,
MaxRequestsPerSecond = 3,
Https = true
});
Welp. This should probably be in their first example, since that's what people are most likely to try first, but it's not. So, to stop trying to make http requests, you just need to set the Https option to false in your code. You just need to add that to the options in your code, like so:
var options = Options.Create(new MarketstackOptions(){
ApiToken = "secretTokenHere",
Https = false
});
I will leave the testing to you, but from the browser test, we know that the request should work, unless there's a bug in their library. Given the information that was available, this is almost certainly the issue.

Redirect for non authorized users not working in ajax request

I have a Cookie based authentication in my webapp to which a sub application make some ajax requests to get the data from db.
the issue is that if the user is not authenticated i redirect him to expired.html, in test mode if i just run in browser or postman an api call like example.com/api/test without getting first the authentication cookie i'm correctly redirected to expired.html. the issue comes when i try to call that api via ajax so by making a simple .get request as the following:
function getPlu(codplu, callback){
let api = 'https://www.example.it/api/plu/?codplu=' + codplu
$.get( api, callback );
}
getPlu('COPERTI', callback => {
...
});
i just get the response from api with code 302 and a .get to expired.html with code 304 but the user still is not redirected to expired.html
So as you can see the status code for that api request is 302 and location should be expired.html BUT it's not getting redirected.
Might it be that browser doesn't handle automatically ajax redirects and i need to do it via client-side (redirect if status.code == 302) or i could fix it via server side?
Here is how the authentication makes the redirect
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options => {
options.Cookie.Name = "AUTH_TOKEN";
options.Cookie.MaxAge = TimeSpan.FromMinutes(120);
options.Events = new CookieAuthenticationEvents()
{
OnRedirectToLogin = (context) =>
{
context.HttpContext.Response.Redirect("https://www.example.it/vmenu/expired.html");
return Task.CompletedTask;
}
};
});
Just to make this answer more clear:
jQuery's ajax uses the XMLHttpRequest object and its methods to execute requests. XMLHttpRequest will follow redirects automatically. Since it's XMLHttpRequest who does that, jQuery's ajax function doesn't even know about it. It only receives the final response, which in the OP's case is 200 Ok (or 304 Not Modified as OP posted).
Also, since the request is made by jQuery/XMLHttpRequest, the client view is not changed if a request or a redirect is executed. Everything is only in the browser's "behind execution".
Since all redirects are executed automatically by XMLHttpRequest, and jQuery is not able to tell if a redirect was made, the most reliable way (and that's the most important thing to me) is handle it manually:
1 - On server side, when unauthenticated request, add a custom header to the response, and respond with 200 OK:
OnRedirectToLogin = (context) =>
{
context.Response.StatusCode = (int)System.Net.HttpStatusCode.OK;
context.Response.Headers.Add("X-Unauthenticated-Redirect", "https://www.example.it/vmenu/expired.html");
return Task.CompletedTask;
}
2 - On client side, just check if this custom header exists. If it does, redirect manually using window.location:
var redirectHeader = jqXHR.getResponseHeader('X-Unauthenticated-Redirect');
if (redirectHeader.length > 0) {
window.location = redirectHeader;
}
Just for reference, from XMLHttpRequest docs:
If the origin of the URL conveyed by the Location header is same origin with the XMLHttpRequest origin and the redirect does not violate infinite loop precautions, transparently follow the redirect while observing the same-origin request event rules.

How to correctly set up AspNet Core 2 authentication behind a load balancer?

I've set up AspNet Core 2 authentication successfully, but now would like to get it working behind a load balancer.
Because the load balancer address is different from my app address I'm changing the redirect Uri in my startup.cs ConfigureServices like this...
options.Events.OnRedirectToIdentityProvider = async n =>
{
n.ProtocolMessage.RedirectUri = "https://frontfacingaddress.com";
await Task.FromResult(0);
};
This works fine and I successfully authenticate and the callback from the identity server calls https://frontfacingaddress.com/signin-oidc. That is correctly handled and handling OnTokenResponseReceived shows that I successfully recieve the token.
The problem is: it is then making another call to the identity server but this time to the app's actual (not load balancing) address. When that comes back it gives an error of: AspNetCore.Correlation.OpenIdConnect cookie not found.
So the Fiddler trace looks like this:
302 HTTPS frontfacingaddress.com /account/signin
200 HTTPS identity.serveraddress.com /connect/authorize/callback etc...
302 HTTPS frontfacingaddress.com /signin-oidc
-- this is where I successfully receive the code, but then:
302 HTTPS actualwebaddress.com /account/signin
200 HTTPS identity.serveraddress.com /connect/authorize/callback etc...
400 HTTPS frontfacingaddress.com /signin-oidc
-- this is the 400 cookie not found error
Why, after successfully authenticating, is it then firing again from the actual address and failing?
The solution was to modify the ReturnUri to use the front-facing address when the ticket was received:
options.Events.OnTicketReceived = async context =>
{
var host = context.HttpContext.Request.Host.Host;
var forwardedHost = context.HttpContext.Request.Headers["X-Forwarded-Host"].ToString();
context.ReturnUri = context.ReturnUri.Replace(host, forwardedHost);
await Task.FromResult(0);
};

My ASP.NET Core API not returning all rows

My ASP.NET Core API is only returning the first two rows out of 40.
I have tried
services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
It sent VS code in to an endless loop. Any ideas on where to look to fix this? I am using the browser and postman to consume the api with the same results.
[EnableCors]
[HttpGet]
public ActionResult<IEnumerable<Fuaxclient>> GetClient()
{
return _context.clientList;
}
I am expecting to get proper json code of about 48 rows. Instead I'm getting 2 rows and broken json. I get this error from FireFox Web Console
error: null​
headers: Object { normalizedNames: Map(0), lazyUpdate: null, headers: Map(0) }
​message: "Http failure response for https://fuaxclientapi.azurewebsites.net/api/fuaxclient: 500 Internal Server Error"​
name: "HttpErrorResponse"
​ok: false
​status: 500
​statusText: "Internal Server Error"
​url: "https://fuaxclientapi.azurewebsites.net/api/fuaxclient"
The API is still running if you would like to try the API to see what I'm talking about.
​
Ok after much digging and researching and banging my head on the desk, I have found my issue. I had NULL in my database and the API stopped at the NULL.
status: 500
​statusText: "Internal Server Error"
As the error 500 itself suggests there error is on the server, in this case the url( endpoint api) stated as https://fuaxclientapi.azurewebsites.net/api/fuaxclient has issue.
It returns invalid json as validated here.
The return value need to be fixed in the api.

Categories