Recent

Author Topic: [SOLVED] fpWeb Default Action  (Read 8574 times)

jamhitz

  • Jr. Member
  • **
  • Posts: 83
[SOLVED] fpWeb Default Action
« on: May 14, 2012, 02:00:57 pm »
Dear All

I have an CGI application with one module and three actions:
  time: TAction; //returns current system time
  echo: TAcion; //echos back whatever QueryFields are input
  notfound: TAction; // shows a "Resource not found" message

I am able to access the  individual actions:
   http://localhost/cgi-bin/tut01/time
   http://localhost/cgi-bin/tut01/echo
   http://localhost/cgi-bin/tut01/notfound

However, If I specify a non-existent action eg:    http://localhost/cgi-bin/tut01/timenow, the app fails with a "No action name and no default action" error; followed by a Stack Trace.

I have tried this:
Code: [Select]
Application.RedirectOnError := true;
Application.RedirectOnErrorURL := 'http://localhost/cgi-bin/tut01.exe/notfound';

...and nothing seems to happen. I've also tried this:
Code: [Select]
procedure TfpMain.DataModuleGetAction(Sender: TObject; ARequest: TRequest; var ActionName: String);
begin
     if Actions.FindAction(ActionName) = nil then
          ActionName := 'notfound';
end;

...but then the "notfound" becomes the "only" action and is returned irrespective of the specified action.

How can I define a "catch-all" action that is executed if and when the specified action is unavailable?

Thank you
« Last Edit: May 15, 2012, 09:38:09 pm by jamhitz »

jamhitz

  • Jr. Member
  • **
  • Posts: 83
Re: fpWeb Default Action
« Reply #1 on: May 15, 2012, 09:33:30 pm »
Well.... I must have  been too tired, because I went back to the drawing board and re-did everything from scratch. This is how I went about it (some kind of mini-tutorial if you may):

a) New CGI Application
b) Rename FPWebModule1 to wmMain (class automatically changes to TwmMain)
c) In the initialization code of Unit1, register module with a simpler name  -from:
   
Code: [Select]
RegisterHTTPModule('TFPWebModule1', TwmMain);   
   ..to:
   
Code: [Select]
RegisterHTTPModule('main', TwmMain);   
d) Project -> View Source: Change the name of the application:
   
Code: [Select]
Application.Title:='CGI Sample 01';   
e) Save Unit1 as uMain.pas, project as sample01.lpr
f) Go to TwmMain: Object Inspector and add four Actions named: 'date', 'number', 'author' and 'default'
g) For each action, program the OnRequest event handler, so the entire module looks like so:

Code: [Select]
procedure TwmMain.authorRequest(Sender: TObject; ARequest: TRequest;
    AResponse: TResponse; var Handled: Boolean);
begin
    AResponse.Contents.Add('<h1>Author</h1>');
    AResponse.Contents.Add('<p>Program Authored by JamHitz</p>' );
    Handled := true;
end;

procedure TwmMain.dateRequest(Sender: TObject; ARequest: TRequest;
    AResponse: TResponse; var Handled: Boolean);
begin
    AResponse.Content := '<h1>Date</h1><p>The current time: ' + FormatDateTime('dd mmm yyyy hh:nn:ss',Now()) + '</p>';
    Handled := true;
end;

procedure TwmMain.defaultRequest(Sender: TObject; ARequest: TRequest;
    AResponse: TResponse; var Handled: Boolean);
begin
    AResponse.Content := '<h1>Default Event</h1>';
    Handled := true;
end;

procedure TwmMain.numberRequest(Sender: TObject; ARequest: TRequest;
    AResponse: TResponse; var Handled: Boolean);
begin
    Randomize;
    AResponse.Contents.Add('<h1>Number</h1>');
    AResponse.Contents.Add('<p>Random number: ' +  FloatToStr(Random(900)) + '</p>' );
    Handled := true;
end;

initialization
  RegisterHTTPModule('main', TwmMain);
end.

h) Build program and copy to your cgi-bin directory (or as per your server configuration). Try to access the resource and notice that these raise an error "Invalid action name and no default action":

http://127.0.0.1/cgi-bin/sample01.exe
http://127.0.0.1/cgi-bin/sample01.exe/main

Any of the following work as expected:

http://127.0.0.1/cgi-bin/sample01.exe/date
http://127.0.0.1/cgi-bin/sample01.exe/main/date
http://127.0.0.1/cgi-bin/sample01.exe/number
http://127.0.0.1/cgi-bin/sample01.exe/main/number
http://127.0.0.1/cgi-bin/sample01.exe/author
http://127.0.0.1/cgi-bin/sample01.exe/main/author
http://127.0.0.1/cgi-bin/sample01.exe/default
http://127.0.0.1/cgi-bin/sample01.exe/main/default

