Protocol violation using Github api - c#

I'm getting data from Github for my application.
The first 2 OAuth steps are ok, but in the third I got the following error:
"the server committed a protocol violation. Section=ResponseStatusLine ERROR"
This is my code:
protected String WebRequest(string url)
{
url += (String.IsNullOrEmpty(new Uri(url).Query) ? "?" : "&") + "access_token=" + _accessToken;
HttpWebRequest webRequest = System.Net.WebRequest.Create(url) as HttpWebRequest;
webRequest.Method = "GET";
webRequest.ServicePoint.Expect100Continue = false;
try
{
using (StreamReader responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream()))
return responseReader.ReadToEnd();
}
catch
{
return String.Empty;
}
}
The program goes in exception after using the StreamReader object, that returns me the error.
If I follow these instructions The server committed a protocol violation. Section=ResponseStatusLine ERROR , the error turns into "403 forbidden".
When Github used api V2, different from now, there was no problem with this code.
So, can't be a .NET limitation but something connected with Github server.
Any suggestions?

You need to set UserAgent like this:
webRequest.UserAgent = "YourAppName";
Otherwise it will give The server committed a protocol violation. Section=ResponseStatusLine error.

Related

Is my method throwing me an exception because the proxy is dead?

So I've been getting into WebRequests recently and something that I found pretty interesting was making a connection through a proxy.
I looked at some blog posts for some code to get a general idea on how it worked and the most recent one would be this code snippet right here.
private static void requestProxy()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://google.com");
WebProxy myproxy = new WebProxy("77.121.11.33", 1080);
myproxy.BypassProxyOnLocal = false;
request.Proxy = myproxy;
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
string content = sr.ReadToEnd();
Debug.Print(content);
Console.WriteLine(content);
}
Console.ReadLine();
}
I tried making a request using that but it seems that it's throwing me an error everytime I try to use a proxy. However when I am not using a proxy it's not throwing me any errors, so I am assuming that the problem lays within the proxy. I tried using different ones but no go.
What I am doing wrong here and whats going on? How do I make a connection with a proxy properly?
Error message
System.Net.WebException: 'An error occurred while sending the request.
The server returned an invalid or unrecognized response'
https://imgur.com/ThxNWzb

HTTPWebRequest GET request causing SSL connection issue

I am trying to connect to a RESTful API and when I access the URL from my browser I get an error stating I am missing headers which is what I was expecting to get. When I connect to the same URL using the below code I get an error stating "The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Authentication failed because the remote party has closed the transport stream". If I use the same code and change the URL to Google.com it works fine and to add to the mystery the connection I make to the API URL from my browser will generate an entry in the Apache logs on the API server, but the below code doesn't. Does anyone have any ideas why I would get that error?
var httpWebRequest = (HttpWebRequest)WebRequest.Create("HTTPS://URL.COM");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "GET";
string html = string.Empty;
try
{
HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse();
string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
Response.Write(responseString);
}
catch (Exception ex)
{
Response.Write(ex.ToString());
}
UPDATE: I tried using HttpClient and got the same results:
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://url.com/");
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("v1/person").Result;
if (response.IsSuccessStatusCode)
{
Response.Write(response);
}
else
{
Response.Write(response);
}
UPDATE 2: The below line of code seems to fix the problem. I am awaiting confirmation now. I am still a little baffled why this was required though.
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;

A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed

