Browse Source

--- Merging r18089 into '.':
U packages/fcl-web/src/base/fphttp.pp
--- Merging r18101 into '.':
U packages/fcl-web/examples/helloworld/README.txt
--- Merging r18181 into '.':
A packages/fcl-web/src/base/fphttpstatus.pas
--- Merging r18182 into '.':
U packages/fcl-web/src/base/httpdefs.pp
U packages/fcl-web/src/base/fphttpserver.pp
--- Merging r18184 into '.':
U packages/fcl-web/src/base/custfcgi.pp
--- Merging r18187 into '.':
U packages/fcl-web/src/base/FCGI-README.txt

# revisions: 18089,18101,18181,18182,18184,18187
------------------------------------------------------------------------
r18089 | michael | 2011-08-04 09:18:13 +0200 (Thu, 04 Aug 2011) | 1 line
Changed paths:
M /trunk/packages/fcl-web/src/base/fphttp.pp

* Make HandleRequest public
------------------------------------------------------------------------
------------------------------------------------------------------------
r18101 | marco | 2011-08-05 15:42:49 +0200 (Fri, 05 Aug 2011) | 2 lines
Changed paths:
M /trunk/packages/fcl-web/examples/helloworld/README.txt

* Fixed filename in readme, patch from Attila Borka, Mantis #19826

------------------------------------------------------------------------
------------------------------------------------------------------------
r18181 | michael | 2011-08-12 21:26:38 +0200 (Fri, 12 Aug 2011) | 1 line
Changed paths:
A /trunk/packages/fcl-web/src/base/fphttpstatus.pas

* Some fixes and additional unit from Darius Blaszijk
------------------------------------------------------------------------
------------------------------------------------------------------------
r18182 | michael | 2011-08-12 21:26:51 +0200 (Fri, 12 Aug 2011) | 1 line
Changed paths:
M /trunk/packages/fcl-web/src/base/fphttpserver.pp
M /trunk/packages/fcl-web/src/base/httpdefs.pp

* Some fixes and additional unit from Darius Blaszijk
------------------------------------------------------------------------
------------------------------------------------------------------------
r18184 | michael | 2011-08-12 23:20:02 +0200 (Fri, 12 Aug 2011) | 1 line
Changed paths:
M /trunk/packages/fcl-web/src/base/custfcgi.pp

* Exit process when a shutdown event is received from mod_fastcgi
------------------------------------------------------------------------
------------------------------------------------------------------------
r18187 | michael | 2011-08-13 09:28:29 +0200 (Sat, 13 Aug 2011) | 1 line
Changed paths:
M /trunk/packages/fcl-web/src/base/FCGI-README.txt

* Removed comment about bug ID #19440
------------------------------------------------------------------------

git-svn-id: branches/fixes_2_6@18828 -

marco 14 years ago
parent
commit
2f5e804f2a

+ 1 - 0
.gitattributes

@@ -2631,6 +2631,7 @@ packages/fcl-web/src/base/fphttp.pp svneol=native#text/plain
 packages/fcl-web/src/base/fphttpapp.pp svneol=native#text/plain
 packages/fcl-web/src/base/fphttpapp.pp svneol=native#text/plain
 packages/fcl-web/src/base/fphttpclient.pp svneol=native#text/plain
 packages/fcl-web/src/base/fphttpclient.pp svneol=native#text/plain
 packages/fcl-web/src/base/fphttpserver.pp svneol=native#text/plain
 packages/fcl-web/src/base/fphttpserver.pp svneol=native#text/plain
+packages/fcl-web/src/base/fphttpstatus.pas svneol=native#text/plain
 packages/fcl-web/src/base/fpweb.pp svneol=native#text/plain
 packages/fcl-web/src/base/fpweb.pp svneol=native#text/plain
 packages/fcl-web/src/base/fpwebfile.pp svneol=native#text/plain
 packages/fcl-web/src/base/fpwebfile.pp svneol=native#text/plain
 packages/fcl-web/src/base/httpdefs.pp svneol=native#text/plain
 packages/fcl-web/src/base/httpdefs.pp svneol=native#text/plain

+ 1 - 1
packages/fcl-web/examples/helloworld/README.txt

