500 Internal Server Error when using HttpWebRequest, how can I get to the real error? - http

I'm trying to improve the information provided in response to an error handled within an app.
This is the code:
Try
httpRequestObj = HttpWebRequest.Create(strRequest)
httpRequestObj.Method = "GET"
httpRequestObj.UseDefaultCredentials = True
* httpResponse = httpRequestObj.GetResponse
Using reader As StreamReader = New StreamReader(httpResponse.GetResponseStream())
strXML = reader.ReadToEnd()
End Using
Catch ex As WebException
'do something with ex
End Try
The webexception is thrown on the * line
Currently all I see in the Exception is "The remote server returned an error: (500) Internal Server Error". I've looked at the exception in debug but the info I need isn't there- I guess the response would need to be read in to see that info but it never gets that far.
If I take the request and paste it into my browser directly I can see the error details in XML format that is returned from the API I'm calling, info like:
<Error>
<description>info I want to get to here</description>
<detail />
<code>info I want to get to here</code>
<source />
<category>info I want to get to here</category>
<file>info I want to get to here</file>
<line>info I want to get to here</line>
<pad />
</Error>
Is there any way I can change this code so that I can get past the 500 error and see the actual response, I'd like to be able to parse this xml to find out the real problem for the failure.
Note: the Exception does have an ex.Response (System.Net.HttpWebResponse), but I can't see the info I need in there, only a load of Header info.

You can get the error response from the exception....
try
{
....
} catch(Exception e) {
if (e is WebException && ((WebException)e).Status==WebExceptionStatus.ProtocolError)
{
WebResponse errResp = ((WebException)e).Response;
using(Stream respStream = errResp.GetResponseStream())
{
// read the error response
}
}
}

System.Net.WebResponse response = null;
try
{
response = wreq.GetResponse();
}
catch (WebException e)
{
if (e.Status == WebExceptionStatus.ProtocolError)
{
string error = new System.IO.StreamReader(e.Response.GetResponseStream()).ReadToEnd();
}
}
catch (Exception e)
{
}
as simple as this, You will get entire response in the string error.

Try to use Fiddler. It's debuging proxy, which will show you all data sending between client and server. You'll be able to see all headers and context as well.

Related

Image Url validation in asp.net

