#1 2016-02-23 13:14:39

fabioxgn
Member
Registered: 2015-11-06
Posts: 34

CurrentServiceContext.Request.Redirect not working, gets overwritten

I'm trying to make a method which will redirect, and the result status and headers are overriden after checking if the Answer is TServiceCustomAnswer.

My method just returns a string (also tested with a procedure) and I'm redirecting using the following code:

CurrentServiceContext.Request.Redirect(URL);

But in this point, the Status code and OutHead are overriden:

        if exec.ExecuteJson([instancePtr],Ctxt.ServiceParameters,WR,Ctxt.ForceServiceResultAsJSONObject) then begin
          Ctxt.Call.OutHead := exec.ServiceCustomAnswerHead;
          Ctxt.Call.OutStatus := exec.ServiceCustomAnswerStatus;
        end else begin

At this point Ctxt.Call.OutHead and Ctxt.Call.OutStatus are correct but it gets set to empty string as the ServiceCustomAnswer stuff is blank.

Also, it would be nice to specify the HTTP Status code in the Redirect method, instead of Permanent True/False, I'd like to use 302 (Found).

Is this a bug or am I doing something wrong?

Last edited by fabioxgn (2016-02-23 13:15:42)

Offline

#2 2016-02-23 13:37:50

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,207
Website

Re: CurrentServiceContext.Request.Redirect not working, gets overwritten

This is not how it works.
You can't use CurrentServiceContext to change the execution at runtime, like this.

Interface-based services are NOT meant to support all HTTP details.
They are made to implement client/server SOA process.

If you use an interface-based service, and expect HTTP level customization of the returned content, define your method to return a TServiceCustomAnswer record.
Then just put the HTTP header redirection to the TServiceCustomAnswer.Header result of your method.
And it will work as expected.

If you want to have full control of the returned content, use a method-based service.
Then do not use CurrentServiceContext, but directly the Ctxt parameter of the implementation.

Offline

#3 2016-02-23 13:49:23

fabioxgn
Member
Registered: 2015-11-06
Posts: 34

Re: CurrentServiceContext.Request.Redirect not working, gets overwritten

ab wrote:

This is not how it works.
You can't use CurrentServiceContext to change the execution at runtime, like this.

Interface-based services are NOT meant to support all HTTP details.
They are made to implement client/server SOA process.

If you use an interface-based service, and expect HTTP level customization of the returned content, define your method to return a TServiceCustomAnswer record.
Then just put the HTTP header redirection to the TServiceCustomAnswer.Header result of your method.
And it will work as expected.

If you want to have full control of the returned content, use a method-based service.
Then do not use CurrentServiceContext, but directly the Ctxt parameter of the implementation.

Didn't know that, thanks.

Offline

#4 2016-06-24 04:46:18

Eugene Ilyin
Member
From: milky_way/orion_arm/sun/earth
Registered: 2016-03-27
Posts: 132
Website

Re: CurrentServiceContext.Request.Redirect not working, gets overwritten

Hi @ab,

Following standard login/logout web app techniques, I need to extend TMVCRendererAbstract.ExecuteCommand as such:

mORMotMVC.pas (1413)

procedure TMVCRendererAbstract.ExecuteCommand(aMethodIndex: integer);

----- old code -------------------------

        if (action.ReturnedStatus=HTML_TEMPORARYREDIRECT) or
           (action.ReturnedStatus=HTML_MOVEDPERMANENTLY) then

----- new code -------------------------

        if (action.ReturnedStatus=HTML_TEMPORARYREDIRECT) or
           (action.ReturnedStatus=HTML_FOUND) or
           (action.ReturnedStatus=HTML_SEEOTHER) or
           (action.ReturnedStatus=HTML_MOVEDPERMANENTLY) then

This is required to handle 302 or 303 POST requests provided by forms redirect to GET methods after login/logout process. POST to GET replacement is done by browsers automatically. Current 307 response code do not replace POST to GET on user agent side (as it required by 303 code).

For example in your 30 - MVC Server sample: if I press Ctrl+F5 after successful login the browser will show popup message with POST repeat. But if we will answer 302 (or more correct 303) on TBlogApplication.Login interface event then browser will replace POST to GET under the hood and all page refreshes after login will not impact the user.

Btw, why did you name HTTP status codes with HTML prefix? Isn't it an abstraction leak (low level HTTP response codes named with high level non-existing HTML_* prefixes)?

Offline

Board footer

Powered by FluxBB