I am having an issue :
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 URL.
Also I get issue like:
System.IO.IOException: Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host
and
System.Net.WebException: The operation has timed out at System.Net.WebClient.UploadFile(Uri address, String method, String fileName)
I know that this question has asked before but believe me I tried almost every single resolution at my end.
Weird thing is this issue does not appear at my end at all and only when client try to use which is not constant. Some time my application works fine at their end too.
What I am trying to accomplish is I have created an desktop application (Win Forms & C#) and trying to login client while sending request to my php api server which is hosted on GODaddy.
var request = (HttpWebRequest)WebRequest.Create("url");
if (request != null)
{
#region System.Net.WebException
request.Method = "POST";
if (!string.IsNullOrEmpty(body))
{
var requestBody = Encoding.UTF8.GetBytes(body);
request.ContentLength = requestBody.Length;
request.ContentType = "application/json";
using (var requestStream = request.GetRequestStream())
{
requestStream.Write(requestBody, 0, requestBody.Length);
}
}
else
{
request.ContentLength = 0;
}
request.Timeout = 15000;
request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);
string output = string.Empty;
try
{
using (var response = (HttpWebResponse)request.GetResponse())
{
using (var stream = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(1252)))
{
if (response.StatusCode == HttpStatusCode.OK)
{
while (!stream.EndOfStream)
{
output += stream.ReadLine();
}
output = stream.ReadToEnd();
}
}
}
}
catch
{
// Excaption Caught here
}
}
Please help me out.
Thanks in advance.
Try adding this...
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
request.ServicePoint.ConnectionLimit = 12;
MSDN article recommends 12 connections per CPU hence the limit of 12 because it's hosted by GoDaddy so I'm sure the server resources are limited.
I think I got the answer. Thought to post it so that it could help anyone else.
It most probably the particular machine issue or server issue but in my case, I tried to set Request.proxy = null and it worked like a charm.
I faced this problem at today. I set Timeout property of HttpWebRequest to 1 200 000 milliseconds (20 minute), but I got this error after 5 minute. I researched many sites at google and I found ReadWriteTimeout property of HttpWebRequest. Default value of ReadWriteTimeout is 5 minute. I increased value of ReadWriteTimeout and problem solved for me.
...
httpWebRequest.Timeout = 1200000;
httpWebRequest.ReadWriteTimeout = 1200000;
...

Http post error: An existing connection was forcibly closed by the remote host

I realise there have been a number of similar posts to this but I haven't found a solution yet. Am trying to post some xml to an MPI gateway but keep getting the following error:
Unable to read data from the transport connection: An existing
connection was forcibly closed by the remote host.
Below is the code I'm currently using but have tried just about every different approach I can think of and they all return the same error:
string result = "";
string xml = "<TNSAuthRequest><CardNumber>0123456789</CardNumber><ExpiryDate>1801</ExpiryDate><PurchaseAmt>750</PurchaseAmt><CurrencyCode>826</CurrencyCode><CurrencyExponent>2</CurrencyExponent><CountryCode>826</CountryCode><MerchantName>Mayflower</MerchantName><MerchantId>0123456789</MerchantId><MerchantData>abcdefghijklmnopqrstuvwxyz0123456789</MerchantData><MerchantUrl>example.com</MerchantUrl><NotificationURL>example.com/basket</NotificationURL></TNSAuthRequest>";
var url = "https://mpi.securecxl.com";
byte[] bytes = System.Text.Encoding.ASCII.GetBytes("xmldata=" + xml.ToString());
ServicePointManager.ServerCertificateValidationCallback += new System.Net.Security.RemoteCertificateValidationCallback(ValidateRemoteCertificate);
var req = (HttpWebRequest)WebRequest.Create(url);
req.AllowWriteStreamBuffering = true;
req.ContentType = "text/xml";
req.Method = "POST";
//req.ContentLength = bytes.Length;
req.KeepAlive = false;
req.ProtocolVersion = HttpVersion.Version10;
req.ServicePoint.ConnectionLimit = 1;
//req.Timeout = -1;
try
{
using (var writer = new StreamWriter(req.GetRequestStream(), Encoding.ASCII))
{
writer.WriteLine(bytes);
}
using (WebResponse resp = req.GetResponse())
{
using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
result = sr.ReadToEnd().Trim();
}
}
}
catch (Exception ex)
{
result = ex.Message + "<br />" + ex.InnerException.Message + "<br /><br />" + xml.Replace("<", "<");
}
ViewBag.result = result;
Am basically wandering if anyone can see anything that might be wrong with the code that could be causing this error or if it's most likely I problem on the their end? Have tried running on my localhost, our live server and my own private server (with a completely different IP) and still get same result.
Any ideas?
I think its because you are connecting to "https" url. In this case you have to add following line to your code.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
It will accept "ssl" protocol for your request. "ServicePointManager.ServerCertificateValidationCallback" handler just controls certificate validity.
Slightly better perhaps:
System.Net.ServicePointManager.SecurityProtocol = System.Net.ServicePointManager.SecurityProtocol | System.Net.SecurityProtocolType.Tls12;
#AlisettarHuseynli is right, this sometimes has to do with https. Most likely occurs when the infrastructure gets updates which may mean TLS gets updated for example from TLS1.0 to TLS1.2 Usually happens with some APIs, etcetera.
If the service you are trying to access can be accessed over http, do that. Change the scheme from https to http. Worked in my case. Otherwise you'll have to add code to support higher versions of TLS. Popular software usually have an opt-in option to use TLS1.2 instead of the old TLS1.0.

