500 Server Error HTML returned from MVC AJAX call when plain text specified - asp.net-mvc-2

I am trying to return plain text from my MVC AJAX methods that indicates an error code. This is working fine on my dev machine, but when deployed to a server (Win2008 R2) I am always getting the HTML of the 500.htm page back in the error.responseText from my AJAX call instead of the text I specified. Any ideas why I would not get back the plain text I intended?
Here is my error handling logic in my controller.
protected override void OnException(
ExceptionContext filterContext
)
{
try
{
Error error = ControllerCommon.ProcessException(filterContext);
// return error
filterContext.Result = HandleError(error.Type);
filterContext.ExceptionHandled = true;
}
catch (Exception ex)
{
Logger.Instance.LogImportantInformation(ex.Message, 0, Constants.EventSourcePortal);
}
}
#endregion
#region Private Methods and Members
private ActionResult HandleError()
{
return HandleError(Error.ErrorType.Unknown);
}
private ActionResult HandleError(
Error.ErrorType errorType
)
{
// set return status code
HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
Logger.Instance.LogImportantInformation(((int)errorType).ToString(CultureInfo.InvariantCulture), 0, Constants.EventSourcePortal);
// return error type
return Content(((int)errorType).ToString(CultureInfo.InvariantCulture), "text/plain");
}
Here is the header that I get back from the Server.
Response Headers
Cache-Control private
Content-Type text/html
Server Microsoft-IIS/7.5
X-AspNet-Version 4.0.30319
X-Powered-By ASP.NET
Date Mon, 20 Jun 2011 16:00:42 GMT
Content-Length 1208
Request Headers
Host pqompo2test01.dns.microsoft.com
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
Accept text/html, /
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip, deflate
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive 115
Connection keep-alive
Content-Type application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With XMLHttpRequest
Referer https://pqompo2test01.dns.microsoft.com/Incident/List
Content-Length 330
Cookie MC1=GUID=111c287d88c64447a63719bb2c858981&HASH=7d28&LV=20114&V=3; A=I&I=AxUFAAAAAACJCAAAMuSpPH1Citx6nZO0iHfvdA!!&CS=116|9n002j21b03; WT_FPC=id=131.107.0.73-1717525904.30146426:lv=1308581948698:ss=1308581948698; MUID=7F438FBFEEE948D88DA06B04F6923159; MSID=Microsoft.CreationDate=04/20/2011 16:45:49&Microsoft.LastVisitDate=06/20/2011 15:59:10&Microsoft.VisitStartDate=06/20/2011 15:59:10&Microsoft.CookieId=4c7552d0-5e75-4e5e-98b9-4ca52421a738&Microsoft.TokenId=ffffffff-ffff-ffff-ffff-ffffffffffff&Microsoft.NumberOfVisits=27&Microsoft.CookieFirstVisit=1&Microsoft.IdentityToken=AA==&Microsoft.MicrosoftId=0668-8044-9161-9043; ANON=A=FA4FB528F204DDFA69239A4FFFFFFFFF&E=b4d&W=4; NAP=V=1.1&E=af3&C=hJtCCJq27admlaiwmdzvTmnAwIEVXv1jFR2I2bJ-gncMGQOJce96RQ&W=4; mcI=Wed, 27 Apr 2011 16:48:43 GMT; omniID=fd752842_58d3_4833_9a0f_d0e1e3bbfef3; WT_NVR_RU=0=msdn:1=:2=; ASP.NET_SessionId=dbcqi222tehjorefcopchuzu; MS0=7fc23d65df4241c89554b502149ccc13; MICROSOFTSESSIONCOOKIE=Microsoft.CookieId=94c8a34f-9184-4e10-84c5-2b9c43c7a962&Microsoft.CreationDate=06/20/2011 15:59:10&Microsoft.LastVisitDate=06/20/2011 15:59:10&Microsoft.NumberOfVisits=1&SessionCookie.Id=04DF98242DBD0730C9388487546F2F37; RPSMCA=FAAaARSsz90pZKmFSg5n0wbtR5MnQAldBwNmAAAEgAAACDNAEUimN1wb2AD%2Bp1PnEJUdd7n5VumQIQerCQYdD5IEd6ZCDEshkiTkvVl5a9eA6%2B9a0Os/1FpoqtvsGYMdWUUc98PUl5ZTo%2BFXAqxiZ9BL5D69OLCPsZEXitrZMulmKXFGQiAD5FqJY8JOOSJ1xptRwdkdrxGF8PuNit/Si87Ft7g4sF9vE878lMSx6TSmQq3nrurnBbdbUvDvwTKLoY0gAikOxJ7GmZoLw4kbzaLR/6/a/XSJFv%2BZ6uHsIwkMn6mndoZKfg3LLjDlCpozrHBlnKtgkn7yZXtd8Or420IXuPMUAF3gfp8VAkhKlVceTXpBv2h4gs6g; RPSMCSA=FAAaARSsz90pZKmFSg5n0wbtR5MnQAldBwNmAAAEgAAACEdSXDQ0SIKI2AC/tM6y7CeHdaKVAab/n/4TLKkF5/01jGkXR0vA07MTvS5vhwgjCPMs4zke%2B0jnB1DqOV2vI4VqQ/%2BOIYh52QkaLREoD5L718AjEJOQdDVRRZiIB51CiYtS0P/kgIkEtfDa5yuTr3w6V2IKhy2%2B6wVrP/UqxsJR%2BZ1QmGxtjv7eQVGdIndrkPx5e9wFqj1qEcf9FNfH0/uajuaTFaNmi/3dQfWuEKxGpoHWNxgoMf8PHLVi2hqltqK47OloCGqQGLPQPx0PSg1K73FTZHhl3%2BuxyNqyWJumKsAUAGuMUzFhTPsQ7JdOSfY2SYyHeaZP; RPSShare=1; MSPAuth=1NNm8kdmWAFrAuL2d8qOShxJKehL!CxEkCQvsgPdNGDqo0XFGsreQZ9GMVjiT1*bHPlGcNVsyfbVO7h!eY32bCNY7Farp2grIyEgAFv7YgJqWZN2Q87*LBZnZ0ASWmhPqe; MSPProf=1ZN*xhGN9GRXSO*HEmrISYo6cowSUbmxtIsYfqtHv!!VzEybb1I33*BdWWJrz54tkO5BzS3eTprAXL1LO9ELLBziO8Sm8WTzkSbV*E6ECcX9N92*AFiJztc4rlwCLQnMBhxlV0qzvlRN4dS1SajyzABZDNBTG*tdyqfnuP6jkSevAhuXYvnEuKZQKAF5fvgr4!oiBQ2KhnuH0$; RequestVerificationToken_Lw=TOS6XUQ+17bDOxh2T75NhhFy2KIJP5BP9MetB7cAa4i68ZEHIEpgE7xwQhzid/YiZCm4GsbW2zsJjlIxkB1hrhVGoU++E1I5BP9X2PyKn0O8tic84cWNz8QRjLDcaAcF4iYEQQ==; prmrsdninc=1
When I run locally on my Win7 machine I simply get the text back that I am expecting.

