How to read HTTP header from response using .NET HttpWebRequest API? - c#

My app currently uses OAuth to communicate with the Twitter API. Back in December, Twitter upped the rate limit for OAuth to 350 requests per hour. However, I am not seeing this. I am still getting 150 from the account/rate_limit_status method.
I was told that I needed to use the X-RateLimit-Limit HTTP header to get the new rate limit. However, in my code, I do not see that header.
Here is my code...
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(newURL);
request.Method = "GET";
request.ServicePoint.Expect100Continue = false;
request.ContentType = "application/x-www-form-urlencoded";
using (WebResponse response = request.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
responseString = reader.ReadToEnd();
}
}
If I inspect the response, I can see that it has a property for Headers, and that there are 16 headers. However, I do not have X-RateLimit-Limit in the list.
(source: yfrog.com)
Any idea what I am doing wrong?

You should simple be able to use:
using (WebResponse response = request.GetResponse())
{
string limit = response.Headers["X-RateLimit-Limit"];
...
}
If that doesn't work as expected, you can do a watch on response.Headers and see what's in there.

Look at the raw response text (e.g., with Fiddler). If the header isn't there, no amount of C# code is going to make it appear. :) From what you've shown, it seems the header isn't in the response.
Update: When I go to: http://twitter.com/account/rate_limit_status.xml there is no X-RateLimit-Limit header. But when I go to http://twitter.com/statuses/public_timeline.xml, it's there. So I think you just need to use a different method.
It still says 150, though!

Related

C# HttpWebRequest Medium Blog returns 403 Forbidden but Site is Open

