Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2016-04

FastCGI on Windows IIS

17 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Marcos Douglas
to Marcos Douglas
Marcos Douglas wrote 14 lines
Hi, I'm trying to use FastCGI on IIS without success. https://www.iis.net/configreference/system.webserver/fastcgi My environment is: - FPC 2.6.5 - Lazarus 1.5 - IIS - Windows 10 The CGI protocol works fine, but FastCGI not. I got an error 500. If I change the fpFCGI to fpcgi — and comment the Application.Port — everything works fine.

I've found the problem:
The Application.Port cannot be setted.

I think this property (Port) is only used in a self-contained server application. Am I right?

Regards,
Marcos Douglas

Reply by email

Michael Van Canneyt
to Marcos Douglas
Marcos Douglas wrote 21 lines
On Sun, Apr 24, 2016 at 1:31 AM, Marcos Douglas wrote: > Hi, > > I'm trying to use FastCGI on IIS without success. > https://www.iis.net/configreference/system.webserver/fastcgi > > My environment is: > - FPC 2.6.5 > - Lazarus 1.5 > - IIS > - Windows 10 > > The CGI protocol works fine, but FastCGI not. I got an error 500. > If I change the fpFCGI to fpcgi — and comment the Application.Port — > everything works fine. I've found the problem: The Application.Port cannot be setted. I think this property (Port) is only used in a self-contained server application. Am I right?

You are right,

Michael.

Reply by email

Marcos Douglas
to Michael Van Canneyt
Michael Van Canneyt wrote 9 lines
> I've found the problem: > The Application.Port cannot be setted. > > I think this property (Port) is only used in a self-contained server > application. Am I right? You are right,

OK, thanks.

Now I have another problem only in fcl-web framework, I think.

I have one module:
ModuleName= 'pdf'
ModuleClass= TPDFModule

and two actions:
'act1'
'act2'

Browser:
http://localhost:2015/fcgitest/pdf/act1

Error:

The application encountered the following error:
Error: Could not determine HTTP module for request "fcgitest.exe" Stack trace:
$004328E3
$00433012
$004323E2

Reply by email

Michael Van Canneyt
to Marcos Douglas
Marcos Douglas wrote 31 lines
On Sun, Apr 24, 2016 at 2:40 AM, Michael Van Canneyt wrote: > >> I've found the problem: >> The Application.Port cannot be setted. >> >> I think this property (Port) is only used in a self-contained server >> application. Am I right? > > > You are right, OK, thanks. Now I have another problem only in fcl-web framework, I think. I have one module: ModuleName= 'pdf' ModuleClass= TPDFModule and two actions: 'act1' 'act2' Browser: http://localhost:2015/fcgitest/pdf/act1 Error: The application encountered the following error: Error: Could not determine HTTP module for request "fcgitest.exe"

Why do you put fcgitest in the request ?

Michael.

Reply by email

Marcos Douglas
to Michael Van Canneyt
Michael Van Canneyt wrote 10 lines
> Browser: > http://localhost:2015/fcgitest/pdf/act1 > > Error: > > The application encountered the following error: > Error: Could not determine HTTP module for request "fcgitest.exe" Why do you put fcgitest in the request ?

Sorry, I didn't understand what you mean. I need to put the executable name in the URL, like "mycgi.cgi" in these examples: http://wiki.freepascal.org/fcl-web

...and there is a typo (missing ".exe"). The 'correct' is: http://localhost:2015/fcgitest.exe/pdf/act1