I was having the same problem trying to return 500 pages containing only text for processing by telerik controls. Of course it worked tickity-boo on my development machine and failed when published up to the proper IIS servers.
This fixed it for me:
http://blog.janjonas.net/2011-04-13/asp_net-prevent-iis_75_overriding-custom-error-page-iis-default-error-page
Summary: Type putting a
Response.TrySkipIisCustomErrors = true;
line in your action

Related

Wrong Content-Type in response in IErrorHandler

I would like to send response to my service in JSON format. I catch my custom errors in my custom behavior:
void IErrorHandler.ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
XDocument errorMsg = XDocument.Parse("<errorMessage>" + error.Message + "</errorMessage>");
var jsonWriter = new JsonErrorBodyWriter(errorMsg);
fault = Message.CreateMessage(version, null, jsonWriter);
fault.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Json));
HttpResponseMessageProperty prop = new HttpResponseMessageProperty();
prop.StatusCode = HttpStatusCode.Unauthorized;
prop.Headers.Add("Content-Type", "application/json; charset=utf-8");
prop.Headers[HttpRequestHeader.ContentType] = "application/json; charset=utf-8";
--Tried different ways to achieve this
fault.Properties.Add(HttpResponseMessageProperty.Name, prop);
}
But I get wrong content-type in response. And also I couldn't manage to write any custom header like :
prop.Headers.Add("Test", "Value");
Reponse:
HTTP/1.1 401 Unauthorized
Content-Type: application/xml; charset=utf-8
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Date: Wed, 30 Sep 2020 08:41:15 GMT
Content-Length: 37
{"description":"Autorization Failed"}
What is wrong in my code?

