405 (POST not allowed) HttpException when trying to apply HttpResponse.Filter - .net-4.0

We are getting a 405 error and the following exception from IIS7 when attempting to apply a ResponseStreamFilter to HttpResponse.Filter:
HttpException:
The HTTP verb POST used to access path '/app/Thing.asmx/Command' is not allowed.
We are applying the filter by using an HttpModule with code like this:
var rfs = new ResponseFilterStream(HttpContext.Current.Response.Filter);
rfs.TransformStream +=
new Func<System.IO.MemoryStream, System.IO.MemoryStream>(ProcessStream);
HttpContext.Current.Response.Filter = rfs;
Log("Response stream filter applied correctly.");
All of the code in our HttpModule works just fine... it's all wrapped in a try-catch just to be safe and isn't throwing any exceptions, and diagnostic logging like the last line above is working correctly.
But it looks like our ProcessStream method in the above code is never being called. If we apply the filter to HttpResponse.Filter at all, IIS throws the 405 exception before our filter begins processing.
Our code has worked before on several similar systems, so we suspect IIS/machine configuration on this specific server is responsible. What could be causing this?
The most commonly reported cause for a 405 error in a situation like this seems to be using Url.Rewrite. (The HTTP verb POST used to access path '/test.html' is not allowed) However, we are never using a Url.Rewrite.
Another commonly reported cause is trailing slashes in the request URL. (HTTP 405 on Error on HTTP POST IIS ASP .NET) But as mentioned above, the URL being requested does not end with a slash.
The app pool is running .NET 4.0 in a Classic pipeline (jQuery AJAX post receives 405 error (HTTP verb POST not allowed)), but our code has run without issue on many other systems under a Classic app pool, so there would still have to be something unique to this server's configuration. Changing to Integrated pipeline breaks the application our code is filtering, so that's not a possible workaround anyway.

Turns out, it was a very obscure IIS bug:
http://support.microsoft.com/kb/980368
The ExtensionlessUrl handler (*.) was incorrectly getting involved with the request instead of just the WebServiceHandlerFactory (*.asmx) as expected. The workaround was:
Manually deleting the ExtensionlessUrl handler entries from the web application's handler mappings
Manually moving the ExtensionlessUrl handler entries under anything you actually expect to be hit
Adding a web.config entry under system.webServer/handlers to remove the ExtensionslessUrl handler as needed (we went with this option to make sure it got included with app demployment)
We had to burn a Microsoft support ticket on this one, since there's no way we would have figured this out in any reasonable timeframe. Hopefully this helps someone else.

Related

Persits ASPPDF ImportFromUrl ServerXMLHTTP Error: The request has timed out

We have a test website that uses Persits ASPPDF to build a PDF using the ImportFromUrl method. It works fine on our test domain, but when I use the same code on another domain (and crucially perhaps, a sub-domain) I get the "MSXML2::ServerXMLHTTP Error: The request has timed out." error.
This leads me to think its related to the problem outlined in
https://support.persits.com/show.asp?code=PS080709171
"the calling Active Server Page (ASP) should not send requests to an ASP in the same virtual directory or to another virtual directory in the same pool or process. This can result in poor performance due to thread starvation."
So perhaps the config of the two servers hosting the two sites (test and live) are different - and if so what would that be? - Or you can't run this method on a sub-domain? Any guidance out there please?
I've had the same issue for weeks and finally found out what the problem was. In my case, it was because I had set to True the options that allow the debug of classic ASP code, without which I could not debug using visual studio. Setting those options back to False fixed the issue.

Asp.net Core 2.0 always receives 404 once deployed

