tel8618217223380 / prado3

Automatically exported from code.google.com/p/prado3
Other
0 stars 0 forks source link

THttpResponse::setStatusCode() has no effect #177

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Create a Prado application with a single page
2. Try to set response status code while serving up the page
3. Run the application requesting the page constructed above

What is the expected output? What do you see instead?
Prado should serve up the status code and text supplied to the 
THttpResponse::setStatusCode() call in the first row of the HTTP header 
returned to the client (browser). However, this is not the case, and an 
empty page with status code 200 (OK) is served up, no matter what. No 
warnings or errors are emitted whatsoever.

What version of the product are you using? On what operating system?
Prado/3.1.5, Apache 2.2.11

Please provide any additional information below.
It doesn't really matter where you try to set the status code. Placing 
THttpResponse::setStatusCode() into the page's OnInit(), OnPreRender() or 
render() method all have the same effect: none, at least in regard of the 
HTTP response header generated, as that will stay 200 - OK, no matter what.

Original issue reported on code.google.com by google...@pcforum.hu on 16 Jun 2009 at 4:31

Attachments:

GoogleCodeExporter commented 9 years ago
All steps of application lifecycle invoked in a loop - the only exception is 
the last
step "onEndRequest" which invoked manualy to ensure logging functionality.

Your describe behavior is no bug - by invoking "completeRequest" you terminate
processing application lifecycles.
Since "flushOutput" (send header & content) is the penultimate step of 
application
lifecycles (last step in the loop) it is impossible to consider your http 
statuscode.

Solution I:
----------------------------------------------
$this->getResponse()->setStatusCode(404,'Document not found');
$this->getResponse()->flush();
echo 'Your "Not Found" Message goes here';
$this->getApplication()->completeRequest();

Solution II:
----------------------------------------------
throw new THttpException(404, 'Your "Not Found" Message goes here');

Solution II offers some opportunities to to customize error page:

1. Customize exceptions templates
----------------------------------------------
copy templates located in:
 "${pradodir}/framework/Exceptions/templates"

into:
"${yourapplicationdir}/protected/ErrorTemplates"

modify your application config:
<module id="error" class="System.Exceptions.TErrorHandler"
ErrorTemplatePath="Application.ErrorTemplates"/>

now you can customize your error pages

2. Customize ErrorHandler
----------------------------------------------
class YourApplicationErrorHandler extends TErrorHandler {

protected function displayException($exception) {
    if( <Your custom exception handling condition> ) {
        <Your custom exception handling rendering>
    }
    else
        parent::displayException($exception);
}

Original comment by GODZilla...@gmail.com on 27 Jun 2009 at 6:53

GoogleCodeExporter commented 9 years ago
Thanks for the reply.

I indeed have tried your first solution - but it didn't work for me. Now I 
realize 
it just appeared not to work, because I tested it with IE, and for some weird 
reason 
MS modified IE8 in a way, that if it gets a HTTP error from the server (or 
can't 
even contant the server in the first place) for a page that it's already 
displaying, 
and you just pressed page refresh (F5) for, then it will keep displaying the 
old 
page, instead of showing the well known error-page. I'm not sure whether this 
is by 
design or just a bug, but IE8 definitively works that way - I've stumbled 
accross 
that behaviour multiple times.

Anyway, I think the Prado documentation should be modified or extended to 
contain 
more information about how to use THTTPResponse::setStatusCode() (for ex. a 
Wiki 
entry could be created by pasting your reply :), as the need of returning a 
custom 
error is a fairly common situation in web applications. However, currently the 
documentation only references setStatusCode() at two places: 1. in the topic 
dicussing the THTTPResponse class and its methods, but it doesn't state 
anything 
about it there beyond the obvious, and 2. in the Wiki entry about database 
based 
authentication, but there you can only see the ::completeRequest() call right 
after ::setStatusCode() - no THttpResponse::flush() anywhere, so somebody 
looking 
how to return a custom code will be only foiled by that, but he will be unable 
to 
find any information on how to do that properly in the documentation.

Original comment by google...@pcforum.hu on 27 Jun 2009 at 4:15