Correct way to invoke protocol buffer serialization with Nancy? - c#

I'm using an embedded Nancy webserver and I've used Nu-Get to install the proper plugins for the built in protocol buffer serialization (Nancy.Serialization.ProtoBuf and protobuf-net).
However, the mere presence of these packages doesn't seem to be enabling protocol buffers for me. I'm sending a request with an Accepts header of application/x-protobuf. Using the Nancy diagnostic page (built-in) I can trace my request and see:
response Headers
status Code
406
log
New Request Started
[DefaultResponseNegotiator] Processing as negotiation
[DefaultResponseNegotiator] Original accept header: application/x-protobuf;q=1
[DefaultResponseNegotiator] Coerced accept header: application/x-protobuf
[DefaultResponseNegotiator] Acceptable media ranges: */*
[DefaultResponseNegotiator] Unable to negotiate response - no headers compatible
So it appears as though it can't handle protocol buffers. When I check the main page of the Diagnostics site:
response Processors
Nancy.Responses.Negotiation.JsonProcessor
Nancy.Responses.Negotiation.ResponseProcessor
Nancy.Responses.Negotiation.ViewProcessor
Nancy.Responses.Negotiation.XmlProcessor
It appears as though only the default response processors are there. Protobuf isn't listed.
Any pointers on how I can get the plugin to register with Nancy?

Related

Stream behaviour when no body in HTTP request

Using Azure Functions .Net 5 and the Microsoft.Azure.Functions.Worker.Http SDK, what is the expected behaviour of HttpRequestData.Body property when the request has no body? Is it null, is it a Stream.Empty, something else?
The documentation is unhelpful, as it simply says: "A Stream containing the HTTP body data."
Azure Functions Core 5 were released this year, there is little information available.
There is information on how to read body requests with ASP Core 3 but this is not .NET 5, and I am not sure Azure Functions are expected to behave in the same way as ASP.
I was so far unable to attach the debugger to the published Function Host, which complicates diagnostics.
what is the expected behaviour of HttpRequestData.Body property when the request has no body?
The raw HTTP request body as a bytestring. This is useful for processing data in different ways like loading the data, parsing etc.
The presence of a message-body in a request is signaled by the inclusion of a Content-Length or Transfer-Encoding header field in the request's message-headers.
If content-length is nothing, then the request read return nothing to read. Sometimes throws errors if the EOF (Function) return type is not valid.
To read http request body from asp.net core 5 using azure functions
Create Asp.Net Core 5 Project and Azure Functions isolated environment
Add each of their references in packages/dependencies.
You need to change the target framework of Microsoft SDK version from 3.1 to 5 because by default it is create in 3.1 in Azure Functions csproj.
And We need to do changes in the local.setting.json file as well as Program.cs file in Core project for reading the Http Request Body. Refer this and this for step by step process!
In HttpRequestBody, Content-length : some numeric value (but not zero) specifies the end of the HttpRequest and its length.
If Content-Length: 0, then HttpRequestData contains empty body like { }.
if neither ("Content-Length" / "Transfer-Encoding: chunked") are present, "the end of the connection" signals the end of the request.
The majority of HTTP queries are bodyless GET requests. To test different hooks that interact with such requests and to adequately stress the proxy code, it is crucial to simulate requests containing bodies. POST or PUT requests are the most common types of HTTP requests with bodies.
For more information on HttpRequestBody - Refer this

C# Non standard header in response causes exception

I have to be able to send a HTTP request for a response like this:
HTTP/1.0 200 OK
/bin/sh: check_updatelock: not found
Cache-Control: no-cache, must-revalidate
Expires: ...
Content-Type: application/json
{"response": "..."}
Now here /bin/sh causes exception: Received an invalid header name: '/bin/sh' (at System.Net.Http.HttpConnection.ParseHeaderNameValue).
I've tried with HttpClient, WebClient, HttpWebRequest, and even with a 3rd party lib named Flurl, but that uses HttpClient under the hood.
The result is always the same expection.
Even in PowerShell, with Invoke-WebRequest, there is an execption: The server committed a protocol violation. Section=ResponseHeader Detail=Header name is invalid
How could I read such a response from a C# .NET Core console app?
(The server is out of my control)
Any idea highly appreciated!
Separator chars, like '/', are not part of the field name in the header. So HttpClient (and other libraries built on top of it) will throw an error.
You can try other third party libraries, which are not based on HttpClient like RestSharp (I'm not sure whether it supports non-standard header, but its not based on HttpClient)

Servce Fabric Reverse Proxy Integration in ASP.NET Core 404 Response

I'm working on an implementation of ICommunicationClient and accompanying stuff for HTTP protocol communication which should be compatible with SF reverse proxy. The most subtle part for me is retry policy. According to Azure docs for 404 errors reverse proxy relies on X-Service-Fabric header to be returned from web service when deciding if it should retry.
ASP.NET Core provides middleware for integration with a reverse proxy which adds X-Service-Fabric header to every 404 response.
Assume we have the scenario when ServicePartitionClient cached the endpoint for a stateless service listening on port 3001. At some point, this service may be moved to another node. On the first node, the Service Fabric runtime allocates a different service with its own endpoints but using the same middleware and listening on the same 3001 port.
When a client tries to call the original service at its old (cached) address it will receive 404 response containing the X-Service-Fabric header. According to reverse proxy policies it shouldn't retry, but for me, it seems like the client will stay connected to the wrong service forever and won't attempt to re-resolve the endpoint.
I can't find any information about this case in the documentation, did I miss something here? Is it safe to rely on this standard middleware and don't do retry attempts on 404 errors with X-Service-Fabric: ResourceNotFound header?
In the described case the communication client will be invalidated by staying connected to the wrong service. It is recommended by Microsoft to use unique URL prefixes for services with dynamically-assigned port to handle those scenarios.
In ASP.NET Core programmers can leverage ServiceFabricMiddleware which checks URL prefixes and returns 410 Gone if they don't match. Then HTTP implementation of ICommunicationClient can retry with re-resolving endpoint only for 410 responses and don't perform any retries on 404 response with X-Service-Fabric: ResourceNotFound header if reverse proxy integration is enabled.
In your given scenario, when your Client encounters a 404, the X-Service-Fabric:ResourceNotFound header isn't the only attribute your code could examine when deciding whether or not to retry some operation.
To simplistically address your concern that your client won't be able to tell the difference between a "friendly" node and a "newly arrived" node, and since you're already working with http headers, you could add a custom HTTP header to outgoing responses to identify that a request comes from your application.
When the client receives a 404, you can simply check for the presence of your custom header to answer the question of whether or not it's a "legit" retry. Of course, adding a custom HTTP header just for the sake of this validation check may be more of a global solution to a local problem. Ed: goes without saying that this should not be used to make security decisions by the application
A more elegant and complex means of accomplishing the same would be to deduce the same result using a different combination of HTTP headers and response attributes (e.g., see if some other headers are expected/unexpected), but this could also be a hyper-local solution to the problem.

HttpClient.SendAsync unsupported media type

As usual, in .NET 4.5, I used a HttpClient to send a get request to restful service (a remote server)
However, this time, it returned error 415 - Unsupported Media Type.
I'm expecting the request header including Content-Type = application/json.
And I cannot find a way to set Content-Type correctly.
Anybody has experience for this case or any suggestion will be appreciated!
The code is as below and the httpResponseMessage.RequestMessage.Headers
Updated 1
As I researched, I cannot add a retricted header for Content-Type. Since this is 4.5 implementation. Is this correct?
Updated 2
I tried to add
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
However it returned Cannot send a content-body with this verb-type
I am guessing that your server is not complaining about the invalid content type you requested but about the content type you sent with that request.
That you get
Cannot send a content-body with this verb-type
seems to hint that your tried to send a GET request. It is rather unusual (allthough technically the HTTP protocol allows this) that servers require a GET request with a body. So my best guess is that there is something wrong with the server.

Webservice Client and Compression

I have Managed to Setup II7 with Gzip Compression .
I can check via web sniffer that my asmx web service encoding is Gzip but how to i enable
gzip Compression on my C# Client , i am using the Web Service is Service reference in my application.
Actually i am trying to send large amount of data , 10k objects of array so Compression with be great effect on bw.
but how do I enable Compression on my C# Client.
i am trying to see that many people sees same problem but there nothing clear answer some says use third party tools or some says about custom headers etc etc .
is not there any proper way , built in to consume Compressed web service
As #Igby Largeman pointed out, you can use your IIS7 to enable the compression on the server, but this is not enough.
The main idea is to set the headers on the client side and server side:
Client:
Accept-Encoding = "gzip, deflate";
You can achieve this by code:
var request = HttpWebRequest.Create("http://foofoo");
request.Headers["Accept"] = "application/json";
request.Headers["Accept-Encoding"] = "gzip, deflate";
or
var request = HttpWebRequest.Create("http://foofoo");
request.AutomaticDecompression = DecompressionMethods.GZip |
DecompressionMethods.Deflate;
If you use some WCF client, and not the HttpWebRequest, you should use custom inspector and dispatcher, like in this article:
So I used a message inspector implementing IClientMessageInspector and IDispatchMessageInspector to automatically set the AcceptEncoding and ContentEncoding http headers.
This was working perfectly but I could not achieve to decompress the response on the server by first detecting the ContentEncoding header thus I used the work around to first try to decompress it and if it fails just try to process the request as normal.
I also did this in the client pipeline and this also works.
Server:
// This is the nearly same thing after all
Content-Encoding = "gzip" OR Content-Encoding = "deflate"
To do this on the Server side, you should enable httpCompression in the IIS.
I think you should check the original article to get this work

Categories

Resources