How to use Sec-Websocket-Extensions in MessageWebsocket upgrade request - c#

I need to use a messagewebsocket, but the documentation says the SetRequestHeader method doesn't support sec-websocket-extensions. The data I need to receive is sent in-whole as a single inbound websocket packet.
The initial http header requires sec-websocket-key and -version values.
How do I get around this?

The initial http header requires sec-websocket-key and -version values.
For connecting to server by WebSocket, the client must send an opening handshake to the server firstly. The Sec-WebSocket-Key header field is used in the WebSocket opening handshake and it is must be included. Without this field, the MessageWebSocket will not connect server successfully. So actually the MessageWebSocket APIs have already setting this field to the header. You don't need to set the request header. You can use Fiddler to grab the get request send by MessageWebSocket, and you will see Set-WebSocket-Key and Set-WebSocket-Version in the header.
As the Sec-WebSocket-Key value of this header field MUST be a nonce consisting of a randomly selected 16-byte and the nonce MUST be selected randomly for each connection, also this header field MUST NOT appear more than once in an HTTP request, so we cannot set this again. But you can set an additionally Set-WebSocket-Version by code as follows although I don't think you need doing this.
messageWebSocket.SetRequestHeader("Sec-WebSocket-Verson", "666");
Details about the WebSocket Protocol please reference RFC6455. And more details about how to use WebSocket in UWP app please reference the official sample. This sample has both server and client side for testing.

Related

what's HttpContext.Response.HasStarted for?

For example, ExceptionHandlerMiddleware Middleware code on Github
uses this as:
if (context.Response.HasStarted ||...)
I don't quite get it, how can the web server starts to send response to clients when the request still in the pipeline assuming the ExceptionHandlerMiddleware is the first middleware in the pipeline? Because the request hasn't got out of ExceptionHandlerMiddleware, so it hasn't arrived to the web server, then how could it be that the web server already starts to send responses to client in this scenario?
Any middleware or handler may choose to call WriteAsync (or other similar methods) on the HttpResponse, possibly multiple times.
It's not necessarily possible for all of those writes to just be stored in local buffers, and indeed may not be desirable to just buffer locally. So, sooner or later, those Write calls are going to result in real data being sent over the network.
And, in this concrete example, a handler may have made multiple calls such as the above before it encounters an error condition that causes control to be returned to the ExceptionHandlerMiddleware.
Your specific ExceptionHandlerMiddleware example uses Microsoft.AspNetCore.Http.HttpResponse.HasStarted:
Gets a value indicating whether response headers have been sent to the client.
https://learn.microsoft.com/en-US/dotnet/api/microsoft.aspnetcore.http.httpresponse.hasstarted?view=aspnetcore-5.0
There is also Microsoft.Net.Http.Server.Response.HasStarted:
Indicates if the response status, reason, and headers are prepared to send and can no longer be modified. This is caused by the first write or flush to the response body.
https://learn.microsoft.com/en-US/dotnet/api/microsoft.net.http.server.response.hasstarted?view=aspnetcore-1.1
Each response consis of two parts: Header and Body
These two being sent together to the client, first the headers than the body. So during development, the only opportunity to set any value on the response object that affects the headers is up to the point at which you start sending the body.
As long as you begin sending the body of the response you can no longer change the headers because they are sent as the first part of the response just before the body begins sending.

How to send a certificate as part of request using api management

[![enter image description here][1]][1]Currently I'm reading a client certificate from the external client and then validating in apim using policies which is done using
<policies>
<inbound>
Now when the request is valid and must attach the servercertificate along with the request and then send it back to the client.
How must this be done? can you please help.
Since you're putting certificate into a header you could simply bin64 encode it. You should be able to do it either by accessing RawData property or calling Export on it.

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.

Rest Sharp - 406 Error - No match for accept header

I'm getting a 406 error when trying to use RestSharp to post a request to a third-party application. I'm new to REST, so I have to admit I didn't even know you could add headers. I tried adding these, but I'm still getting the same issue:
var client = new RestClient(myURL);
RestRequest request = new RestRequest("restAction", Method.POST);
request.AddHeader("Accept", "text/plain");
request.AddHeader("Content-Type", "text/plain");
request.AddParameter("parameter1", param1);
request.AddParameter("parameter2", param2);
var response = client.Execute(request);
From what I've read, this may be dealing with a header named "accept". Is that right?
Any idea what could be going on?
In general in HTTP, when a client makes a request to a server, it tells the server what kinds of formats it's prepared to understand (accept). This list of acceptable formats is what the Accept header is for. If the server can't respond using any of the media types in the Accept header, it will return a 406. Otherwise, it will indicate which media type it chose in the Content-Type header of the response. Putting "*/*" in the Accept header tells the server that the client can handle any response media type.
In my original comment to your question, I said that RestSharp looks like it's including "*" in the Accept header by default, but looking closer I see now that it's actually not. So, if you don't override the Accept header like you've done here, the default header value is "application/json","application/xml","text/json","text/x-json","text/javascript","text/xml", and it appears the server you're talking to doesn't speak any of these media types.
If the server you're working with doesn't speak json or xml, I don't think you can use RestSharp, unless you create your own deserializer. I'm not sure if you can do this from the public API or if you'd have to modify the source yourself and recompile it for you own needs.
Since you're still getting HTTP errors from the server, I would recommend taking RestSharp out of the equation for right now, and just speaking HTTP directly to the server until you actually get a correct response from the server. You can use a tool like Fiddler to make a HTTP requests directly. When you send the request (for now in the debugging stage), send an Accept header of "*/*" to get around the 406. Once you've figured out what media types the server can send back to you, you should change this back to being a media type you know you can read and you know the server can send.
It sounds like the main issue here is really just not knowing the protocol of the server. If there's any documentation on the service you're talking to, I would read that very carefully to figure out what media types it's prepared to respond with and how to craft the URLs that it expects.

Server side redirect truncating request payloads

I'm on IIS 6 and I have an ASP.Net 4.0 site that's a single page to serve as a SOAP reverse proxy. I have to modify the return content in order to delete a trouble node from the response and add a tracking node.
In order to facilitate its function as a reverse proxy for all addresses, I have the 404 on the server set to a custom "URL" of "/default.aspx" (the page for my app)
For requests without a payload, it works perfectly - such as for ?WSDL Urls. It requests the proper URL from the target system, gets the response and sends it back - it's pretty utterly transparent in this regard.
However, when a SOAP request is being made with an input payload, the Request.InputStream in the code is always empty. Empty - with one exception - using SOAPUI, I can override the end point and send the request directly to /default.aspx and it will receive the input payload. Thus, I have determined that the custom 404 handler is - when server-side transferring the request - stripping the payload. I know the payload is being sent - I have even wiresharked it on the server to be sure. But then when I add code to log the contents of Request.InputStream it's blank - even though Request.ContentLength shows the right content length for the original request.
I've also been looking for a good way to use ASP.Net to intercept the requests directly rather than allowing the normal IIS 404 handler to take care of it but even with a wildcard mapping, I can't seem to get the settings right nor am I fully confident that it would help. (But I'm hoping it would?)
Finally, I don't have corporate permission to install MVC framework.
Thus, I need either some configuration for IIS I am missing to make this work properly or some other method of ensuring that I get the request payload to my web page.
Thanks!
What about using an HTTP Handler mapped to all requests?
You'll need to add a wildcard application mapping as detailed here and correctly configure your HTTP Handler.

Categories

Resources