[SOLVED] fpWeb Default Action lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- jamhitz · 2012-05-14 12:00 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 ---------------------------------------------------------------------- jamhitz · 2012-05-15 19:33 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('
Program Authored by JamHitz
' ); Handled := true; end; procedure TwmMain.dateRequest(Sender: TObject; ARequest: TRequest; AResponse: TResponse; var Handled: Boolean); begin AResponse.Content := 'The current time: ' + FormatDateTime('dd mmm yyyy hh:nn:ss',Now()) + '
'; Handled := true; end; procedure TwmMain.defaultRequest(Sender: TObject; ARequest: TRequest; AResponse: TResponse; var Handled: Boolean); begin AResponse.Content := 'Random number: ' + FloatToStr(Random(900)) + '
' ); 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 · 2012-06-05 00:46 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 := 'The current time: ' + FormatDateTime('dd mmm yyyy hh:nn:ss',Now()) + '
'; 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('Program Authored by TeraGLEAN, LLC
' ); Handled := true; end; initialization RegisterHTTPModule('Main', TMain); end. ---------------------------------------------------------------------- BigChimp · 2013-02-09 15:42 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('To do: add list scans stuff here.
'); Handled:=true; end; procedure TFPWebModule1.unsupportedRequest(Sender: TObject; ARequest: TRequest; AResponse: TResponse; var Handled: Boolean); begin AResponse.Contents.Add('Unsupported method.
' ); 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.