Recent

Author Topic: Redirecting to another action  (Read 2916 times)

egsuh

  • Hero Member
  • *****
  • Posts: 1292
Redirecting to another action
« on: April 21, 2020, 02:21:00 pm »
Is it possible to redirect to another action within fpweb web module?

e.g.  I'd like to do,


Code: Pascal  [Select][+][-]
  1. procedure TwmDC1.DoSomethingRequest(Sender: TObject; ARequest: TRequest;
  2.     AResponse: TResponse; var Handled: Boolean);
  3. begin
  4.         // do something
  5.         AResponse.SendRedirect ('Respond');   // <-- Here, I want to redirect to another action, not url.
  6. end;
  7.  
  8.  
  9. procedure TwmDC1.RespondRequest(Sender: TObject; ARequest: TRequest;
  10.    AResponse: TResponse; var Handled: Boolean);
  11. begin
  12.   AResponse.Content := OutTemplate.GetContent;
  13.   Handled := True;
  14. end;
  15.  

Of course I can write
Code: Pascal  [Select][+][-]
  1.   RespondRequest(Sender, ARequest,  AResponse, Handled);
  instead of AResponse.SendRedirect.
« Last Edit: April 21, 2020, 02:22:54 pm by egsuh »

alantelles

  • New Member
  • *
  • Posts: 21
Re: Redirecting to another action
« Reply #1 on: April 23, 2020, 06:55:39 pm »
I guess you already answered.  :D
# compulsive coder
FPC 3.2.0, Lazarus 2.0.10

devEric69

  • Hero Member
  • *****
  • Posts: 648
Re: Redirecting to another action
« Reply #2 on: May 29, 2020, 10:17:20 am »
Is it possible to redirect to another action within fpweb web module?

Code: Pascal  [Select][+][-]
  1. procedure TwmDC1.RespondRequest(Sender: TObject; ARequest: TRequest;
  2.    AResponse: TResponse; var Handled: Boolean);
  3. begin
  4.   AResponse.Content := OutTemplate.GetContent;
  5.   Handled := True;
  6. end;
  7.  

Of course I can write
Code: Pascal  [Select][+][-]
  1.   RespondRequest(Sender, ARequest,  AResponse, Handled);
  instead of AResponse.SendRedirect.

Thanks for the tip.
For information, if the called RespondRequest is coded without calling ModuleTemplate.GetContent (ModuleTemplate.GetContent = request to parse the HTML file, and eventually replace its " transparent tags ", in the @viewXyz_onReplaceTag event), but rather by affecting directly the Content of AResponse, then we must call AResponse.SendContent in order to avoid returning into the calling onRequest. For example:


Code: Pascal  [Select][+][-]
  1. procedure Tgo_uiCtrlFoo.uiActDoThis_onRequest(Sender: TObject; ARequest: TRequest; AResponse: TResponse; var Handled: Boolean);
  2. begin
  3.     Handled:= true;  
  4.     if something_is_not_ok then
  5.        uiAct403Forbidden_onRequest(Sender, ARequest, AResponse, Handled);
  6.  
  7.    // if *only* something is ok, then i continue
  8.    ...\...
  9.  
  10. end;  
  11.    
  12.  
  13. procedure Tgo_uiCtrlFoo.uiAct403Forbidden_onRequest(Sender: TObject; ARequest: TRequest; AResponse: TResponse; var Handled: Boolean);
  14. begin
  15.   Handled:= True;
  16.   with AResponse do begin
  17.     Code:= 403;
  18.     CodeText:= 'Forbidden';
  19.     Content:= '<HTML>'+
  20.                      '<HEAD>'+
  21.                      '<META CONTENT="text/html; charset=UTF-8" http-equiv="content-type">'+
  22.                      '<TITLE>Forbidden</TITLE>'+
  23.                      '</HEAD>'+
  24.                      '<BODY>'+
  25.                      '<P><B>403</B>: URL forbidden.</P>'+
  26.                      '</BODY>'+
  27.                      '</HTML>';
  28.     Session.Terminate; // Here, I want too, to clear the "Pascal_SESSION" i.e. Self.Session
  29.     SendContent; //|--◉ I do not want to return into the caller (i.e. into uiActDoThis_onRequest)!
  30.   end;    
  31. end;