I have an ASP.Net Core API that works great while running in Visual Studio. I am able to perform all actions successfully. However, now that I have deployed it to a Win 2008 R2 server, using IIS as reverse proxy, no page resolves. I always get a 404 page not found error. Actually, if I add a default get method returning value array, like what is provided by default when creating a new controller, it always returns. I do not understand what the issue is.
With the given information, I suspect only one thing, is that your server is not allowing HTTP Methods, or at least the OPTIONS one(for the preflight request).
To remediate to that, check out the UrlScan.ini config file in your server located at the below path:
C:\Windows\System32\inetsrv\urlscan
Open the file, and go to [AllowVerbs] section, it should be as the following(Add OPTIONS if it's not there):
[AllowVerbs]
;
; The verbs (aka HTTP methods) listed here are those commonly
; processed by a typical IIS server.
;
; Note that these entries are effective if "UseAllowVerbs=1"
; is set in the [Options] section above.
;
GET
HEAD
POST
OPTIONS
Hope you'll find this useful

Can't disable WSGIErrorOverride

I am backing a web app with a Flask API that returns custom error codes. The API runs through Apache and the WSGI module, in daemon mode.
I included a WSGIErrorOverride Off instruction in the Apache conf file for the API (which is supposed to be the default but I included it anyway).
Yet anytime my Flask app returns a custom error code (they work when I run the app using the built-in server), Apache sends an error 500. How can I prevent that?
Thanks to comments by duskwuff and Graham Dumpleton, I found that the problem doesn't come from Apache WSGI but from my Flask app.
More precisely, I was using the Flask-RESTful package, which is in charge, among other things, of transforming my views' return values into actual responses.
When those views are decorated (here with an equivalent of #login_required), those decorators are called by the Flask-RESTful package itself, and when an exception is thrown, something goes wrong.
For some reason, my app returns the custom error when I run the built-in server and an error 500 when I run it over Apache. Not quite sure why yet, I'm guessing Flask-RESTful is doing something that is not WSGI-compliant. I was on the verge of dropping it anyway for other reasons, so I'm OK with this solution.
Update: it looks like the problem does indeed come from Flask-RESTful: https://github.com/flask-restful/flask-restful/issues/372

Apache custom dynamic error response

I've seen hundreds of pages explaining how to create custom error pages in Apache 2 server. My question is different. I have a web application running in Apache (it is a ISAPI DLL, but it could also be a CGI executable). My application can handle internal server errors and generate a detailed error message (for instance, include a full stack trace), included in the response together with error code 500. AFAIK, Apache just let me use redirection in order to display custom error messages: http://httpd.apache.org/docs/2.2/custom-error.html
HTTP spec (RFC 2616 - section 10), not only allows but also recommend that detailed error message should be included in the BODY section of the response in case of error code > 500.
Link: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5
Seems that Apache won't let my custom error message go to the browser, and always replace it with its own internal error message and I believe that it is not the correct behavior, based on RFC 2616.
So my question is: Is there any setting in Apache server that will let my custom message go to the browser? Or, is there anything that can be done in my application that will instruct Apache to send my custom error message (something like some specific header field in the response)?
More on the subject:
When my ISAPI application returns error code 500, with other error information in the response body, Apache replaces it with its standard "500 Internal Server Error" message/HTML content, and inside Error.log file I can see the "useless" "Premature end of script headers" message. I'm deeply sure that my headers are fine, including the Content-Type field.
If I replace the 500 error code with any other server error code (e.g. 501) it works flawlessly and my response goes to the browser as is. The same header is sent to the Apache server, only the error code is different (501, instead of 500). With this test result in mind, one of these two must be true:
1- Apache requires some specific header field when status code is 500
2- Apache won't let custom error messages with status code 500 go to the browser.
I don't see any other alternative.
I think you're conflating two questions. You can generate a 500 response with a CGI script and include your custom body. Or you can override any 500 with any resource you want.
If you're failing to do the former, it's likely because of some subtle thing in the ISAPI interface between Apache and your module. Desk-checking the code says you should be able either set the pseudo
Status: 500
Header, or basically return any ISAPI error and end up with a 500 and your custom body.
Apache has two notions of a status code -- the one in the status line (r->status) and an error code returned separately from the module that handles the request (return HTTP_INTERNAL_SERVER_ERROR, return r->status).
When the former is used as the latter is when the custom error messages get lost. All of that happens in./modules/arch/win32/mod_isapi.c in Apache. Whatever is going on, it is ISAPI unique.

Custom JSON IErrorHandler in WCF returning StatusCode 200/504 when should return 400

I have a WCF service that among other bindings also uses WebHttpBinding for JSON inputs/results.
I made a custom IErrorHandler implementation in order to be able to set the StatusCode to 400 when something goes wrong and also return a JSON understandable message. It´s the straight implementation that you can find everywhere (nice way described here).
My problem is: when I test it locally using Visual Studio Web Development Server (Cassini) it works perfectly. However, when I deploy it to my test server (Windows 2008 with standard config for IIS and everything else) it does not work.
When I call it and debug with Firebug I get a HttpStatusCode 200 as a return and no response text. With Fiddler I get a HttpStatusCode 504 and no return at all. However, the behavior I expected (and what happens locally) is a call to the error callback of the ajax call with the responseText set.
I debugged it remotely and everything looks just fine. The execution pipeline is OK and all the classes are called as they should be just like they are locally, except it does not work.
Any suggestions? I´m pretty much out of options here to figure this out.
Thanks a lot!
if firebug and fiddler are giving different results, what happens if you telnet to it directly and perform a request (Something like:)
GET /VirtualDirectoryAndGetData HTTP/1.1
HOST: example.com
[carriage return]
It wouldn't surprise me if you're somehow getting odd headers/formatting back (to explain why firebug/fiddler disagree)
Another thing to test would be publishing to your dev machine to see if it's a machine-specific issue or a server vs dev webserver issue.
If it's happening anywhere outside VS, you might also try commenting out the lines where you set
rmp.StatusCode = System.Net.HttpStatusCode.BadRequest;
rmp.StatusDescription = "Bad request";
This may indicate whether it's a response code issue or an error handler issue.
If you can edit your question to include the results (with sensitive info removed), we'll see if we can track it down further.
Edit: after looking at the question again, it may well be that the server is erroring before it can send ANY response. FF might assume 200 by default, whereas ie might assume 504 (Gateway Timeout). This is total speculation but is possible. Do you see anything in the event logs?
I had a similar issue which I was able to solve. Take a look at the IIS settings. Details on how I overcame the issue are in this post: IErrorHandler returning wrong message body when HTTP status code is 401 Unauthorized