i have images url , i need to check url is responding or not .
For Example :Below i i have written three image url, first two url is not valid only third url is valid .but second and fourth url is responding as valid image
and but there is no image.
http://media.expedia.com/hotels/1000000/90000/84900/84853/84853_744_b.jpg
http://www.iceportal.com/brochures/media/show.aspx?brochureid=ICE19044&did=3073&mtype=3073&type=pic&lang=en&publicid=4175749&resizing=X
http://images.trvl-media.com/hotels/1000000/30000/20400/20313/20313_166_b.jpg
http://www.iceportal.com/brochures/ice/ErrorPages/404.htm?aspxerrorpath=/brochures/media/show_A.aspx
here is my code:
public static bool CheckUrlExists(string url)
{
try
{
Uri u = new Uri(url);
WebRequest w = WebRequest.Create(u);
w.Method = WebRequestMethods.Http.Head;
using (StreamReader s = new StreamReader(w.GetResponse().GetResponseStream()))
{
return (s.ReadToEnd().Length >= 0);
}
}
catch
{
return false;
}
}
with this code i am validating only those url which is showing 404 error,but not those url which showing 'Sorry, requested brochure is temporarily un-published 'or any other type of message.
You will need a more complex logic to validate if the URL points to an image. If a resource is missing from the server or it is otherwise unavailable, you may get a HTTP error like the infamous 404, which will trigger a WebException. However, that is only part of the story.
Your second URL returns HTTP 200, confirming that the resource is there when in fact the resource is missing. What you really get there is a HTML document explaining the resource is not available. This is bad practice, but not without example.
At very least, you should examine the MIME type (Content-Type header, see WebResponse.ContentType) of the resource you test. A content type of image/* suggests an image-type resource. Failing to detect a known MIME type (e.g. if you receive application/octet-stream) you can actually HTTP GET get resource and run image type detection on the downloaded content.
I would suggest using HttpWebRequest and HttpWebResponse to do this, they are sub classes of WebRequest and WebResponse and as such are more granular for what you're trying to achive. The following code works with the example URIs provided
public static bool CheckUrlExists(string url)
{
try
{
Uri u = new Uri(url);
HttpWebRequest w = (HttpWebRequest)WebRequest.Create(u);
w.AllowAutoRedirect = false;
w.Method = WebRequestMethods.Http.Head;
HttpWebResponse response = (HttpWebResponse)w.GetResponse();
return response.StatusCode == HttpStatusCode.OK; //Check http status code
}
catch(WebException ex)
{
return false;
}
}
What's important here is that I'm checking the HttpStatus code. You're catch will already catch the 404s but the problem URIs ultimately lead to a 200 (OK). By setting AllowAutoRedirect to false the HttpWebRequest instance returns a 302 (redirect) status code, instead of following the redirect through to the "Sorry, requested brochure is temporarily un-published." page which is returning 200 (OK). This should serve your purpose.
Also: Catching a WebException will allow you to examine the status code (400+,500+, etc).
Be aware however, that you may be redirected to a new location for the image you're requesting. Taking that you might want to use PeterK's mime type check.

HttpHandler does not send response after catching SqlException?

This HttpHandler does not send a response if con.Open() throws an exception, for example if faultyConnectionString has an invalid database name. Why?
public void ProcessRequest(HttpContext context)
{
int status = 400;
string message = "Test error!";
string faultyConnectionString = "Data Source=LOCALHOST\\SQLEXPRESS;Initial Catalog=XXX;User ID=XXX;Password=XXX";
try
{
using (SqlConnection con = new SqlConnection(faultyConnectionString))
{
//throw new Exception("This works as expected, and is returned to client");
con.Open();
}
}
catch (Exception ex)
{
status = 500;
message = "Test Exception: " + ex.Message;
}
context.Response.StatusCode = status;
context.Response.StatusDescription = message;
}
Here is how I am handling the call in the client:
function GetContacts() {
$.ajax({
type: "POST",
url: "xxx.ashx",
data: "",
contentType: "application/x-www-form-urlencoded; charset=utf-8",
dataType: "text", // "json",
success: function (response, a, b) {
alert(response.status + " " + response.statusText);
},
error: function (response, a, b) {
alert(response.status + " " + response.statusText);
}
});
}
If I F12 in FireFox it shows me that there is no Response received after the request is sent. In IE it shows me "SCRIPT7002: XMLHttpRequest: Network Error 0x2ef3, Could not complete the operation due to error 00002ef3.". In both cases the jquery ajax call returns status=0 and statusText="error".
If I comment out the two lines inside the catch block then it works as expected, sending the 403 code to the client and ignoring the exception.
Different types of exceptions do not have the same problem. If I throw a new Exception() before con.Open() then it also works as expected. What is different with SqlException?
UPDATE: The very first time I hit ProcessRequest it gets called 5 times in succession before the client shows the status=0 result (breakpoint on first line is hit 5 times).
FIDDLER: If I fire up Fiddler it (fiddler) intercepts the transaction and sends "504 Fiddler - Receive Failure" to my ajax call. Looks like the initial repetition may be a retry mechanism, when fiddler is active it does it 13 times.
Fiddler reports: "Session #xxx raised exception System.Net.Sockets.SocketException An existing connection was forcibly closed by the remote host".
I believe the way your client (browser) handles 404 errors is what is causing this, and each browser type is handling the error differently. 404 errors are specific to "Not Found" so you may want to use a different error code such as a 500 error. More info on error codes is available here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
Please keep in mind that passing back detailed error messages to a client could be a security issue due to information leakage. You may be better off passing back a generic error to the client and logging detailed error information on the server side.
Edit:
Testing this locally, the way you are setting context.Response.StatusDescription to contain ex.Message is producing an invalid HTTP response. Try only placing text such as Internal Server Error in there. Additional details can be added to the body of the response using context.Response.Write(bodyText) but please keep the security implications of this in mind.

Bad access exception in Poco::Net::HTTPClientSession when network connection is lost

When I run the following code without a network connection, I get a bad access error on the last line.
Poco::URI uri(sRemoteLoggingURL);
HTTPClientSession session(uri.getHost(), uri.getPort());
HTTPRequest request(HTTPRequest::HTTP_POST, uri.getPathAndQuery());
request.set("User-Agent", "Poco");
string reqBody = "{\"logMessage\":\""+ message + "\", \"application_name\":\""+ sAppName +"\"}";
request.setContentLength( reqBody.length() );
std::ostream& sessionStream = session.sendRequest(request);
Is this expected behavior? Do I need to check for network connectivity before I try to send a request? If so, how do I do that? I've tried session.connected(), but that is returning false even when I do have a network connection.
I think I figured it out. Apparently, you need to be sure to call reset on the session before you destroy it (or before it goes out of scope) if there's an exception. This code works:
Poco::URI uri(sRemoteLoggingURL);
HTTPClientSession session(uri.getHost(), uri.getPort());
try{
HTTPRequest request(HTTPRequest::HTTP_POST, uri.getPathAndQuery());
request.set("User-Agent", "Poco");
string reqBody = "{\"logMessage\":\""+ message + "\", \"application_name\":\""+ sAppName +"\"}";
request.setContentLength( reqBody.length() );
std::ostream& sessionStream = session.sendRequest(request);
if (sessionStream.good()) {
sessionStream << reqBody;
HTTPResponse res;
string text;
istream &is = session.receiveResponse(res);
StreamCopier::copyToString(is, text);
}
}catch(Poco::Exception& e){
// apparently, you MUST call reset before destroying the session, or you'll crash
session.reset();
sdfLog::logFormat("appContent::doIdle Poco::Exception: %s\n", e.what());
}catch(...){
session.reset();
sdfLog::logFormat("appContent::doIdle exception in remote logger %s\n");
}

Sending SMS using Twilio from my website in asp.net

I am trying to send SMS from twilio account. Here is my code.
try
{
string ACCOUNT_SID = ConfigurationManager.AppSettings["XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"];
string AUTH_TOKEN = ConfigurationManager.AppSettings["XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"];
TwilioRestClient client = new TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN);
client.SendSmsMessage("+1XXXXXXXXXX", "+1XXXXXXXXXXX", "Hi");
Label1.Text = "Sent Successfully";
}
catch (Exception ex)
{
Label1.Text = "Error:"+ex.Message;
}
Running on my server, I am receiving message "Sent Successfully" but not receiving message on my phone.
I have changed the original numbers with "XXXXX".Also I have added packages for Twilio.
Please let me know if can.
Twilio evangelist here.
You might be getting an error back from the Twilio REST API when you make the call to SendSmsMessage. You can check if this is happening by grabbing the value returned from the method and seeing if the RestException property is null or not:
var result = client.SendSmsMessage("+1xxxxxxxxxx", "+1xxxxxxxxxx", "Hi");
if (result.RestException!=null)
{
//An error occured
Console.Writeline(result.RestException.Message);
}
Another option would be to use a tool like Fiddler to watch the actual HTTP request/response as it happens and see if any errors are happening.
Hope that helps.

httpconnection.getResponseCode() giving EOF exception

I am using Httconnection for connecting to webserver , somtimes request fails causing
EOFException when calling httpconnection.getResponseCode().
I am setting the following headers while making the connection
HttpConnection httpconnection = (HttpConnection) Connector.open(url.concat(";interface=wifi"));
httpconnection.setRequestProperty("User-Agent","Profile/MIDP-2.0 Configuration/CLDC-1.0");
httpconnection.setRequestProperty("Content-Language", "en-US");
I am closing all the connections after processing the request properly.Is this exception is due to exceeding max connections.
It's an internal server error, which return status code 500 in response.
This may be caused by incorrect request, but as well server code or overload may be the reason.
If you have access to server, check event logs.
See also
500 EOF when chunk header expected
Why might LWP::UserAgent be failing with '500 EOF'?
500 EOF instead of reponse status line in perl script
Apache 1.3 error - Unexpected EOF reading HTTP status - connectionreset
Error 500!
UPDATE On the other hand, if it's not response message, but a real exception, then it may be simply a bug, just like in old java
And workaround may be putting getResponseCode() inside of try/catch and call second time on exception:
int responseCode = -1;
try {
responseCode = con.getResponseCode();
} catch (IOException ex1) {
//check if it's eof, if yes retrieve code again
if (-1 != ex1.getMessage().indexOf("EOF")) {
try {
responseCode = con.getResponseCode();
} catch (IOException ex2) {
System.out.println(ex2.getMessage());
// handle exception
}
} else {
System.out.println(ex1.getMessage());
// handle exception
}
}
Talking by connections number limit, read
What Is - Maximum number of simultaneous connections
How To - Close connections
Using HTTPTransportSE, write this before invoke the method "call"
ArrayList<HeaderProperty> headerPropertyArrayList = new ArrayList<HeaderProperty>();
headerPropertyArrayList.add(new HeaderProperty("Connection", "close"));
transport.call(SOAP_ACTION, envelope, headerPropertyArrayList);

Resources