@@ -104,7 +104,7 @@ Note: You need to change the module name if needed. For example on Linux,
 the module is not mod_fastcgi-2.4.6-AP22.dll but mod_fastcgi.so (need to be 
 the module is not mod_fastcgi-2.4.6-AP22.dll but mod_fastcgi.so (need to be 
 compiled from sources found at http://www.fastcgi.com/dist/ ).
 compiled from sources found at http://www.fastcgi.com/dist/ ).
 The port (2015 in this example) must match the one set in the project main 
 The port (2015 in this example) must match the one set in the project main 
-file (echo.lpr).
+file (helloworld.lpr).
 The FCGI application must be running in order for this demo to work (external 
 The FCGI application must be running in order for this demo to work (external 
 FCGI server setup). Do not forget to restart it after changes and 
 FCGI server setup). Do not forget to restart it after changes and 
 recompilation.
 recompilation.

+ 0 - 3
packages/fcl-web/src/base/FCGI-README.txt

@@ -256,9 +256,6 @@ LoadModule fastcgi_module "modules/mod_fastcgi-2.4.6-AP22.dll"
   ScriptAlias /myfcgi "C:/My Programs/LazarusFCGITest/helloworld.exe"
   ScriptAlias /myfcgi "C:/My Programs/LazarusFCGITest/helloworld.exe"
 </IfModule>
 </IfModule>
 
 
-Known issues on Windows:
-http://bugs.freepascal.org/view.php?id=19440
-
 2.1.4 Start/Restart your Apache server.
 2.1.4 Start/Restart your Apache server.
 If you will use the FastCgiExternalServer, then start your application 
 If you will use the FastCgiExternalServer, then start your application 
 manually, so it can start accepting incoming requests from the web server.
 manually, so it can start accepting incoming requests from the web server.

+ 79 - 3
packages/fcl-web/src/base/custfcgi.pp

@@ -105,9 +105,15 @@ Type
     FAddress: string;
     FAddress: string;
     FTimeOut,
     FTimeOut,
     FPort: integer;
     FPort: integer;
+
 {$ifdef windowspipe}
 {$ifdef windowspipe}
     FIsWinPipe: Boolean;
     FIsWinPipe: Boolean;
 {$endif}
 {$endif}
+{$IFDEF WINDOWS}
+    FShutdownThread : TThread;
+    Procedure CheckShutDownEvent;
+    Procedure HandleShutDownEvent(Sender : TObject);
+{$ENDIF}
     function AcceptConnection: Integer;
     function AcceptConnection: Integer;
     procedure CloseConnection;
     procedure CloseConnection;
     function Read_FCGIRecord : PFCGI_Header;
     function Read_FCGIRecord : PFCGI_Header;
@@ -169,18 +175,53 @@ Implementation
 uses
 uses
   dbugintf;
   dbugintf;
 {$endif}
 {$endif}
- 
-
-
 {$undef nosignal}
 {$undef nosignal}
 
 
 {$if defined(FreeBSD) or defined(Linux)}
 {$if defined(FreeBSD) or defined(Linux)}
   {$define nosignal}
   {$define nosignal}
 {$ifend}
 {$ifend}
 
 
+{$IFDEF WINDOWS}
+Type
+
+  { TShutdownThread }
+  TShutdownEvent = Procedure (Sender : TObject) Of Object;
+  TShutdownThread = Class(TThread)
+  Private
+    FEvent : THandle;
+    FOnShutDown : TShutdownEvent;
+  Public
+    Constructor CreateWithEvent(AEvent : THandle; AOnShutDown : TShutdownEvent);
+    Procedure Execute; override;
+  end;
+{$ENDIF}
+
 Const 
 Const 
    NoSignalAttr =  {$ifdef nosignal} MSG_NOSIGNAL{$else}0{$endif};
    NoSignalAttr =  {$ifdef nosignal} MSG_NOSIGNAL{$else}0{$endif};
 
 
+{$IFDEF WINDOWS}
+{ TShutdownThread }
+
+constructor TShutdownThread.CreateWithEvent(AEvent: THandle; AOnShutDown : TShutdownEvent);
+begin
+  Inherited Create(False);
+  FEvent:=AEvent;
+  FOnShutDown:=AOnShutDown;
+  OnTerminate:=AOnShutDown;
+end;
+
+procedure TShutdownThread.Execute;
+begin
+  WaitForSingleObject(FEvent,INFINITE);
+  If Assigned(FOnShutDown) then
+    FOnShutDown(Self);
+  // This is very ugly, but there is no other way to stop the named pipe
+  // from accepting new connections.
+  // Using Halt(0) is not enough.
+  ExitProcess(0);
+end;
+{$ENDIF WINDOWS}
+
 { TFCGIHTTPRequest }
 { TFCGIHTTPRequest }
 
 
 procedure TFCGIRequest.ReadContent;
 procedure TFCGIRequest.ReadContent;
@@ -473,16 +514,27 @@ end;
 { TFCgiHandler }
 { TFCgiHandler }
 
 
 constructor TFCgiHandler.Create(AOwner: TComponent);
 constructor TFCgiHandler.Create(AOwner: TComponent);
+
 begin
 begin
   Inherited Create(AOwner);
   Inherited Create(AOwner);
   FRequestsAvail:=5;
   FRequestsAvail:=5;
   SetLength(FRequestsArray,FRequestsAvail);
   SetLength(FRequestsArray,FRequestsAvail);
   FHandle := THandle(-1);
   FHandle := THandle(-1);
   FTimeOut:=50;
   FTimeOut:=50;
+{$IFDEF WINDOWS}
+  CheckShutdownEvent;
+{$ENDIF}
 end;
 end;
 
 
 destructor TFCgiHandler.Destroy;
 destructor TFCgiHandler.Destroy;
 begin
 begin
+{$IFDEF WINDOWS}
+  IF (FShutDownThread<>Nil) then
+    begin
+    TShutDownThread(FShutDownThread).FOnShutDown:=Nil;
+    TShutDownThread(FShutDownThread).OnTerminate:=Nil;
+    end;
+{$ENDIF}
   SetLength(FRequestsArray,0);
   SetLength(FRequestsArray,0);
   if (Socket<>0) then
   if (Socket<>0) then
     begin
     begin
@@ -492,6 +544,30 @@ begin
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
+{$IFDEF WINDOWS}
+Procedure TFCgiHandler.CheckShutdownEvent;
+
+Var
+  H : THandle;
+
+begin
+  // This is normally only used in mod_fastcgi.
+  // mod_fcgid just kills off the process...
+  H:=THandle(StrToIntDef(sysutils.GetEnvironmentVariable('_FCGI_SHUTDOWN_EVENT_'),0));
+  If (H<>0) then
+    FShutDownThread:=TShutdownThread.CreateWithEvent(H,@HandleShutDownEvent);
+end;
+
+procedure TFCgiHandler.HandleShutDownEvent(Sender : TOBject);
+begin
+  TShutDownThread(Sender).FOnShutDown:=Nil;
+  TShutDownThread(Sender).OnTerminate:=Nil;
+  FShutDownThread:=Nil;
+  Terminate;
+end;
+
+{$ENDIF}
+
 procedure TFCgiHandler.CloseConnection;
 procedure TFCgiHandler.CloseConnection;
 Var
 Var
   i : Integer;
   i : Integer;

+ 1 - 1
packages/fcl-web/src/base/fphttp.pp

@@ -38,13 +38,13 @@ Type
   Protected
   Protected
     Procedure DoHandleRequest(ARequest : TRequest; AResponse : TResponse; Var Handled : Boolean); virtual;
     Procedure DoHandleRequest(ARequest : TRequest; AResponse : TResponse; Var Handled : Boolean); virtual;
     Procedure DoGetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean); virtual;
     Procedure DoGetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean); virtual;