...but it does not solve the problem. :(

Regards,
Marcos Douglas

Reply by email

Marcos Douglas
to Marcos Douglas
Marcos Douglas wrote 21 lines
On Sun, Apr 24, 2016 at 3:58 AM, Michael Van Canneyt wrote: >> Browser: >> http://localhost:2015/fcgitest/pdf/act1 >> >> Error: >> >> The application encountered the following error: >> Error: Could not determine HTTP module for request "fcgitest.exe" > > > Why do you put fcgitest in the request ? Sorry, I didn't understand what you mean. I need to put the executable name in the URL, like "mycgi.cgi" in these examples: http://wiki.freepascal.org/fcl-web ...and there is a typo (missing ".exe"). The 'correct' is: http://localhost:2015/fcgitest.exe/pdf/act1 ...but it does not solve the problem. :(

My env: Lazarus 1.5 r50201M FPC 2.6.5 i386-win32-win32/win64

So I took his example here \packages\fcl-web\examples\helloworld Compiled it. ISS configured to port 2020.
Call in browser http://localhost:2020/helloworld.exe/func1call

...and got the same error:

The application encountered the following error:

Error: Could not determine HTTP module for request "helloworld.exe" Stack trace:
$0042F823
$0042FF52
$0042F322
$00401775 main, line 13 of helloworld.lpr

Please, have you any ideas?

Best regards,
Marcos Douglas

Reply by email

Michael Van Canneyt
to Marcos Douglas
Marcos Douglas wrote 9 lines
> http://localhost:2015/fcgitest.exe/pdf/act1 > > ...but it does not solve the problem. :( My env: Lazarus 1.5 r50201M FPC 2.6.5 i386-win32-win32/win64 So I took his example here \packages\fcl-web\examples\helloworld Compiled it. ISS configured to port 2020. Call in browser http://localhost:2020/helloworld.exe/func1call

I have never tested the Fastcgi support with IIS.
The problem is probably that IIS does not provide the same PATHINFO environment variable as Apache or NGINX.

The PATHINFO environment variable is used to determine what module needs to be invoked. You can influence this by setting and handling the OnGetModule event of the TFastCGIApplication application object. In this event, you can examine the request, and return the class of the module that must be created.

When you do, please save the contents of PATHINFO to some file, and send it here, so I can examine it and adapt the implementation so it can handle IIS as well.

Michael.

Reply by email

Marcos Douglas
to Michael Van Canneyt
Michael Van Canneyt wrote 29 lines
On Sun, 24 Apr 2016, Marcos Douglas wrote: >> http://localhost:2015/fcgitest.exe/pdf/act1 >> >> ...but it does not solve the problem. :( > > > My env: Lazarus 1.5 r50201M FPC 2.6.5 i386-win32-win32/win64 > > So I took his example here \packages\fcl-web\examples\helloworld > Compiled it. ISS configured to port 2020. > Call in browser http://localhost:2020/helloworld.exe/func1call I have never tested the Fastcgi support with IIS. The problem is probably that IIS does not provide the same PATHINFO environment variable as Apache or NGINX. The PATHINFO environment variable is used to determine what module needs to be invoked. You can influence this by setting and handling the OnGetModule event of the TFastCGIApplication application object. In this event, you can examine the request, and return the class of the module that must be created. When you do, please save the contents of PATHINFO to some file, and send it here, so I can examine it and adapt the implementation so it can handle IIS as well.

Hi,

Doesn't matter if is CGI or FastCGI. Same problem.

I did more tests.
In my example, I have 1 Module "pdf" and 1 Action "act1".

The Module has a DataModuleRequest event:
begin
  AResponse.Content := 'default';
  Handled := True;
end;
The Action has a Request event:
begin
  AResponse.Content := 'list';
  Handled := True;
end;

#1 Call Action
URL: http://localhost:2015/fcgitest.exe/act1/
Result: error - Could not determine HTTP module for request "act1" Log:
PATHINFO=/fcgitest.exe/act1/
NEXT_PATHINFO=fcgitest.exe

#2 Call Module/Action
URL: http://localhost:2015/fcgitest.exe/pdf/act1/
Result: print - "default"
Log:
PATHINFO=/fcgitest.exe/pdf/act1/
NEXT_PATHINFO=fcgitest.exe

If you do not have time, maybe I can try to fix. But how we can know what Server is running (Apache, IIS, etc)?

Thanks,
Marcos Douglas

Reply by email

Michael Van Canneyt
to Marcos Douglas
Marcos Douglas wrote 30 lines
> > When you do, please save the contents of PATHINFO to some file, and send it > here, so I can examine it and adapt the implementation so it can handle IIS > as well. Hi, Doesn't matter if is CGI or FastCGI. Same problem. I did more tests. In my example, I have 1 Module "pdf" and 1 Action "act1". The Module has a DataModuleRequest event: begin AResponse.Content := 'default'; Handled := True; end; The Action has a Request event: begin AResponse.Content := 'list'; Handled := True; end; #1 Call Action URL: http://localhost:2015/fcgitest.exe/act1/ Result: error - Could not determine HTTP module for request "act1" Log: PATHINFO=/fcgitest.exe/act1/ NEXT_PATHINFO=fcgitest.exe

You always need to specify 2 paths:

http://localhost:2015/fcgitest.exe/pdf/act1/

Unless you have set a default module and name in the application:

  AllowDefaultModule:=True;
  DefaultModuleName:='pdf';
  PreferModuleName:=False;
Show quoted text 7 lines
#2 Call Module/Action URL: http://localhost:2015/fcgitest.exe/pdf/act1/ Result: print - "default" Log: PATHINFO=/fcgitest.exe/pdf/act1/ NEXT_PATHINFO=fcgitest.exe

Yes, this is a normal response, it seems ?

Even so, PATHINFO should not contain /fcgitest.exe/. You can trust Microsoft to do things in an incompatible way :/

Michael.

Reply by email

Michael Schnell
to Marcos Douglas: I'm trying to use FastCGI on IIS without success.…

Not believing that FCGI will work decently with IIS, my colleagues successfully used a different approach to use their (Delphi) programs via IIS in the Internet.

They did a small ISAPI transfer DLL and did the business logic in a Windows Service They linked the two Delphi programs via RemOBJ.

I suppose using FPC and some propriety protocol for linking the DLL and the business logic will be doable.

-Michael

Reply by email

Marcos Douglas
to Michael Van Canneyt: You always need to specify 2 paths: http://localhost:2015/fcgitest.exe/pdf/act1/ Unless…
Michael Van Canneyt wrote 9 lines
You always need to specify 2 paths: http://localhost:2015/fcgitest.exe/pdf/act1/ Unless you have set a default module and name in the application: AllowDefaultModule:=True; DefaultModuleName:='pdf'; PreferModuleName:=False;

I've read emails on the list that you said that only if the program has more than one Module is necessary to specify two paths. But Ok, for me makes more sense to use 2 paths.

Show quoted text 9 lines
> #2 Call Module/Action > URL: http://localhost:2015/fcgitest.exe/pdf/act1/ > Result: print - "default" > Log: > PATHINFO=/fcgitest.exe/pdf/act1/ > NEXT_PATHINFO=fcgitest.exe Yes, this is a normal response, it seems ?

Well, I was thinking if an Action should have more priority to execute if I call it directly on URL — but I don't know if the 'Module request' was execute because of the bug on PATHINFO or because it has more priority.

Even so, PATHINFO should not contain /fcgitest.exe/. You can trust Microsoft to do things in an incompatible way :/

Yeah... :\
So do you will make a patch or doesn't have time in this week? Maybe I can try. Now I know there is a SERVER_SOFTWARE variable to test if is Windows IIS... but if you will fix just tell me, please.

I'm still using FPC 2.6.5 version. But I guess this package still works in this version so, do you think can I replace the fcl-web from 2.6.5 to use 3.0.0 version, after the changes?

Thanks,
Marcos Douglas

Reply by email

Michael Van Canneyt
to Marcos Douglas
Marcos Douglas wrote 11 lines
On Mon, Apr 25, 2016 at 3:57 AM, Michael Van Canneyt wrote: > > > Yes, this is a normal response, it seems ? Well, I was thinking if an Action should have more priority to execute if I call it directly on URL — but I don't know if the 'Module request' was execute because of the bug on PATHINFO or because it has more priority.

because of the bug on PATHINFO.

You can control the behaviour with the 'PreferModuleName' property. But that only works if there is a default module.

Show quoted text 8 lines
> Even so, PATHINFO should not contain /fcgitest.exe/. > You can trust Microsoft to do things in an incompatible way :/ Yeah... :\ So do you will make a patch or doesn't have time in this week? Maybe I can try. Now I know there is a SERVER_SOFTWARE variable to test if is Windows IIS... but if you will fix just tell me, please.

Well, time is of course an issue, but more importantly, I do not have ISS to test with.

I think that PATHINFO needs to be corrected in custcgi.pp:

Procedure TCGIRequest.InitFromEnvironment:
Something like
If Pos('IIS', ServerName)>0 then
   // Cut binary name from PathInfo

It will then also be fixed for FastCGI as it reuses this routine.

I'm still using FPC 2.6.5 version. But I guess this package still works in this version so, do you think can I replace the fcl-web from 2.6.5 to use 3.0.0 version, after the changes?

It should not be a problem.

Michael.

Reply by email

Marcos Douglas
to Michael Van Canneyt: because of the bug on PATHINFO. You can control the behaviour with the 'PreferModuleName'…
Michael Van Canneyt wrote 11 lines
Well, time is of course an issue, but more importantly, I do not have ISS to test with. I think that PATHINFO needs to be corrected in custcgi.pp: Procedure TCGIRequest.InitFromEnvironment: Something like If Pos('IIS', ServerName)>0 then // Cut binary name from PathInfo It will then also be fixed for FastCGI as it reuses this routine.

I'll work on that. Thanks.

Regards,
Marcos Douglas

Reply by email

Marcos Douglas
to Marcos Douglas
Marcos Douglas wrote 13 lines
On Tue, Apr 26, 2016 at 3:39 AM, Michael Van Canneyt wrote: > Well, time is of course an issue, but more importantly, I do not have ISS to > test with. > > I think that PATHINFO needs to be corrected in custcgi.pp: > > Procedure TCGIRequest.InitFromEnvironment: > > Something like If Pos('IIS', ServerName)>0 then > // Cut binary name from PathInfo > > It will then also be fixed for FastCGI as it reuses this routine.

Hi Michael,

Using the original sources of version 2.6.5 I can get the SERVER_SOFTWARE=Microsoft-IIS/10.0

So, I replaced the fcl-web package, version 2.6.5 to use 3.1.1. But in this last version SERVER_SOFTWARE is empty. I don't know why.

Look the code below.

===BEGIN===
procedure TCGIRequest.InitFromEnvironment;
Var
  I : Integer;
  R,V,OV : String;
  M : TMap;
begin
  For I:=1 to CGIVarCount do
    begin
    V:=GetEnvironmentVariable(CGIVarNames[I]);
    if (V'') then
      begin
      M:=MapCgiToHTTP[i];
      if M.HhhUnknown then
        SetHeader(M.H,HTTPDecode(V))
      else if M.VhvUnknown then
        begin
        if M.VhvQuery then
          V:=HTTPDecode(V);
        SetHTTPVariable(M.V,V)
        end;
      end;
    end;
//---------------------
  if Pos('IIS', ServerSoftware) > 0 then
    PathInfo := StringReplace(PathInfo, ScriptName, '', []);
//---------------------
  R:=UpCase(Method);
  if (R='POST') or (R='PUT') or (ContentLength>0) then
    ReadContent;
end;

===END===

Only these lines are new:
  if Pos('IIS', ServerSoftware) > 0 then
    PathInfo := StringReplace(PathInfo, ScriptName, '', []);

Nothing happens, because ServerSoftware is empty.
If I comment the first line, the PathInfo will be fixed but I got this error: "Could not determine HTTP module for request "list""

Consider this:
1- PathInfo and ScriptName are properties of THTTPHeader class 2- ServerSoftware is a property of TCGIRequest

So, on this version you check: M.HhhUnknown or M.VhvUnknown, then I'd tryed to implement:

[unit custcgi, line 166, const MapCgiToHTTP]
{ 17: 'SERVER_SOFTWARE' } (h:hhUnknown; v : hvServerSoftware),

...and added in httpdefs.THTTPVariableType too

...and I'd implemented this property too:
THTTPReader
    Property ServerSoftware : String Index Ord(hvServerSoftware) read
GetHTTPVariable Write SetHTTPVariable;

Does't work.

So, now I have 2 problems:
1- If I change the PathInfo without check ServerName, I can fix it but the app raise an exception;
2- ServerSoftware doesn't work in version 3.1.1 .

Regards,
Marcos Douglas

Reply by email