i) Now I go back to TwmMain, click on the action named "default", In the Object Inspector set Default := false. Now you can access the "default action" url using the first two methods.

So far, so good. How about if we give a name of an action that does not exist:

http://127.0.0.1/cgi-bin/sample01.exe/main/nothere

...this still returns the default action as expected. Mission complete!!

IPguy

  • Sr. Member
  • ****
  • Posts: 385
Re: [SOLVED] fpWeb Default Action
« Reply #2 on: June 05, 2012, 02:46:46 am »
I'm mimicing what jamhitz did for cgi with the "HTTP Server Application" type of project.

To the tMain object, I added three actions (Date, Author, Default) and created an "OnRequest" for each of the three actions.

To access them:
localhost:8081  -> default action
localhost:8081/Default  -> default action
localhost:8081/Author  -> author page
localhost:8081/Date  ->  date page

jamhitz - thanks for the hints and direction.

Next: create a default page with menus and / or buttons and to link those to the actions.

Code: [Select]
unit PARMain;

// localhost:8081

{$mode objfpc}{$H+}

interface

uses
  SysUtils, Classes, Menus, httpdefs, fpHTTP, fpWeb, Interfaces;

type

  { TMain }

  TMain = class(TFPWebModule)
    MenuItem1: TMenuItem;
    mAdmin: TMenuItem;
    procedure AuthorRequest(Sender: TObject; ARequest: TRequest;
      AResponse: TResponse; var Handled: Boolean);
    procedure DateRequest(Sender: TObject; ARequest: TRequest;
      AResponse: TResponse; var Handled: Boolean);
    procedure DefaultRequest(Sender: TObject; ARequest: TRequest;
      AResponse: TResponse; var Handled: Boolean);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Main: TMain;

implementation

{$R *.lfm}

{ TMain }

procedure TMain.DateRequest(Sender: TObject; ARequest: TRequest;
  AResponse: TResponse; var Handled: Boolean);
begin
  AResponse.Content := '<h1>Date</h1><p>The current time: '
                       + FormatDateTime('dd mmm yyyy hh:nn:ss',Now()) + '</p>';
  Handled := true;
end;

procedure TMain.DefaultRequest(Sender: TObject; ARequest: TRequest;
  AResponse: TResponse; var Handled: Boolean);
begin
  AResponse.ContentType := 'text/html;charset=utf-8';
  AResponse.Contents.LoadFromFile('Main.html');
  Handled := True;
end;

procedure TMain.AuthorRequest(Sender: TObject; ARequest: TRequest;
  AResponse: TResponse; var Handled: Boolean);
begin
    AResponse.Contents.Add('<h1>Author</h1>');
    AResponse.Contents.Add('<p>Program Authored by TeraGLEAN, LLC</p>' );
    Handled := true;
end;

initialization
  RegisterHTTPModule('Main', TMain);
end.
                         
             

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: [SOLVED] fpWeb Default Action
« Reply #3 on: February 09, 2013, 04:42:13 pm »
Strange. Looking through old posts for info on fpweb, I found this one.

As opposed to the others, I didn't seem to have any problems: use default fpweb cgi, FPC 2.6.0, Linux, 2 actions, one set to default (called unsupported), 2 handlers... this seems to work and catch both non-existing URL actions as well as existing ones.

Code: [Select]
unit tigercgimain;

{$i tigerserver.inc}

interface

uses
  SysUtils, Classes, httpdefs, fpHTTP, fpWeb,
  tigerservercore;

type

  { TFPWebModule1 }

  TFPWebModule1 = class(TFPWebModule)
    procedure listRequest(Sender: TObject; ARequest: TRequest;
      AResponse: TResponse; var Handled: Boolean);
    procedure unsupportedRequest(Sender: TObject; ARequest: TRequest;
      AResponse: TResponse; var Handled: Boolean);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  FPWebModule1: TFPWebModule1;

implementation

{$R *.lfm}

{ TFPWebModule1 }

procedure TFPWebModule1.listRequest(Sender: TObject; ARequest: TRequest;
  AResponse: TResponse; var Handled: Boolean);
begin
  AResponse.Contents.Add('<p>To do: add list scans stuff here.</p>');
  Handled:=true;
end;

procedure TFPWebModule1.unsupportedRequest(Sender: TObject; ARequest: TRequest;
  AResponse: TResponse; var Handled: Boolean);
begin
  AResponse.Contents.Add('<p>Unsupported method.</p>' );
  Handled := true;
end;

initialization
  RegisterHTTPModule('TFPWebModule1', TFPWebModule1);
end.

Any comments?

I've updated the wiki http://wiki.lazarus.freepascal.org/fcl-web#Notes; corrections welcome as always.
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

 

TinyPortal © 2005-2018