-    Procedure HandleRequest(ARequest : TRequest; AResponse : TResponse; Var Handled : Boolean);
     Function ProduceContent : String; virtual;
     Function ProduceContent : String; virtual;
     Procedure SetRequest(ARequest: TRequest);
     Procedure SetRequest(ARequest: TRequest);
   Protected
   Protected
     Property BeforeRequest : TRequestEvent Read FBeforeRequest Write FBeforeRequest;
     Property BeforeRequest : TRequestEvent Read FBeforeRequest Write FBeforeRequest;
     Property AfterResponse : TResponseEvent Read FAfterResponse Write FAfterResponse;
     Property AfterResponse : TResponseEvent Read FAfterResponse Write FAfterResponse;
   Public
   Public
+    Procedure HandleRequest(ARequest : TRequest; AResponse : TResponse; Var Handled : Boolean);
     Procedure GetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean);
     Procedure GetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean);
     Function  HaveContent : Boolean; virtual;
     Function  HaveContent : Boolean; virtual;
     function ContentToStream(Stream : TStream) : boolean; virtual;
     function ContentToStream(Stream : TStream) : boolean; virtual;

+ 16 - 2
packages/fcl-web/src/base/fphttpserver.pp

@@ -37,6 +37,7 @@ Type
     FConnection: TFPHTTPConnection;
     FConnection: TFPHTTPConnection;
   protected
   protected
     procedure SetContent(AValue : String);
     procedure SetContent(AValue : String);