.NET service responds 500 internal error and "missing parameter" to HttpWebRequest POSTS but test form works fine

I am using a simple .NET service (asmx) that works fine when invoking via the test form (POST). When invoking via a HttpWebRequest object, I get a WebException "System.Net.WebException: The remote server returned an error: (500) Internal Server Error." Digging deeper, reading the WebException.Response.GetResponseStream() I get the message: "Missing parameter: serviceType." but I've clearly included this parameter.
I'm at a loss here, and its worse that I don't have access to debug the service itself.
Here is the code being used to make the request:
string postData = String.Format("serviceType={0}&SaleID={1}&Zip={2}", request.service, request.saleId, request.postalCode);
byte[] data = (new ASCIIEncoding()).GetBytes(postData);
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.Timeout = 60000;
httpWebRequest.Method = "POST";
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
httpWebRequest.ContentLength = data.Length;
using (Stream newStream = httpWebRequest.GetRequestStream())
{
newStream.Write(data, 0, data.Length);
}
try
{
using (response = (HttpWebResponse)httpWebRequest.GetResponse())
{
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception("There was an error with the shipping freight service.");
string responseData;
using (StreamReader responseStream = new StreamReader(httpWebRequest.GetResponse().GetResponseStream(), System.Text.Encoding.GetEncoding("iso-8859-1")))
{
responseData = responseStream.ReadToEnd();
responseStream.Close();
}
if (string.IsNullOrEmpty(responseData))
throw new Exception("There was an error with the shipping freight service. Request went through but response is empty.");
XmlDocument providerResponse = new XmlDocument();
providerResponse.LoadXml(responseData);
return providerResponse;
}
}
catch (WebException webExp)
{
string exMessage = webExp.Message;
if (webExp.Response != null)
{
using (StreamReader responseReader = new StreamReader(webExp.Response.GetResponseStream()))
{
exMessage = responseReader.ReadToEnd();
}
}
throw new Exception(exMessage);
}
Anyone have an idea what could be happening?
Thanks.
UPDATE
Stepping through the debugger, I see the parameters are correct. I also see the parameters are correct in fiddler.
Examining fiddler, I get 2 requests each time this code executes. The first request is a post that sends the parameters. It gets a 301 response code with a "Document Moved Object Moved This document may be found here" message. The second request is a GET to the same URL with no body. It gets a 500 server error with "Missing parameter: serviceType." message.
It seems like you found your problem when you looked at the requests in Fiddler. Taking an excerpt from http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html:
10.3.2 301 Moved Permanently
The requested resource has been assigned a new permanent URI and any future references to this resource SHOULD use one of the returned URIs. Clients with link editing capabilities ought to automatically re-link references to the Request-URI to one or more of the new references returned by the server, where possible.
.....
Note: When automatically redirecting a POST request after
receiving a 301 status code, some existing HTTP/1.0 user agents
will erroneously change it into a GET request.
Here's a couple options that you can take:
Hard-code your program to use the new Url that you see in the 301 response in Fiddler
Adjust your code to retrieve the 301 response, parse out the new Url from the response, and build a new response with the new Url.
The latter option would be ideal if you're dealing with user-based input on the Url (like a web browser), since you don't know where the user is going to want your program to go.

Categories