Docker API returns 200 OK then 400 BAD REQUEST

I am writing an API client for Docker. I understood from the documentation that the API is Restful/HTTP, yet if you connect to the local daemon you have to do it over the exposed unix socket.
It all seems to work, I open a socket, send an HTTP request (which respects the specification), I receive the expected response, but also a 400 BAD REQUEST response follows immediately.
Here is the request:
GET /info HTTP/1.1
Host: localhost
Accept: application/json
And here is what I get:
HTTP/1.1 200 OK
Api-Version: 1.30
Content-Type: application/json
Docker-Experimental: false
Ostype: linux
Server: Docker/17.06.1-ce (linux)
Date: Thu, 01 Feb 2018 18:53:18 GMT
Transfer-Encoding: chunked
892
{"ID":"6MGE:35TO:BI..." ...}
0
HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
Connection: close
400 Bad Request
First, I figured that there is a bug on my side and I am somehow sending 2 requests, but I enabled debugging and followed the logs with sudo journalctl -fu docker.service and there is exactly one request received... at least one is logged, the GET /info. I've also debugged the code and 1 single request is sent.
Any hint is greatly appreciated!
Edit: here is the client's code:
final StringBuilder hdrs = new StringBuilder();
for(final Map.Entry<String, String> header : headers) {
hdrs.append(header.getKey() + ": " + header.getValue())
.append("\r\n");
}
final String request = String.format(
this.template(), method, home, hdrs, this.readContent(content)
);
final UnixSocketChannel channel = UnixSocketChannel.open(
new UnixSocketAddress(this.path)
);
final PrintWriter writer = new PrintWriter(
Channels.newOutputStream(channel)
);
writer.print(request);
writer.flush();
final InputStreamReader reader = new InputStreamReader(
Channels.newInputStream(channel)
);
CharBuffer result = CharBuffer.allocate(1024);
reader.read(result);
result.flip();
System.out.println("read from server: " + result.toString());
It seems like you have an extra CRLF between headers and body.
private String template() {
final StringBuilder message = new StringBuilder();
message
.append("%s %s HTTP/1.1\r\n")
.append("Host: localhost").append("\r\n")
.append("%s")
.append("\r\n").append("\r\n") //one of these is superfluous, as each header line ends with "\r\n" itself
.append("%s");
return message.toString();
}
Remove one append("\r\n") after headers and see what happens.
Fixed. Initially, I thought the problem was with the line endings (that they should have been \n instead of \r\n). Turns out, the 400 BAD REQUEST occured because the Connection: close header was missing, while the Request made was being closed right after receiving the response.
More details here.

can't get web page source from url in Swift