+  published
     Property Connection : TFPHTTPConnection Read FConnection;
     Property Connection : TFPHTTPConnection Read FConnection;
   end;
   end;
 
 
@@ -93,12 +94,15 @@ Type
 
 
   TFPCustomHttpServer = Class(TComponent)
   TFPCustomHttpServer = Class(TComponent)
   Private
   Private
+    FAdminMail: string;
+    FAdminName: string;
     FOnAllowConnect: TConnectQuery;
     FOnAllowConnect: TConnectQuery;
     FOnRequest: THTTPServerRequestHandler;
     FOnRequest: THTTPServerRequestHandler;
     FPort: Word;
     FPort: Word;
     FQueueSize: Word;
     FQueueSize: Word;
     FServer : TInetServer;
     FServer : TInetServer;
     FLoadActivate : Boolean;
     FLoadActivate : Boolean;
+    FServerBanner: string;
     FThreaded: Boolean;
     FThreaded: Boolean;
     function GetActive: Boolean;
     function GetActive: Boolean;
     procedure SetActive(const AValue: Boolean);
     procedure SetActive(const AValue: Boolean);
@@ -138,6 +142,12 @@ Type
     property Threaded : Boolean read FThreaded Write SetThreaded;
     property Threaded : Boolean read FThreaded Write SetThreaded;
     // Called to handle the request. If Threaded=True, it is called in a the connection thread.
     // Called to handle the request. If Threaded=True, it is called in a the connection thread.
     Property OnRequest : THTTPServerRequestHandler Read FOnRequest Write FOnRequest;
     Property OnRequest : THTTPServerRequestHandler Read FOnRequest Write FOnRequest;
+
+  published
+    //aditional server information
+    property AdminMail: string read FAdminMail write FAdminMail;
+    property AdminName: string read FAdminName write FAdminName;
+    property ServerBanner: string read FServerBanner write FServerBanner;
   end;
   end;
 
 
   TFPHttpServer = Class(TFPCustomHttpServer)
   TFPHttpServer = Class(TFPCustomHttpServer)
@@ -152,6 +162,8 @@ Type
 
 
   EHTTPServer = Class(Exception);
   EHTTPServer = Class(Exception);
 
 
+  Function GetStatusCode (ACode: Integer) : String;
+
 implementation
 implementation
 
 
 resourcestring
 resourcestring
@@ -426,8 +438,7 @@ begin
   Until (S='');
   Until (S='');
 end;
 end;
 
 
-constructor TFPHTTPConnection.Create(AServer: TFPCustomHttpServer; ASocket: TSocketStream
-  );
+constructor TFPHTTPConnection.Create(AServer: TFPCustomHttpServer; ASocket: TSocketStream);
 begin
 begin
   FSocket:=ASocket;
   FSocket:=ASocket;
   FServer:=AServer;
   FServer:=AServer;
@@ -448,6 +459,8 @@ Var
 begin
 begin
   // Read headers.
   // Read headers.
   Req:=ReadRequestHeaders;
   Req:=ReadRequestHeaders;
+  //set port
+  Req.ServerPort := Server.Port;
   try
   try
     // Read content, if any
     // Read content, if any
     If Req.ContentLength>0 then
     If Req.ContentLength>0 then
@@ -611,6 +624,7 @@ begin
   inherited Create(AOwner);
   inherited Create(AOwner);
   FPort:=80;
   FPort:=80;
   FQueueSize:=5;
   FQueueSize:=5;
