404 not found error using ServiceStack ServerEventsClient with Pipedream SSE API - c#

I'm using Pipedream as a data source which provides event data via an SSE API.
As per the instructions here, I'm using the following code to subscribe to the SSE:
var client = new ServerEventsClient("https://api.pipedream.com/sources/dc_mXugEA/sse")
{
EventStreamRequestFilter = req => req.AddBearerToken("[MYTOKEN]"),
OnMessage = message => Console.WriteLine(message.Json)
}.Start();
However, I get a System.Net.WebException with the message 'The remote server returned an error: (404) Not Found.'
But if I use HttpClient directly, it succeeds:
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "[MYTOKEN]");
using var reader = new StreamReader(await client.GetStreamAsync("https://api.pipedream.com/sources/dc_mXugEA/sse"));
while (!reader.EndOfStream)
{
Console.WriteLine($"Received message: {await reader.ReadLineAsync()}");
}
Of course, I want to use ServerEventsClient instead of HttpClient to avoid the boilerplate looping code. But why is ServerEventsClient not working in this case?

ServiceStack’s Server Events clients only works with ServiceStack’s Server Events feature, I.e. it can’t be used to consume a 3rd Party SSE stream.

Related

Timeout while making POST request with no authentication C#

I want to make a POST request to a rest service. There is no authentication, it has only two customized header. My code is below. I am getting the error :
An exception of type 'System.AggregateException' occurred in mscorlib.dll but was not handled in user code.
"A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond"
May you help ? What is wrong in the code ?
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("id", "8888");
client.DefaultRequestHeaders.Add("type", "CUSTOMER");
Uri uri = new Uri(requestUri);
var ob = new { id= "5", color= "pink" };
var transferJson = JsonConvert.SerializeObject(ob);
var content = new StringContent(transferJson, Encoding.UTF8, "application/json");
HttpResponseMessage responseMessage = client.PostAsync(uri, content).Result;
Your code itself doesn't look faulty. The error message suggests that the request ran into a timout, which means that the HttpClient waits for a set period of time and terminates if the server doesn't respond. Have you tried pinging the server to make sure it's actually up and running?
It that's the case you could try to increase the timeout value of your HttpClient (see here https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.timeout?view=netframework-4.8).
Additionally you could try to send the request with another tool like Postman to see whether the issue lies within your code, your parameters (like timeout), or the server itself.

Read GRPC headers