« Last Edit: June 08, 2020, 02:32:19 pm by devEric69 »
use: Linux 64 bits (Ubuntu 20.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.

egsuh

  • Hero Member
  • *****
  • Posts: 1292
Re: Redirecting to another action
« Reply #3 on: June 07, 2020, 09:27:05 am »
@devEric69

Thank you for your advice.

I was not sure of the role of "SendResponse", but your explanation makes it clear. I'll test this myself.

BTW, this is little bit weired that in Delphi, setting "Handled :- true" stops all following operations as far as I know. But in Lazarus, it does not. It's quite long ago when I wrote Delphi codes, so I do not want to check this again.

Have you ever running FastCGI server? If you have much experience, please share it with me. My CGI server runs well, but fCGI seems to lag sometimes, so that the web-server sends errors, and resume after a few minutes.

devEric69

  • Hero Member
  • *****
  • Posts: 648
Re: Redirecting to another action
« Reply #4 on: June 08, 2020, 02:29:16 pm »
Quote
BTW, this is little bit weired that in Delphi, setting "Handled :- true" stops all following operations as far as I know. But in Lazarus, it does not. It's quite long ago when I wrote Delphi codes, so I do not want to check this again.

Hi,

Thank you @egsuh.

I think like you. But don't have the precise explanation.
The only thing I'm sure with the affectation "Handled:= true\false", is that when Handled == false, whereas the code is coming back again in the calling TWebAction that answers first because it was corresponding to the PATHINFO environment variable, or whereas it goes away i.e. it "shunts" its calling TWebAction because it meets SendContent; (Redirect; too, I guess???), then the HTML code sent back toward the browser is always empty, even if AResponse.Content has been affected.

I, too, have read many examples that start mechanically with the line "Handled:= true;". And I have also reproduced it mechanically ("Monkey see, Monkey do"). I guess it's didactic. It's to prevent people like me from spending a whole day coding ... an empty answer in the browser :) .

So, the example above, should be:
Code: Pascal  [Select][+][-]
  1. procedure Tgo_uiCtrlFoo.uiActDoThis_onRequest(Sender: TObject; ARequest: TRequest; AResponse: TResponse; var Handled: Boolean);
  2. begin  
  3.     if something_is_not_ok then
  4.        uiAct403Forbidden_onRequest(Sender, ARequest, AResponse, Handled);
  5.  
  6.    // if *only* something is ok, then i continue
  7.    Handled:= true; // <==(!!!) more logical here, after any possible "shunt" of the callstack.
  8.    ...\...
  9. end;  
  10.    
  11.  
  12. procedure Tgo_uiCtrlFoo.uiAct403Forbidden_onRequest(Sender: TObject; ARequest: TRequest; AResponse: TResponse; var Handled: Boolean);
  13. begin
  14.   Handled:= True;
  15.   with AResponse do begin
  16.     Code:= 403;
  17.     CodeText:= 'Forbidden';
  18.     Content:= '<HTML>'+
  19.                      '<HEAD>'+
  20.                      '<META CONTENT="text/html; charset=UTF-8" http-equiv="content-type">'+
  21.                      '<TITLE>Forbidden</TITLE>'+
  22.                      '</HEAD>'+
  23.                      '<BODY>'+
  24.                      '<P><B>403</B>: URL forbidden.</P>'+
  25.                      '</BODY>'+
  26.                      '</HTML>';
  27.     Session.Terminate; // Here, I want too, to clear the "Pascal_SESSION" i.e. Self.Session
  28.     SendContent; //|--◉ I do not want to return into the caller (i.e. into uiActDoThis_onRequest)!
  29.   end;    
  30. end;
  31.  


Quote
Have you ever running FastCGI server? If you have much experience, please share it with me. My CGI server runs well, but fCGI seems to lag sometimes, so that the web-server sends errors, and resume after a few minutes.

No, sorry: I'm currently only writing a CGI application. If its loading in memory becomes problematic because there is too much traffic, then I'll can still migrate it to fast-CGI, before looking for other solutions.
« Last Edit: June 08, 2020, 02:45:34 pm by devEric69 »
use: Linux 64 bits (Ubuntu 20.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.

sash

  • Sr. Member
  • ****
  • Posts: 366
Re: Redirecting to another action
« Reply #5 on: June 08, 2020, 06:37:07 pm »
The problem is that you're using wrong terms.
In http, redirect is a response type "HTTP 302 Found" with new suggested url.
While you (seems like) want to respond with content from another action.
Lazarus 2.0.10 FPC 3.2.0 x86_64-linux-gtk2 @ Ubuntu 20.04 XFCE

egsuh

  • Hero Member
  • *****
  • Posts: 1292
Re: Redirecting to another action
« Reply #6 on: June 09, 2020, 06:04:10 am »

Code: Pascal  [Select][+][-]
  1. The problem is that you're using wrong terms.
  2. In http, redirect is a response type "HTTP 302 Found" with new suggested url.
  3. While you (seems like) want to respond with content from another action.

You are right in some sense. I can write full URL in the SendRedirect, like

Code: Pascal  [Select][+][-]
  1. AResponse.SendRedirect(ARequest.host + ARequest.SCript + 'mynextaction');
  2.  

But it looks like calling IIS (in Windows case) again, and I want to move to new action within my application. I've solved this issue by writing procedures, and passing AResponse as a parameter to the procedure. The content of AResponse is defined within the procedure.




Leledumbo

  • Hero Member
  • *****
  • Posts: 8757
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Redirecting to another action
« Reply #7 on: June 13, 2020, 09:04:49 pm »
You are right in some sense. I can write full URL in the SendRedirect, like
...
But it looks like calling IIS (in Windows case) again.
Because that's essentially what a HTTP redirect is ;)
Your app responds to the request (from browser) with a HTTP redirect status (301/302/307) and a Location header. The browser then interprets the HTTP status and issue another request to the URL specified in Location header, which of course will call your app again. A more proper term for what you actually mean is delegation, not redirect, as it may happen internally within a request handling, transparent from the browser.

 

TinyPortal © 2005-2018