+  FServerBanner := 'Freepascal';
 end;
 end;
 
 
 destructor TFPCustomHttpServer.Destroy;
 destructor TFPCustomHttpServer.Destroy;

+ 201 - 0
packages/fcl-web/src/base/fphttpstatus.pas

@@ -0,0 +1,201 @@
+unit FPHTTPStatus;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  SysUtils, fphttpserver, HTTPDefs;
+
+(* construct and return the default error message for a given
+ * HTTP defined error code
+ *)
+function http_error_response(status: integer; ARequest: TFPHTTPConnectionRequest): string;
+
+implementation
+
+function error_string(status: integer; ARequest: TFPHTTPConnectionRequest): string;
+begin
+  case status of
+    301: ;
+    302: ;
+    307: Result := '<p>The document has moved <a href=\' +
+        HTTPEncode(ARequest.Location) +
+        '\>here</a>.</p>';
+    303: Result := '<p>The answer to your request is located ' +
+        '<a href=\' +
+        HTTPEncode(ARequest.Location) +
+        '\>here</a>.</p>';
+    305: Result := '<p>This resource is only accessible ' +
+        'through the proxy' +
+        HTTPEncode(ARequest.Location) +
+        '<br />You will need to configure ' +
+        'your client to use that proxy.</p>';
+    407: ;
+    401: Result := '<p>This server could not verify that you' +
+        'are authorized to access the document' +
+        'requested.  Either you supplied the wrong' +
+        'credentials (e.g., bad password), or your' +
+        'browser doesn''t understand how to supply' +
+        'the credentials required.</p>';
+    400: Result := '<p>Your browser sent a request that ' +
+        'this server could not understand.<br />' +
+        '</p>';
+    403: Result := '<p>You don''t have permission to access ' +
+        HTTPEncode(ARequest.URI) +
+        'on this server.</p>';
+    404: Result := '<p>The requested URL ' +
+        HTTPEncode(ARequest.URI) +
+        ' was not found on this server.</p>';
+    405: Result := '<p>The requested method ' +
+        HTTPEncode(ARequest.Method) +
+        ' is not allowed for the URL ' +
+        HTTPEncode(ARequest.URI) +
+        '.</p>';
+    406: Result := '<p>An appropriate representation of the ' +
+        'requested resource ' +
+        HTTPEncode(ARequest.URI) +
+        ' could not be found on this server.</p>';
+    300: ;
+    411: Result := '<p>A request of the requested method ' +
+        HTTPEncode(ARequest.Method) +
+        ' requires a valid Content-length.<br />';
+    412: Result := '<p>The precondition on the request ' +
+        'for the URL ' +
+        HTTPEncode(ARequest.URI) +
+        ' evaluated to false.</p>';
+    501: Result := '<p>' +
+        HTTPEncode(ARequest.Method) + ' to ' +
+        HTTPEncode(ARequest.URI) +
+        ' not supported.<br />' +
+        '</p>';
+    502: Result := '<p>The proxy server received an invalid ' +
+        'response from an upstream server.<br />' +
+        '</p>';
+    506: Result := '<p>A variant for the requested ' +
+        'resource<pre>' +
+        HTTPEncode(ARequest.URI) +
+        '</pre>is itself a negotiable resource. ' +
+        'This indicates a configuration error.</p>';
+    408: Result := '<p>Server timeout waiting for the HTTP request from the client.</p>';
+    410: Result := '<p>The requested resource<br />' +
+        HTTPEncode(ARequest.URI) +
+        '<br />is no longer available on this server ' +
+        'and there is no forwarding address.' +
+        'Please remove all references to this ' +
+        'resource.</p>';
+    413: Result := 'The requested resource<br />' +
+        HTTPEncode(ARequest.URI) + '<br />' +
+        'does not allow request data with ' +
+        HTTPEncode(ARequest.Method) +
+        ' requests, or the amount of data provided in' +
+        'the request exceeds the capacity limit.';
+    414: Result := '<p>The requested URL''s length exceeds the capacity' +
+        'limit for this server.<br />' +
+        '</p>';
+    415: Result := '<p>The supplied request data is not in a format ' +
+        'acceptable for processing by this resource.</p>';
+    416: Result := '<p>None of the range-specifier values in the Range ' +
+        'request-header field overlap the current extent ' +
+        'of the selected resource.</p>';
+    417:
+    begin
+      if pos('Expect', ARequest.HeaderLine) <> 0 then
+        Result := '<p>The expectation given in the Expect request-header' +
+          'field could not be met by this server.' +
+          'The client sent<pre>   ' +
+          HTTPEncode(ARequest.HeaderLine) + '</pre>'
+      else
+        Result := '<p>No expectation was seen, the Expect request-header ' +
+          'field was not presented by the client.';
+    end;
+    422: Result := '<p>The server understands the media type of the' +
+        'request entity, but was unable to process the' +
+        'contained instructions.</p>';
+    423: Result := '<p>The requested resource is currently locked.' +
+        'The lock must be released or proper identification' +
+        'given before the method can be applied.</p>';
+    424: Result := '<p>The method could not be performed on the resource' +
+        'because the requested action depended on another' +
+        'action and that other action failed.</p>';
+    426: Result := '<p>The requested resource can only be retrieved' +
+        'using SSL.  The server is willing to upgrade the current' +
+        'connection to SSL, but your client doesn''t support it.' +
+        'Either upgrade your client, or try requesting the page' +
+        'using https://';
+    507: Result := '<p>The method could not be performed on the resource' +
+        'because the server is unable to store the' +
+        'representation needed to successfully complete the' +
+        'request.  There is insufficient free space left in' +
+        'your storage allocation.</p>';
+    503: Result := '<p>The server is temporarily unable to service your' +
+        'request due to maintenance downtime or capacity' +
+        'problems. Please try again later.</p>';
+    504: Result := '<p>The gateway did not receive a timely response' +
+        'from the upstream server or application.</p>';
+    510: Result := '<p>A mandatory extension policy in the request is not' +
+        'accepted by the server for this resource.</p>';
+    else
+      //HTTP internal server error
+      Result := '<p>The server encountered an internal ' +
+        'error or' +
+        'misconfiguration and was unable to complete ' +
+        'your request.</p>' +
+        '<p>Please contact the server ' +
+        'administrator at ' +
+        HTTPEncode(ARequest.Connection.Server.AdminMail) +
+        ' to inform them of the time this ' +
+        'error occurred,' +
+        ' and the actions you performed just before ' +
+        'this error.</p>' +
+        '<p>More information about this error ' +
+        'may be available' +
+        'in the server error log.</p>';
+  end;
+end;
+
+function signature(const prefix: string; ARequest: TFPHTTPConnectionRequest): string;
+var
+  name: string;
+begin
+  if ARequest.Connection.Server.AdminName <> '' then
+    name := ARequest.Connection.Server.AdminName
+  else
+    name := ARequest.Connection.Server.AdminMail;
+
+  if ARequest.Connection.Server.AdminMail <> '' then
+    Result := prefix + '<address>' +
+      ARequest.Connection.Server.ServerBanner +
+      ' Server at <a href="' +
+      'mailto:' +
+      HTTPEncode(ARequest.Connection.Server.AdminMail) +
+      '">' +
+      HTTPEncode(name) +
+      '</a> Port ' + ARequest.ServerPort +
+      '</address>'
+  else
+    Result := prefix + '<address>' + ARequest.Connection.Server.ServerBanner +
+      ' Server at ' +
+      ARequest.Connection.Server.AdminMail +
+      ' Port ' + ARequest.ServerPort +
+      '</address>';
+end;
+
+function http_error_response(status: integer; ARequest: TFPHTTPConnectionRequest): string;
+var
+  title: string;
+  h1: string;
+begin
+  title := Format('%d %s', [status, GetStatusCode(status)]);
+  h1 := GetStatusCode(status);
+
+  Result := '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">' +
+    '<html><head><title>' + title +
+    '</title></head><body><h1>' + h1 + '</h1>' +
+    error_string(status, ARequest) +
+    signature('<hr>', ARequest) +
+    '</body></html>';
+end;
+
+end.
+