I'm sending data via GRPC to, let's call it, IntegrationApi, calling a method Foo. I need to read header values from the response (the API I'm communicating with sends rate-limiting headers).
I'm using https://www.nuget.org/packages/Grpc.Core/
var metaData = new Metadata();
metadata.Add(new Metadata.Entry("Authorization", $"Bearer {apiKey}"));
var channel = new Channel("url to endpoint", new SslCredentials());
var client = new IntegrationApi(channel);
var callOptions = new CallOptions()
.WithHeaders(metadata)
.WithDeadline(DateTime.UtcNow.AddSeconds(15))
.WithWaitForReady(false);
var response = client.Foo(req, options);
but the response only gives me the properties based on the Foo.proto file.
How do I do this?
You are using the synchronous version of "Foo" method, and that one uses a simplified version of the API (=only allows access to the response and throws RpcExceptions in case of an error).
If you call the asynchronous version of the same method ("FooAsync"), you'll get back a call object that can access all the call details (such as response headers).
https://github.com/grpc/grpc/blob/044a8e29df4c5c2716c7e8250c6b2585e1c425ff/src/csharp/Grpc.Core.Api/AsyncUnaryCall.cs#L73

SSL TLS communication in c# with self signed certificate not working

I have a .pem certificate file which is used to communicate between two servers. For communication I have written a program in C# like this:
var client = new RestClient("https://aaaaa.com:1111");
client.ClientCertificates = new X509CertificateCollection();
client.ClientCertificates.Add(new X509Certificate(#"C:\Users\aaa\Desktop\bbb.pem"));
var request = new RestRequest("/qqq/www", Method.POST);
request.AddJsonBody(new { create = new { msgBdy="Test" } });
var response = client.Execute(request);
Console.WriteLine(response.StatusCode);
//The underlying connection was closed: An unexpected error occurred on a send.
When I post the request through SoapUI it goes through, but when I try to send it through Postman or the above C# program it doesn't.
Screenshot from wireshark is below:
The change cipher spec event is called for the successful API call but through postman and c# application this event is never called.
I have tried to do this as explained in this article as well https://www.codeproject.com/Articles/326574/An-Introduction-to-Mutual-SSL-Authentication but that also didn't work.
How can I fix this issue.

How do you make gRPC client Timeout in C# if the server is down?

I am writing a connection back to a TensorFlow Serving system with gRPC from a C# platform on MS Windows 10. I have seen many references to Time-out and Dead-line with the C++ API for gRPC, but can't seem to figure out how to for a timeout under C#.
I am simply opening a channel to the server, setting up a client and the calling to the server. I would like this Classify to time-out after 5 seconds or so. Any help or direction would be appreciated.
channel = new Channel(modelServer, ChannelCredentials.Insecure);
var client = MyService.NewClient(channel);
MyResponse classvalue = client.Classify(featureSet);
To set the deadline for a call, you can simply use the following "deadline:"
client.Classify(featureSet, deadline: DateTime.UtcNow.AddSeconds(5));
or
client.Classify(featureSet, new CallOptions(deadline: DateTime.UtcNow.AddSeconds(5)));
Both ways should be easily discoverable by code completion.
GRPC timeout to detect server down scenario needs to be used on the call to connect the channel. I did it like this:
private async void SampleCode()
{
var client = await GetClient();
var data = await client.GetAllTemplatesAsync(request, new
CallOptions().WithDeadline(DateTime.UtcNow.AddSeconds(7)));
}
private async Task<MyGrpcClient> GetClient()
{
var channel = new Channel("somehost",23456, ChannelCredentials.Insecure);
await channel.ConnectAsync(deadline: DateTime.UtcNow.AddSeconds(2));
return new MyGrpcClient(channel);
}
So, if the server is down the call to GetClient() will timeout. Where as if the server is up but response takes too long then the timeout on the client service call will take effect.

C# Windows Store App HTTPClient with Basic Authentication leads to 401 "Unauthorized"

I am trying to send a HTTP GET request to a service secured with BASIC authentication and https. If I use the RESTClient Firefox plugin to do so there is no problem. I am defining the basic-header and sending the GET to the url and I am getting the answer (data in json).
Now I am working on a Windows Store App in C# which is meant to consume the service. I enabled all required capabilities in the manifest and wrote the following method:
private async void HttpRequest()
{
string basic = "Basic ...........";
Uri testuri = new Uri(#"https://...Servlet");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", basic);
Task<HttpResponseMessage> response = client.GetAsync(testuri);
var text = await response;
var message = text.RequestMessage;
}
I tried out many different possibilites like getting the response-string but everything lead to an 401 Status Code answer from the Server.
I looked at many similar problems and my understanding of the communication is the following: Client request -> Server response with 401 -> Client sends Authorization header -> Server response with 200 (OK)
What I don't understand is why I am getting the 401 "Unauthorized" Status Code although I am sending the Authorization header right at the beginning. It would be interesting if someone knows how this is handled in the RESTClient.
The BASIC header is definetly correct I was comparing it with the one in the RESTClient.
It would be great if someone could help me with this.
Thanks in advance and kind regards,
Max
Was having a similar problem, i added a HttpClientHandler to HttpClient.
var httpClientHandler = new HttpClientHandler();
httpClientHandler.Credentials = new System.Net.NetworkCredential("","")
var httpClient = new HttpClient(httpClientHandler);
Credentials should be encoded, before adding to the header. I tested it in WPF app, It works...
string _auth = string.Format("{0}:{1}", "username", "password");
string _enc = Convert.ToBase64String(Encoding.UTF8.GetBytes(_auth));
string _basic = string.Format("{0} {1}", "Basic", _enc);
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization",_basic);

Categories