I'm currently using SwiftHTTP for getting source of url address. I am using 'get method' for getting source code of url address which is
do {
let opt = try HTTP.GET(self.my_url_address!)
opt.start { response in
if let err = response.error {
print("error: \(err.localizedDescription)")
return
}
print(response.description)
}
} catch let error {
print("got an error creating the request: \(error)")
}
after this code run I got this output in Xcode output screen
URL: http://myweburl.com/detay/swat-under-siege.html
Status Code: 200
Headers: Content-Type: text/html
Connection: keep-alive
CF-RAY: 38391215a60e2726-FRA
Set-Cookie: ASPSESSIONIDSABBBSDT=HPKKPJGCDLKMDMILNGHPCAGD; path=/
Date: Mon, 24 Jul 2017 18:51:24 GMT
Vary: Accept-Encoding
X-Powered-By: ASP.NET Transfer-Encoding: Identity
Server: cloudflare-nginx
Content-Encoding: gzip
Cache-Control: private
The status code is 200 but the output is not the source code of url. How can I fix this?
Response is correct. I've tried requesting the website (the real one) and it works:
print(response.data.base64EncodedString())
If you decode the BASE64 data, it will render valid HTML code.
The issue seems related to encoding. After checking the website's head tag, it states that the charset is windows-1254
String(data: response.data, encoding: .windowsCP1254) // works. latin1, etc.
Your issue is similar to SWIFT: NSURLSession convert data to String

302 redirect after CORS preflight