+ 11 - 2
packages/fcl-web/src/base/httpdefs.pp

@@ -187,6 +187,7 @@ type
     Procedure SetContentLength(Value : Integer);
     Procedure SetContentLength(Value : Integer);
     Function GetFieldIndex(AIndex : Integer) : Integer;
     Function GetFieldIndex(AIndex : Integer) : Integer;
     Function GetServerPort : Word;
     Function GetServerPort : Word;
+    Procedure SetServerPort(AValue : Word);
     Function GetSetFieldValue(Index : Integer) : String; virtual;
     Function GetSetFieldValue(Index : Integer) : String; virtual;
   Protected
   Protected
     Function GetFieldValue(Index : Integer) : String; virtual;
     Function GetFieldValue(Index : Integer) : String; virtual;
@@ -241,7 +242,7 @@ type
     Property RemoteAddr : String Index 27 read GetFieldValue Write SetFieldValue; // Alias, Delphi-compat
     Property RemoteAddr : String Index 27 read GetFieldValue Write SetFieldValue; // Alias, Delphi-compat
     Property RemoteHost : String Index 28 read  GetFieldValue Write SetFieldValue;
     Property RemoteHost : String Index 28 read  GetFieldValue Write SetFieldValue;
     Property ScriptName : String Index 29 read  GetFieldValue Write SetFieldValue;
     Property ScriptName : String Index 29 read  GetFieldValue Write SetFieldValue;
