Vertx HttpClient does not timeout - httpclient

I am posting not the whole code but code snippets which I think matter to my issue.
I have setup HttpClientOptions as follows.
HttpClientOptions clientOptions = new HttpClientOptions()
.setDefaultHost(host)
.setDefaultPort(port)
.setMaxPoolSize(config.getMaxPoolSize())
.setConnectTimeout(config.getTimeout());
HttpClient httpClient = vertx.createHttpClient(clientOptions);
And then I use this client for a post request as follows:
httpClient.post(ePoint, httpClientResponse -> {
httpClientResponse.bodyHandler(body -> {
if (body.length() == 0) {
ctx.fail();
return;
}
String bodyString = body.toString();
int statusCode = httpClientResponse.statusCode();
if (statusCode != HttpStatus.SC_CREATED) {
ctx.fail();
return;
}
logger.info(ctx, "blah blah");
ctx.next();
})
.exceptionHandler(throwable -> {
ctx.fail();
});
But If I do a simulate a timeout at the recipient side exception handler is not called. But I set the time out as follows in the post request exception handler gets called for a time out Exception.
httpClient.post(ePoint, httpClientResponse -> {
httpClientResponse.bodyHandler(body -> {
if (body.length() == 0) {
ctx.fail();
return;
}
String bodyString = body.toString();
int statusCode = httpClientResponse.statusCode();
if (statusCode != HttpStatus.SC_CREATED) {
ctx.fail();
return;
}
logger.info(ctx, "blah blah");
ctx.next();
}).setTimeout(config.getTimeout())
.exceptionHandler(throwable -> {
ctx.fail();
});
Is this a Vertx bug or by design.

Following approach will work. We need to setup the timeout at request level
HttpClientOptions clientOptions = new HttpClientOptions()
.setDefaultHost(host)
.setDefaultPort(port)
.setMaxPoolSize(config.getMaxPoolSize())
.setConnectTimeout(config.getTimeout());
HttpClient httpClient = vertx.createHttpClient(clientOptions);
HttpClientRequest request = httpClient.request(HttpMethod.GET, url, response -> {
//process response
}).exceptionHandler(e -> {
e.printStackTrace();
comp.completeExceptionally(e);
});
request.putHeader("content-type", "application/json")
.setTimeout(timeout).end();

Related

Using socket to cmmunicate node app to c# service

[Sorry for my bad English]
Hi!
I have to communicate between a node.js application [client side] and c# application [server side].
Each side sends pings to the other, on TCP protocol.
I Successed to create both client and server side, but I have to problems:
after the first ping from the client to the server, the client throws an error:
This socket has been ended by the other party
What i'm doing wrong?
The server reads the incomeing pings into a large buffer.
When I decode it to string, I get string with length of 4096.
How I read the excact message length?
This is the server side code: [c#, .NET 6]
using System.Net;
using System.Net.Sockets;
using System.Text;
Console.WriteLine("Start...");
CancellationTokenSource cts = new();
TcpListener listener = new(IPAddress.Any, 11111);
try
{
listener.Start();
Console.WriteLine("Listining...");
var clientCounter = 0;
var ct = cts.Token;
while (!ct.IsCancellationRequested)
{
using TcpClient client = await listener.AcceptTcpClientAsync(ct)
.ConfigureAwait(false);
using NetworkStream stream = client.GetStream();
_ = PrintUploadedData(stream, ct);
_ = PushData(stream, ct);
clientCounter++;
Console.WriteLine("New client ({0}) connected", clientCounter);
}
}
finally
{
cts.Cancel();
listener.Stop();
}
async Task PrintUploadedData(NetworkStream stream, CancellationToken ct)
{
var buf = new byte[4096];
while (!ct.IsCancellationRequested)
{
var timeout = CancellationTokenSource.CreateLinkedTokenSource(
ct,
new CancellationTokenSource(TimeSpan.FromMinutes(3)).Token);
try
{
var amountRead = await stream.ReadAsync(buf, timeout.Token);
if (timeout.IsCancellationRequested)
{
Console.Error.WriteLine("No Message.");
break;
}
if (amountRead == 0) break; //end of stream.
var message = Encoding.UTF8.GetString(buf);
Console.WriteLine(message);
}
catch (OperationCanceledException)
{
Console.Error.WriteLine("Time out");
break;
}
}
}
async Task PushData(NetworkStream stream, CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
var messageToSend = DateTime.Now.TimeOfDay.ToString();
var messageBytes = Encoding.UTF8.GetBytes(messageToSend);
await stream.WriteAsync(messageBytes, ct).ConfigureAwait(false);
await Task.Delay(TimeSpan.FromSeconds(15), ct);
}
}
And the client side code [node.js]:
import { Socket } from 'net';
var client = new Socket();
client.on('connect', () => console.log("CONNECTED"));
client.on('data', data => console.log("data", data.toString()));
client.on('error', err => console.error(err));
client.connect(11111, "127.0.0.1");
printMessages();
async function printMessages() {
for (let i = 0; i < 10; i++) {
client.write('Ping ' + i);
await sleep(4000);
}
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

PayPal authentication problem on azure "live store"

I am getting the following error when trying to use paypal API
HttpStatusCode: Unauthorized; AUTHENTICATION_FAILURE; Authentication failed due to invalid authentication credentials or a missing Authorization header.
But problem is only when i publish my code to Azure Api. Live store works if I run it on visual studio.
public async Task<bool> InvoicingCreate(Models.ShopTransaction t)
{
sentJson = null;
if (_accessToken == null) await GetAccessTokenAsync();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "v2/invoicing/invoices");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken.access_token);
bool addNotes;
if (t.Product.TotalPrice == 0.0) addNotes = false;
else if (t.PaymentMethod == null) addNotes = true;
else if (t.PaymentMethod == "paypal" || t.PaymentMethod == "credit_card") addNotes = false;
else addNotes = true;
string billingEmail;
if (t.Product.IndividualCouponId.HasValue)
{
billingEmail = _configuration["Shop:CouponInvoiceEmail"];
}
else
{
billingEmail = t.BillingAddress.Email;
}
var inv = new Root
{
detail = new Detail
{
.......details the items. ...
},
.......Fill the items. ...
sentJson = JsonConvert.SerializeObject(inv, Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore });
request.Content = new StringContent(JsonConvert.SerializeObject(inv), Encoding.UTF8, "application/json");
HttpResponseMessage response = await _httpClient.SendAsync(request);
string content = await response.Content.ReadAsStringAsync();
if (response.StatusCode != System.Net.HttpStatusCode.Created)
{
Error error = JsonConvert.DeserializeObject<Error>(content);
throw new Exception(CompactError("Invoicing-create", response.StatusCode, error));
}
CreateResponse invoiceCreated = JsonConvert.DeserializeObject<CreateResponse>(content);
t.InvoiceId = invoiceCreated.href.Split('/').Last();
return true;
}
Auth methode
appsettings.json paypalmodel
Invoicing methode
I found the problem.
It's an domain issue. It has send to many request on paypal server. So classic denial of service.

SOAP service exception after second call

I created a SOAP service that fetches some data from a remote server.
After second call I always get an exception:
stackTrace: org.w3c.dom.DOMException: WRONG_DOCUMENT_ERR: A node is used in a different document than the one that created it.
Any ideas what could be wrong?
function getInstance () {
return LocalServiceRegistry.createService('SaveNewCustomerService', new SaveNewCustomerServiceObject());
}
function SaveNewCustomerServiceObject() {};
SaveNewCustomerServiceObject.prototype.initServiceClient = function() {
this.webReference = webreferences.CustomerWS;
return this.webReference.getDefaultService();
}
SaveNewCustomerServiceObject.prototype.createRequest = function(svc, params) {
return params;
}
SaveNewCustomerServiceObject.prototype.execute = function(svc, requestObject) {
var customerRequestObjTest = new webreferences.CustomerWS.SaveNewCustomer();
if (requestObject != null) {
setObj(); //reduced
}
var result;
try{
result = svc.serviceClient.saveNewCustomer(customerRequestObjTest);
var a =result;
}catch(ex){
var e = ex; //
if(e.faultString == "Import error"){
log.info("Import error" + e.faultDetail);
}else{
log.info(e.faultDetail);
}
}
return result;
}
SaveNewCustomerServiceObject.prototype.parseResponse = function(svc, responseObject) {
return responseObject;
}

Using Post Request return a multiple values in Unity

I am new to Unity i have created a Post Request from that i want to return the Authentication-Token Header and authorization header and some required json data here is my code
private IEnumerator BasketId()
{
string url = "http://hololens5.northeurope.cloudapp.azure.com/INTERSHOP/rest/WFS/inSPIRED-inTRONICS-Site/-/baskets/";
using (UnityWebRequest request = UnityWebRequest.Post(url, "Hello"))
{
yield return request.SendWebRequest();
string token = request.GetResponseHeader("Authentication-token");
if (request.isNetworkError || request.isHttpError)
{
Debug.Log(request.error);
}
else
{
string jsonResut = System.Text.Encoding.UTF8.GetString(request.downloadHandler.data);
obj = JsonConvert.DeserializeObject<BasketId>(jsonResut);
Debug.Log(obj.Uri);
Debug.Log("Authentication-Token: " + token);
yield return obj.Title;
yield return token;
}
}
}
so i could i return the values. Please help me.
Because Coroutine is not immediate (blocking) so you won't be able to return the response directly. What you need to do is to have an event or callback that will be called when your request completed.
Here is how you can achieve it by passing the callback as argument:
private IEnumerator GetBasketId(System.Action<string, BasketId> callback)
{
string url = "http://hololens5.northeurope.cloudapp.azure.com/INTERSHOP/rest/WFS/inSPIRED-inTRONICS-Site/-/baskets/";
using (UnityWebRequest request = UnityWebRequest.Post(url, "Hello"))
{
yield return request.SendWebRequest();
if (request.isNetworkError || request.isHttpError)
{
Debug.Log(request.error);
if (callback != null)
{
callback(null, null);
}
// callback?.Invoke(null, null); // for short
}
else
{
if (callback != null)
{
string token = request.GetResponseHeader("Authentication-token");
string jsonResut = System.Text.Encoding.UTF8.GetString(request.downloadHandler.data);
obj = JsonConvert.DeserializeObject<BasketId>(jsonResut);
if (callback != null)
{
callback(token, obj);
}
// callback?.Invoke(token, obj); // for short
}
}
}
}
so when you want to start the request simply call something like:
StartCoroutine(GetBasketId((token, basketId) =>
{
if (string.IsNullOrEmpty(token))
{
// Handle error
}
else
{
// Handle success
Debug.Log("Token: " + token);
Debug.Log(basketId.Title);
}
});

How can I get all post ids for a Facebook page?

I am using https://graph.facebook.com/v2.4/page_id/posts?fields=id to get all post ids from a Facebook page, but I am running into an infinite loop issue with pagination due to paging.next property always returning a url. It looks like the last page points to the first page. How would I know I have reached the end of results.
Here is a code example:
public static Dictionary<string,string> GetPagePostIds(string accessToken, string pageId)
{
Dictionary<string, string> postIds = new Dictionary<string, string>();
StringBuilder sb = new StringBuilder(graphAPIURL);
sb.Append("/").Append(pageId).Append("/posts/?access_token=").Append(accessToken);
sb.Append("&fields=id");
string url = sb.ToString();
int pages = 0;
int rows = 0;
while (url != null)
{
System.Net.WebRequest req = System.Net.WebRequest.Create(url);
System.Net.WebResponse response = req.GetResponse();
string json = null;
using (System.IO.StreamReader sr = new System.IO.StreamReader(response.GetResponseStream()))
{
json = sr.ReadToEnd();
Console.WriteLine(json);
}
if (json != null)
{
pages++;
Dictionary<string, dynamic> data = (Dictionary<string, dynamic>)Newtonsoft.Json.JsonConvert.DeserializeObject(json, typeof(Dictionary<string, dynamic>));
if (data.ContainsKey("data"))
{
Newtonsoft.Json.Linq.JArray a = (Newtonsoft.Json.Linq.JArray)data["data"];
foreach (Newtonsoft.Json.Linq.JObject o in a)
{
rows++;
postIds.Add(o["id"].ToString(), o["id"].ToString());
}
}
if (data.ContainsKey("paging"))
{
try
{
if (data["paging"]["next"] == url)
{
//otherwise we will be stuck in the infinite loop, as next url of the last page is not null
break;
}
//if next link is present, there are more pages available
url = null;
url = data["paging"]["next"];
}
catch (Exception)
{
}
}
}
}
return postIds;
}
You can break the loop, if you reach to the point, where you only receive empty results.
So you just simply extend your while loop with a second condition. Here is some simple pseudocode:
while (url != null && resultsOnPage) {
[...]
if (data.ContainsKey("data") && data['data'].Count > 0 ) {
[...]
} else {
resultsOnPage = false;
}
[...]
}
Just leave the rest as it is.