Medium blog pages are available on Chrome, IE etc... browsers but I can not send a web request with this code blog. It returns 403 Forbidden. By the way this method was working properly a couple of days ago. I changed my IP address numerious times, thought they might have banned my IP address but did not work.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://medium.com/#coinbaseblog");
request.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (System.IO.Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
Try this:
var request = (HttpWebRequest)WebRequest.Create("https://medium.com/#coinbaseblog");
request.UserAgent = #"Mozilla/5.0 (compatible; Rigor/1.0.0; http://rigor.com)";
var result = (HttpWebResponse)request.GetResponse();
http status code 403 indicates that server has understood the request but refuses to authorize it. Even if you are reauthenticating it will make no difference. This is similar to http status code 401 but in this case reauthentication works just fine. You may be authenticated but the resource which you are trying to access is restricted for you.

Do I need to post every request header when simulating a webpage log in through C#?

I am working on getting information that is behind a log in page, and using this as my starting point.
Looking at the Network tab, I looked at the form data and saw there were 3 additional values than just client/password (csrf, time, hash).
I attempted to log into the site as follows.
string formUrl = "mysite_loginaction";
string formParams = string.Format("client_id={0}&password={1}", "client", "password");
string cookieHeader;
WebRequest req = WebRequest.Create(formUrl);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(formParams);
req.ContentLength = bytes.Length;
using (Stream os = req.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
WebResponse resp = req.GetResponse();
cookieHeader = resp.Headers["Set-cookie"];
When I print out the resp to my console, it shows my the log in page, when i was expecting the next page after login (google 2f page).
Do I need to post a csfr, time, and hash values as well to get a successful login?
Like it has been mentioned in your link, there is a concept of sessionid token. If you do want to stay logged in, you need to pass that token everytime for the following http requests.
Also, the CSRF token will always be different each time you do the request, but you do need to pass it along your next request to be successful.
To know more about CSRF, I should redirect you to this link
You're going to have to mess around with it. Most of the time you don't need all the headers, but I would assume that hash is required.

Measure exact time breakdown of http request in c#

I have a HTTP request in my Asp.net MVC app with some code like below:
var request = (HttpWebRequest)WebRequest.Create("http://www.example.com/get");
request.Method = "GET";
using (var response = (HttpWebResponse)request.GetResponse())
{
var statusCode = response.StatusCode;
var body = new StreamReader(response.GetResponseStream()).ReadToEnd();
//my logic ...
}
So I'm wondering if there is any solution to find out request exact time breakdown like Google Chrome Developer Tools. If I want to be honest, I need these times:
DNS Lookup
Initial connection
Request sent
Waiting (TTFB)
Content Download
Google Chrome Developers Tools example:

Adding Headers and Post data in RESTfull/HTTP Request in C#

I'm having problems with sending POST request in C# and it seems I misunderstood some HTTP basics. So basically I'm implementing RESTfull service client, which work as follows:
Make POST request with username/password and get token
Use this token in header (Authorization:TOKEN) while making other GET/POST/PUT requests
I use WebRequest to make GET requests (with Authorization header) and it's working. But when I use following code to make PUT requests, service is giving "Authentication failed - not logged in" message back:
String url = String.Format("{0}/{1}", AN_SERVER, app);
WebRequest theRequest = WebRequest.Create(url);
theRequest.Method = "POST";
theRequest.ContentType = "text/x-json";
theRequest.ContentLength = json.Length;
Stream requestStream = theRequest.GetRequestStream();
requestStream.Write(Encoding.ASCII.GetBytes(json), 0, json.Length);
requestStream.Close();
theRequest.Headers.Add("Authorization", authToken);
HttpWebResponse response = (HttpWebResponse)theRequest.GetResponse();
I must be making minor mistake (at least I hope so) while sending POST request. So what am I doing wrong?
Thanks.
Moving Headers before the request steam works (as per AI W's comment), because the request stream is adding the body.
The way webrequest is implemented internally, you need to finish the header before writing body, and once its in stream format, its ready to send.
If you look at the implementation of webrequest in reflector or some such decompiling tool, you'll be able to see the logic.
Hope this helps

C# REST client sending data using POST

I'm trying to send a simple POST request to a REST web service and print the response (code is below, mostly taken from Yahoo! developer documentation and the MSDN code snippets provided with some of the documentation). I would expect the client to send:
Request Method: POST (i.e. I expect $_SERVER['REQUEST_METHOD'] == 'POST' in PHP)
Data: foo=bar (i.e. $_POST['foo'] == 'bar' in PHP)
However, it seems to be sending:
Request Method: FOO=BARPOST
Data: (blank)
I know the API works as I've tested it with clients written in Python and PHP, so I'm pretty sure it must be a problem with my C#. I'm not a .NET programmer by trade so would appreciate any comments/pointers on how to figure out what the problem is - I'm sure it's something trivial but I can't spot it myself.
uri, user and password variables are set earlier in the code - they work fine with GET requests.
request = (HttpWebRequest) WebRequest.Create(uri);
request.Credentials = new NetworkCredential(user, password);
request.Method = WebRequestMethods.Http.Post;
request.ContentType = "application/x-www-form-urlencoded";
string postData = "foo=bar";
request.ContentLength = postData.Length;
StreamWriter postStream = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII);
postStream.Write(postData);
postStream.Close();
response = (HttpWebResponse) request.GetResponse();
The REST API is written in PHP, and the $_POST array is empty on the server when using the C# client.
Eventually found the HttpWebRequest.PreAuthenticate property which seems to solve the problem if the code is edited like so:
request = (HttpWebRequest) WebRequest.Create(uri);
request.PreAuthenticate = true;
request.Credentials = new NetworkCredential(user, password);
request.Method = WebRequestMethods.Http.Post;
From the documentation I presume this forces authentication before the actual POST request is sent. I'm not sure why the class doesn't do this automatically (libraries for other languages make this process transparent, unless you explicitly turn it off), but it has solved the problem for me and may save someone else another 2 days of searching and hair-pulling.
For what it's worth, PreAuthenticate doesn't need to be set for GET requests, only POST, although if you do set it for a GET request everything will still work, but take slightly longer.

Categories

Resources