C# WebAPI - Get full HTTP request [duplicate] - c#

This question already has answers here:
How to extract custom header value in Web API message handler?
(13 answers)
Closed 5 years ago.
In one of my WebAPI Controllers, I'd like to see the original raw HTTP request which was sent by the client (like the stuff you can see on http://web-sniffer.net/):
POST / HTTP/1.1
Host: www.some.host.tld
Connection: keep-alive
Accept-Encoding: gzip[CRLF]
Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7
field1=FIELD1&field2=FIELD2
Content-type: application/x-www-form-urlencoded
[...]
How can I do this? Both Request and RequestContext don't contain this data and I didn't find any other resource to query for this content.
I tried searching for similar questions on SO, but only found questions for raw content or (if full html) for Java.
In the back of my mind I have a small memory regarding this in combination with the FilterConfig.cs, but sadly nothing specific enough. And with luck someone more knowledgable than me even knows a way to get this information directly.
Edit:
It seems, that it is impossible to capture the raw HTTP request directly. After reading the linked answers, it seems that I have to rebuild the request from several fields.
According to the link from Jeff's comment in his answer, I have to rebuild the original request from a bunch of parsed fields:
HttpContext.Current.Request.HttpMethod + .Url + .ServerVariables["SERVER_PROTOCOL"] for the start line.
HttpContext.Current.Request.ServerVariables["ALL_RAW"] for the headers
Request.Content.ReadAsStreamAsync().Result (don't forget to seek to position 0 before reading) for the content

Install and run Telerik Fiddler. This captures the traffic, decodes HTTPS traffic. It's what I use all the time for this purpose.

Related

Seeking source of Http Response Headers in MVC application

I've inherited a .NET C# MVC application. I noticed that different pages interact differently with the server when the user uses the Back and Forward buttons built into the browser. Some pages would hit the server and some would not. I used Postman to hit the various URLs and found that different pages are returning different response headers.
Cache-Control: private
Cache-Control: public, no-store, max-age=0
Pages in the first set are cached in the browser's "private" cache. There is no hit against the server when this page is loaded in the browser via the Back or Forward button.
The second control string is somewhat of a conflict, however the most restrictive directive of no-store overrides. These pages hit the server every time the page is loaded.
I've searched the codebase. I've located related meta tags in various page template markup files but I'm looking specifically for the headers. Moreover, the meta tags are all the same, so that could not account for the different headers in different pages.
IIS is not configured to add this header. Moreover, when I run this application in debug, out of Visual Studio / IIS Express, I see these headers sent back with the response. Different headers for different pages.
I can't find any explicit code which is emitting these headers on the server (I searched for Response.AddHeader and didn't find anything) so I'm thinking that there might be different configurations of the different MVC Templates which is implicitly generating these headers? Does that make sense? (I don't have a lot of experience with MVC.) I'll keep looking, but if you have knowledge of MVC which could point me in the right direction, I'd really appreciate that.
I continued looking into this. As Alexei Levenkov pointed out, Angular is executing client side. Not the right place to be looking.
Here's an image of a Debug session processing the page request. At this point there are exactly two headers in the Response.Headers collection.
After this statement executes, the response received by the browser contains many more headers. The View() method is not my code so I have no ability to trace into it. Clearly though, the View() method reacts to some declarative configuration somewhere which results in different response headers for different templates. As I mentioned before, I'm no Angular.js expert and I'm not much better with MVC. I'm probably missing something very basic.
Within this transaction there is nothing which executes after the return View() statement. Step over that statement, step off the closing method brace and the content returns to the client.
Postman shows 11 response headers, including the one in particular which interests me.
Now here I am stepping into a different request which returns a different Cache-Control header. Again, we see the same two headers in the Response.Headers collection.
Yet, the View method returns 13 response headers and a different Cache-Control header:
Here's a clue: The different pages which return different headers are grouped into different controllers. One controller returns Cache-Control: private, while the other controller returns Cache-Control: public, no-store, max-age=0.
I suppose, ultimately, the question boils down to the following: How are controllers defined in MVC to return specific headers on the response? (Like I said, I'm not an MVC expert so this might be a very long-winded presentation to get to a very basic question. Thanks for your help!)
I believe this is the answer. It's a meta-tag on the Controller. (As a declarative, this would not be seen when stepping through the code. An examination of the source is necessary and of course, it helps to know what you are looking for. Now I know!)
namespace rater8.RMM.Web.Controllers
{
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public class RMMController : Controller
{
...
}
...
}
The other controller did not have any such meta-tag. It appears that not specifying this meta-tag results in Cache-Control: private, which allows browsers to preserve the page in the local cache for Back and Froward navigation without hitting the server.
Specifying the meta-tag as shown in the code example above results in Cache-Control: public, no-store, max-age=0 (That's a strange cache-control value where public is in conflict with no-store but the latter wins out as it is the more restrictive attribute.)

What does a curl_error_56 and a HTTP_error_502 have in common?

I am working on a Chatbot in Slack that sends a POST request to http://localhost:44331/values/api an .NET Core API that i built in C#. In the Post request is a response_url in the body I can use to send back the needed information.
So I have been trying to make this work for about two weeks now and used a fiddler and to mimic the request so I can make some changes on the body and the headers to see if that makes a difference.
So after a lot of errors I have come to two specific errors that haven't changed for a long while.
sent with the Slack Chatbot: curl_error_56
There really isnt much I can change in this matter except the url I want to send the request to.
In fact this request has never even reached the post method in my API.
Thats what the Slackbot answers
sent with fiddler: HTTP error 400
I used Requestbin to get the information that has been sent by the bot and copied it into the composer in fiddler.
I am a total novice to Web programming in any kind of way so I really don't know what they have in common.
Are those errors coming because I am using localhost?
What am I missing?
here is the request so you can copy it if needed
host: localhost:44331
Accept: application/json,*/*
Accept-Encoding: gzip,deflate
Content-Type: application/x-www-form-urlencoded
User-Agent: Slackbot 1.0 (+https://api.slack.com/robots)
X-Slack-Request-Timestamp: 1569238196
X-Slack-Signature: v0=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Length: 381
Connection: keep-alive
Alright I got some help by a friend and he explained to me that Slack is unable to access my localhost, because it is not a local app. It is taking its information from the web and making it send a request to my localhost is useless because it is not a static IP.
What i need is an Endpoint.
I can get one by requesting it from my ISP (Internet Service Provider) or getting myself a server which already has an static IP.
Thanks for any help you wanted to provide.

configuring IIS to cache based on content-type?

We had a weird issue on our site last week that seemed to be a caching issue. A version of our page was cached with Content-Type: text/vnd.wap.wml; charset=utf-8 set in the header.
After some research, I found out that asp .net uses .browser files in the %SystemRoot%\Microsoft.NET\Framework\versionNumber\CONFIG\Browsers path to determine preferred mime types for certain user agents. based on the content-type above, it looks like a Nokia phone was the first application to hit our page after a cache clear based on the content-type above, and asp stored a cached version of the page with that content-type rather than text/html. the problem with that content-type is that browsers do not recognize it, and will just display the page as plain text.
I could verify that the above scenario was the cause. I took one of our servers out of our pool, recycled the app pools for the site and reset iis, then hit the page with fiddler and passed the follow headers as a GET to our homepage.
Accept: text/html
User-Agent: NokiaN90-1/3.0545.5.1 Series60/2.8 Profile/MIDP-2.0 Configuration/CLDC-1.1
this returned the following content-type in the response as expected:
Content-Type: text/vnd.wap.wml; charset=utf-8
Now to fix this going forward, it would make sense for asp to cache various flavors of the page based on the content-type it will be serving, right? is there a way to configure asp to do this, or is there a better way to handle this scenario?
I believe that customarily you'd add Vary: User-Agent header if you plan to serve different content types to different clients. E.g. http://msdn.microsoft.com/en-us/library/system.web.httpcachevarybyheaders.useragent(v=vs.100).aspx

OAuth Test Console signature doesn't agree with working request

I'm having trouble using the LinkedIn API due to being returned a 401 with auth_problem=signature_invalid. I do however have a project which seems to be working with fine so I'm using this to identify the differences.
I read that I can debug with the OAuthTestConsole however this appears to be generating a different signature than the working project.
Since I'm this is only a hobby you can have both my keys:
API Key: gh69xphn2hcr
Secret Key: 0ld6NVvjmpvrmZqw
My working request is:
POST https://api.linkedin.com/uas/oauth/requestToken HTTP/1.1
Content-Type: application/x-www-form-urlencoded Host: api.linkedin.com
Content-Length: 175
Connection: Keep-Alive
oauth_consumer_key=gh69xphn2hcr&oauth_nonce=186481&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1325243837&oauth_version=1.0&oauth_signature=gTeEgzknW6DyI3aFTDcXduroIG4%3d
However the oAuthTestConsole returns an oauth_signature of WNcZFXAC5Y2hoK4srFiFc69zi0M= which is nothing alike (encoded or not).
I'm thinking I must be using the TestConsole wrong and this is preventing me from fixing my issue between the working / non working projects. Could you please point me in the right direction as to why this might occur?
To use the OAuth Test Console, you need to make sure that all of the parameters are exactly the same
- the timestamp (you'll need to set that manually, as it'll otherwise be created based on the current time)
- the nonce (check to see what your library is sending)
- the method (POST in this case)
You need to clear both fields for the access_token (since you don't have one for this initial request)
There is a working C# example posted by a community member here:
https://developer.linkedin.com/thread/1190
Many people have had a lot of luck starting with that, as using OAuth can be tricky without an example to start from.

Icecast 2: protocol description, streaming to it using C#

I need to write an Icecast 2 client that will be able to stream audio from the computer (mp3-files, soundcard recording and so forth) to the server. I decided to write such a client on C#.
Two questions:
1) It will be very useful to know common guidelines (best practices, maybe tricks) I may/should/must use to seamlessly work with streamed audio (streamed over network, of course) in C#. Some general technical documentation about streaming over TCP/IP in common and ICY in particular, advices and notes on the overall architecture of the application will be very appreciated.
2) Is there any good documentation regarding the Icecast 2 streaming protocol? I couldn't find those docs on the official site of Icecast. I don't want to extract the protocol description directly from the source code of it. If the protocol is really simple and neat, could anybody provide a summary of it right here?
As far as I know, there is no protocol spec anywhere, outside of the Icecast source code. Here's what I've found from packet sniffing:
Audio Stream
The protocol is similar to HTTP. The source client will connect to the server make a request with the mountpoint, and pass some headers with information about the stream:
SOURCE /mp3test ICE/1.0
content-type: audio/mpeg
Authorization: Basic c291cmNlOmhhY2ttZQ==
ice-name: This is my server name
ice-url: http://www.google.com
ice-genre: Rock
ice-bitrate: 128
ice-private: 0
ice-public: 1
ice-description: This is my server description
ice-audio-info: ice-samplerate=44100;ice-bitrate=128;ice-channels=2
If all is good, the server responds with:
HTTP/1.0 200 OK
The source client then proceeds to send the binary stream data. Note that it seems some encoders don't even wait for the server to respond with 200 OK before they start sending stream data. Just headers, an empty line, and then stream data.
Meta Data
Meta data is sent using an out-of-band HTTP request. The source client sends:
GET /admin/metadata?pass=hackme&mode=updinfo&mount=/mp3test&song=Even%20more%20meta%21%21 HTTP/1.0
Authorization: Basic c291cmNlOmhhY2ttZQ==
User-Agent: (Mozilla Compatible)
The server responds with:
HTTP/1.0 200 OK
Content-Type: text/xml
Content-Length: 113
<?xml version="1.0"?>
<iceresponse><message>Metadata update successful</message><return>1</return></iceresponse>
Also note that both the audio stream and meta data requests are sent on the same port. Unlike SHOUTcast, this is the base port that the server is running on.
I'm going to comment here despite this question being quite old.
Icecast is HTTP compliant. This was always the case for the listener side (plain and simple HTTP1.0, RFC 1945), starting with 2.4.0 it's also true for the source client side.
To implement a source client it's a PUT request in compliance with HTTP 1.1 aka RFC2616. Some options can be set through HTTP headers, for details please refer to the current Icecast documentation.
If you send one of the supported container formats: Ogg or WebM (technically EBML), then this is all you need to know. To make it clear this covers at leastOpus, Vorbis, Theora and VP8 codecs.
Please note that while generally working fine, other formats are technically not supported. Icecast only passes through the stream without any processing in such a case.
If you need help or have further questions, then the official mailing lists and the IRC channel are the right place to go.
Looked at Icecast2 a good long while ago: best reference I could find was at http://forums.radiotoolbox.com/viewtopic.php?t=74 link (I should print that out, took me forever to figure out the proper Google spell to cast to surface that again). It appears to cover source to server and server to client.
Questions remain about just how accurate it is: I got about halfway through an Android implementation before other things consumed me, and I can't quite remember what was wrong with the communication between my implementation of that and VLC/Winamp, but honestly it was the closest thing I could find to a spec.
The best description I know is here: https://gist.github.com/ePirat/adc3b8ba00d85b7e3870
#ePirat is xpiph/icecast core committer.

Categories