I'm running into a problem with a 302 redirect after my CORS preflight has successfully returned a 200 status. I'm currently building an app using Laravel 4.1 and Angular 1.2 as well as my own OAUTH2 server.
The error that Chrome/FF/Safari are sending back to me is:
XMLHttpRequest cannot load http://localhost.api/api/v1/tracks?$filter=id%20eq%20guid%27d7de10ba-e353-455b-a3cb-ced9b4965141%27&. The request was redirected to 'http://localhost.api/session/invalid', which is disallowed for cross-origin requests that require preflight.
I assume whats causing my issue is the "redirect" thats happening - as my normal CORS requests all work as expected.
My configuration for my Access-Control-Allow-* headers is fairly open right now during testing.
'paths' => array(
'^/api/' => array(
'allow_origin'=> array('*'),
'allow_headers'=> array('Content-Type', 'Authorization'),
'allow_methods'=> array('POST', 'PUT', 'GET', 'DELETE', 'OPTIONS'),
'max_age' => 0
),
'^/session/' => array(
'allow_origin'=> array('*'),
'allow_headers'=> array('Content-Type', 'Authorization'),
'allow_methods'=> array('GET', 'OPTIONS'),
'max_age' => 0
)
The redirect in question is in a pre-filter thats checking the validity of an OAUTH2 access token
public function filter($route, $request, $data = null)
{
// Get the authorization header or fail
if ($authorization = Request::header('Authorization', false)) {
list($type, $token) = explode(' ', $authorization);
if (is_null($auth = OAuth2::token($token)->first())) {
return Redirect::to('session/invalid');
}
$tokenExpiryDate = Carbon::createFromTimeStamp($auth->access_token_expires);
// If we don't have a Bearer authentication header
// or if the token has expired. Then redirect to an
// expired session route
if ( 'bearer' != strtolower($type)
|| Carbon::now()->gt($tokenExpiryDate)
) {
return Redirect::route(
'expiredSession',
array('expiry' => $tokenExpiryDate->timestamp)
);
}
} else {
// The authentication header is invalid, redirect to let the user know.
return Redirect::to('session/invalid');
}
}
All these requests worked when I tried debugging using POSTMAN, but after my research I've basically found that extensions don't necessarily have to play by the same rules. As well as I noticed my requests using POSTMAN never send any preflight OPTIONS requests when I initiate a simple GET, POST, etc..
Here are the headers of both an OPTIONS request as well as a GET request to follow it that is returning my error
OPTIONS Request
Remote Address:127.0.0.1:80
Request URL:http://localhost.api/api/v1/tracks?$filter=id%20eq%20guid%27d7de10ba-e353-455b-a3cb-ced9b4965141%27&
Request Method:OPTIONS
Status Code:200 OK
Request Headers
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, authorization
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
DNT:1
Host:vegas.ine.com
Origin:http://localhost.angular
Pragma:no-cache
Referer:http://localhost.angular/admin/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36
Response Headers
Access-Control-Allow-Headers:content-type, authorization
Access-Control-Allow-Methods:POST, PUT, GET, DELETE, OPTIONS
Access-Control-Allow-Origin:http://localhost.angular
Cache-Control:no-cache
Connection:close
Content-Type:text/html
Date:Thu, 01 May 2014 16:22:19 GMT
Server:Apache/2.2.26 (Unix) DAV/2 PHP/5.4.24 mod_ssl/2.2.26 OpenSSL/0.9.8y
Set-Cookie:laravel_session=eyJpdiI6IktOZjlTM1ZVNUx0TEhoaTczY3dQcDBKRWlvbnppbDA3QTdqSENJdTc2R1U9IiwidmFsdWUiOiJEZ2ltXC9mNm1Qa20rV3BVRlNHTXgySGtUeVlpNjNZcGFudDFBWDJJekl1MEVNVlhSRE5WWk5YZDNxUkZuU0VEVytcL3NLNlVBXC9hZWtJQzdHU2FqVWtMdz09IiwibWFjIjoiYTYxYjEwNjlmYmI2MjMwNmE4MzlkYjIwNGZlNzA4Y2ViZGVkZmU1MTQzMzc5NmU2YzI2ZGExNzYxY2U5ZjdiMCJ9; expires=Thu, 01-May-2014 18:22:19 GMT; path=/; httponly
X-Frame-Options:SAMEORIGIN
X-Powered-By:PHP/5.4.24
GET Request
Remote Address:127.0.0.1:80
Request URL:http://localhost.api/api/v1/tracks?$filter=id%20eq%20guid%27d7de10ba-e353-455b-a3cb-ced9b4965141%27&
Request Method:GET
Status Code:302 Found
Request Headers
Accept:application/json, text/plain, */*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Authorization:Bearer 6Ss4XPrPM5jQD7Es0dz7TPRQ76hGA69vT9K94pst
Cache-Control:no-cache
Connection:keep-alive
DNT:1
Host:vegas.ine.com
Origin:http://localhost.angular
Pragma:no-cache
Referer:http://localhost.angular/admin/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36
Response Headers
Access-Control-Allow-Origin:http://localhost.angular
Cache-Control:no-cache
Connection:Keep-Alive
Content-Type:text/html; charset=UTF-8
Date:Thu, 01 May 2014 16:22:19 GMT
Keep-Alive:timeout=5, max=100
Location:http://localhost.api/session/invalid
Server:Apache/2.2.26 (Unix) DAV/2 PHP/5.4.24 mod_ssl/2.2.26 OpenSSL/0.9.8y
Set-Cookie:laravel_session=eyJpdiI6InlnREVPcUJTcyswMnRLanFDSlZ6QWFBVXZWMGdMNVNLYWxNTHRJVUlkalk9IiwidmFsdWUiOiJ4aXN5U0dcL1NYeGQrcUVzWFhYV3o2MWhcL25hQTlhcVUxbWxkN2R6SG9KZDNKaGNLTkRQY2FyTitpVHNGZzYxVVRtZUhoZGZRWE9GWjZRaDd1VVwvZUZuUT09IiwibWFjIjoiY2EzZTViZGIzZmVlMDcwZjdhMzBjOWQxYTgwZWNlYTJiMDk3ODdlZTk3NTYxMDNmM2YyODJjOGIxMzBmMmJlMiJ9; expires=Thu, 01-May-2014 18:22:20 GMT; path=/; httponly
Transfer-Encoding:chunked
Vary:Authorization
X-Clockwork-Id:1398961340.2239.1349476325
X-Clockwork-Version:1.5
X-Frame-Options:SAMEORIGIN
X-Powered-By:PHP/5.4.24
I have done something like this and it worked fine for me
//pattern to allow origins
$allowedOriginPattern = /** YOUR PATTERNS **/;
$allowedOrigin = "";
if (preg_match($allowedOriginPattern, $_SERVER['HTTP_ORIGIN'])) {
$allowedOrigin = $_SERVER['HTTP_ORIGIN'];
}
/**
* set http content type
*/
header('Content-Type: application/json;charset=UTF-8');
header('Access-Control-Allow-Origin: ' . $allowedOrigin);
header('Access-Control-Allow-Methods: DELETE, HEAD, GET, OPTIONS, POST, PUT');
header('Access-Control-Allow-Headers: Content-Type, Content-Range, Content-Disposition, Content-Description');
header('Access-Control-Max-Age: 1728000');
I have added this code in laravel index.php
Here is the reference for CORS
http://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0
Spent an hour and this trying to redirect to a subdomain
Instead just used javascript after a successful response
window.location.href = resp.data.redirect

GWT RPC GWTTestCase + GUICE 2.0

Im trying to create an app with the GWT on the front end and GUICE on the backend served on the Google App Engine.
I have created a very simple app using the example setup
http://stuffthathappens.com/blog/2009/09/14/guice-with-gwt/#comment-49355
The app works fine, however I wanted to add some unit tests for the GWT RPC calls.
I am trying to use the GWTTestCase as below:
`public void testContactMessageService() {
ContactMessage message = new ContactMessage();
message.setName("Jeff");
message.setMessage("Just wanted to say I'm a fan.");
message.setEmail("man.nick.utd#gmail.com");
ContactMessageServiceAsync contactMessageService = GWT.create(ContactMessageService.class);
contactMessageService.sendMessage(message,
new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
System.out.println(caught);
fail("big time failure");
finishTest();
}
public void onSuccess(String result) {
System.out.println("success, biatch");
assertTrue(true);
finishTest();
}
});
delayTestFinish(1000);
}
`/**
However when I run the test it fails and on the console it prints
[WARN] 404 - POST /com.resume.Contacthandler.JUnit/GWT.rpc (192.168.0.11) 1425 bytes
Request headers
Host: 192.168.0.11:4016
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.19) Gecko/2010031422 Firefox/3.0.19
Accept-Language: en-us
Accept: /
Connection: Keep-Alive
Referer: 192.168.0.11:4016/com.resume.Contacthandler.JUnit/junit.html?gwt.codesvr=192.168.0.11:4012
X-GWT-Permutation: HostedMode
X-GWT-Module-Base: 192.168.0.11:4016/com.resume.Contacthandler.JUnit/
Content-Type: text/x-gwt-rpc; charset=utf-8
Content-Length: 285
Response headers
Content-Type: text/html; charset=iso-8859-1
Content-Length: 1425
com.google.gwt.user.client.rpc.StatusCodeException: 404
HTTP ERROR: 404 NOT_FOUND
RequestURI=/com.resume.Contacthandler.JUnit/GWT.rpc
From this output I am assuming something on the server side with Guice is not getting setup.
How do you setup the server side Guice servlets when running GWTTestCases ?
There are much simpler ways to get Guice and GWT working other than the approach in the stuffthathappens blog. For instance, the following code is most of what you'd need to do to get a servlet up and running. This doesn't touch any GWT code so it's easy to test with pure JRE tests - you'd just need to set up a test injector and get an instance of the Service Impl.
serve("/myapp/importservice").with(SourceImportServiceImpl.class);
#Singleton
public class SourceImportServiceImpl extends RemoteServiceServlet {
private Provider<SimpleDao> daoProvider;
#Inject
public SourceImportServiceImpl(Provider<SimpleDao> daoProvider) {
this.daoProvider = daoProvider;
}
... RPC method implementations
}