-    Property ServerPort : Word Read GetServerPort; // Index 30
+    Property ServerPort : Word Read GetServerPort Write SetServerPort; // Index 30
     Property HTTPAccept : String Index 1 read GetFieldValue Write SetFieldValue;
     Property HTTPAccept : String Index 1 read GetFieldValue Write SetFieldValue;
     Property HTTPAcceptCharset : String Index 2 read GetFieldValue Write SetFieldValue;
     Property HTTPAcceptCharset : String Index 2 read GetFieldValue Write SetFieldValue;
     Property HTTPAcceptEncoding : String Index 3 read GetFieldValue Write SetFieldValue;
     Property HTTPAcceptEncoding : String Index 3 read GetFieldValue Write SetFieldValue;
@@ -273,6 +274,7 @@ type
     FFiles : TUploadedFiles;
     FFiles : TUploadedFiles;
     FReturnedPathInfo : String;
     FReturnedPathInfo : String;
     FLocalPathPrefix : string;
     FLocalPathPrefix : string;
+    FServerPort : String;
     function GetLocalPathPrefix: string;
     function GetLocalPathPrefix: string;
     function GetFirstHeaderLine: String;
     function GetFirstHeaderLine: String;
   Protected
   Protected
@@ -594,6 +596,12 @@ begin
   Result:=StrToIntDef(GetFieldValue(30),0);
   Result:=StrToIntDef(GetFieldValue(30),0);
 end;
 end;
 
 
+Procedure THTTPHeader.SetServerPort(AValue : Word);
+
+begin
+  SetFieldValue(30,IntToStr(AValue));
+end;
+    
 function THTTPHeader.GetSetFieldValue(Index: Integer): String;
 function THTTPHeader.GetSetFieldValue(Index: Integer): String;
 
 
 Var
 Var
@@ -674,7 +682,7 @@ begin
       27 : ; // Property RemoteAddress : String Index 27 read GetFieldValue Write SetFieldValue;
       27 : ; // Property RemoteAddress : String Index 27 read GetFieldValue Write SetFieldValue;
       28 : ; // Property RemoteHost : String Index 28 read  GetFieldValue Write SetFieldValue;
       28 : ; // Property RemoteHost : String Index 28 read  GetFieldValue Write SetFieldValue;
       29 : ; // Property ScriptName : String Index 29 read  GetFieldValue Write SetFieldValue;
       29 : ; // Property ScriptName : String Index 29 read  GetFieldValue Write SetFieldValue;
-      30 : ; // Property ServerPort : Word Read GetServerPort; // Index 30
+      30 : ; // Property ServerPort : Word Read GetServerPort; // Index 30 in TRequest
       36 : FHTTPXRequestedWith:=Value;
       36 : FHTTPXRequestedWith:=Value;
     end;
     end;
 end;
 end;
@@ -1042,6 +1050,7 @@ procedure TRequest.SetFieldValue(Index: Integer; Value: String);
 begin
 begin
   Case Index of
   Case Index of
     25 : FPathInfo:=Value;
     25 : FPathInfo:=Value;
+    30 : FServerPort:=Value;
     31 : FCommand:=Value;
     31 : FCommand:=Value;
     32 : FURI:=Value;
     32 : FURI:=Value;
   else
   else