Recent

Author Topic: Http Server use a random port  (Read 8570 times)

mercury

  • Full Member
  • ***
  • Posts: 154
Http Server use a random port
« on: April 21, 2016, 03:01:54 pm »
I’m going to embed a small web server in the application using fcl-web.
Something like this:

Code: Pascal  [Select][+][-]
  1. uses
  2.   ... fphttpserver;
  3.  
  4. type
  5.  
  6. TThreadHTTPServer = class(TThread)
  7. private
  8.   FHTTPServer: TFPCustomHttpServer;
  9.   procedure DoHandleRequest(Sender: TObject;
  10.     var ARequest: TFPHTTPConnectionRequest; var AResponse: TFPHTTPConnectionResponse);
  11.  
  12. protected
  13.  
  14. public
  15.   constructor Create;
  16.   destructor Destroy; override;
  17.   procedure Execute; override;
  18. end;
  19.  
  20. implementation
  21.  
  22. procedure TThreadHTTPServer.DoHandleRequest(Sender: TObject;
  23.   var ARequest: TFPHTTPConnectionRequest; var AResponse: TFPHTTPConnectionResponse);
  24. begin
  25.   AResponse.Content := 'balabala...';
  26. end;
  27.  
  28. constructor TThreadHTTPServer.Create();
  29. begin
  30.   inherited Create(True);
  31.  
  32.   FHTTPServer := THTTPServer.Create(nil);
  33.   FHTTPServer.Threaded := False;
  34.   FHTTPServer.Address := '127.0.0.1';
  35.   FHTTPServer.Port := 0;               // <------------------ so, which port is used?
  36.   FHTTPServer.OnRequest := @DoHandleRequest;
  37.  
  38. end;
  39.  
  40. destructor TThreadHTTPServer.Destroy;
  41. begin
  42.   FHTTPServer.Free;
  43.   inherited Destroy;
  44. end;
  45.  
  46. procedure TThreadHTTPServer.Execute;
  47. begin
  48.   try
  49.     FHTTPServer.Active := True;
  50.     DebugLn('Execute Done');            //<---------------------- this will never show
  51.   except
  52.     on E: Exception do begin
  53.       DebugLn('Error: ' + LineEnding + E.UnitName + '/' + E.ClassName + LineEnding + E.Message);
  54.     end;
  55.   end;
  56. end;

I have two problem:
1. Set the Port to 0 will use a random port, but how to know which one is used?
2. When I free the TThreadHTTPServer , it always be a “ESocketError” error. How to fix this?

Thank for your help.


« Last Edit: April 22, 2016, 05:09:09 pm by mercury »

Leledumbo

  • Hero Member
  • *****
  • Posts: 8835
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Http Server use a random port
« Reply #1 on: April 22, 2016, 02:46:56 pm »
1. Set the Port to 0 will use a random port, but how to know which one is used?
Inside your server's method, access Server.GetConnection.LocalAddress.sin_port.
2. When I free the TThreadHTTPServer , it always be a “ESocketError” error. How to fix this?
Debug it, get a stack trace.

Thaddy

  • Hero Member
  • *****
  • Posts: 18792
  • Glad to be alive.
Re: Http Server use a random port
« Reply #2 on: April 22, 2016, 04:15:14 pm »
Actually, when you do not set the port it defaults to 80... Or if you set the port to zero... (default still to 80) Which makes it undebugable if you have a browser open and an actual internet connection. Don't do that. Learn how to do it. Production behavior is 80 because http design says so.. It's not a bug. Unless you count the programmer as a bug. Develop with any other randomly chosen port (by you!) except 80.

Today I would suggest port 1999...
« Last Edit: April 22, 2016, 04:20:22 pm by Thaddy »
Recovered from removal of tumor in tongue following tongue reconstruction with a part from my leg.

mercury

  • Full Member
  • ***
  • Posts: 154
Re: Http Server use a random port
« Reply #3 on: April 22, 2016, 05:18:56 pm »
Today I would suggest port 1999...
I don't want use a fixed port. It just for local use. So a random port will now conflict with any other servers like IIS, Nginx..

Inside your server's method, access Server.GetConnection.LocalAddress.sin_port.
GetConnection is protected, can't access it. Actually even TFPCustomHttpServer.FServer is not accessible.

Debug it, get a stack trace.
It says "Could not accept a client connection on socket: 1588, error 10038".
What this mean?

Thank for your help.

Thaddy

  • Hero Member
  • *****
  • Posts: 18792
  • Glad to be alive.
Re: Http Server use a random port
« Reply #4 on: April 22, 2016, 05:24:27 pm »
I don't want use a fixed port. It just for local use. So a random port will now conflict with any other servers like IIS, Nginx..
There's no logic in that. How do you want to have a server running when no client knows up-front where it is?
You can use any port you like except maybe for the first 10.000.
Or are you making the mistake that a client isn't very likely to do a handshake.....
Recovered from removal of tumor in tongue following tongue reconstruction with a part from my leg.

mercury

  • Full Member
  • ***
  • Posts: 154
Re: Http Server use a random port
« Reply #5 on: April 25, 2016, 04:30:24 am »
There's no logic in that. How do you want to have a server running when no client knows up-front where it is?
You can use any port you like except maybe for the first 10.000.
Or are you making the mistake that a client isn't very likely to do a handshake.....
Of course I have my logic. As I said it’s for internal use. The HTTP communicate is just between a pair of local program. And there may run many pairs of them at a same time. So a fixed port is not practicable.
Anyway I want use a random port. Thanks for your advice.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8835
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Http Server use a random port
« Reply #6 on: April 25, 2016, 11:05:59 am »
Actually, when you do not set the port it defaults to 80... Or if you set the port to zero... (default still to 80)
Actually, setting the port to 0 DOES mean random port.
GetConnection is protected, can't access it. Actually even TFPCustomHttpServer.FServer is not accessible.
That's why I said to do it inside your server class, it inherits from the base class where GetConnection is defined. And you don't access the private FServer field, but the public Server property.
It says "Could not accept a client connection on socket: 1588, error 10038".
What this mean?
The port is forbidden to listen to. Like Thaddy said, port number under 10000 requires special permission. Either run it with root or don't use random port.

Thaddy

  • Hero Member
  • *****
  • Posts: 18792
  • Glad to be alive.
Re: Http Server use a random port
« Reply #7 on: April 25, 2016, 11:31:26 am »
Actually, when you do not set the port it defaults to 80... Or if you set the port to zero... (default still to 80)
Actually, setting the port to 0 DOES mean random port.

Setting to zero means (should mean) select the default port for the protocol, which is 80 for http.. Anything else is a bug. Did you test that? I would be highly amazed if it was a random port... At least synapse does the correct thing.
« Last Edit: April 25, 2016, 11:33:40 am by Thaddy »
Recovered from removal of tumor in tongue following tongue reconstruction with a part from my leg.

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1315
Re: Http Server use a random port
« Reply #8 on: April 25, 2016, 01:42:27 pm »
I use Synapse, and it means: a random port.

Then again, it might help that most servers I make run on Linux, where ports up to 1024 are reserved.

Thaddy

  • Hero Member
  • *****
  • Posts: 18792
  • Glad to be alive.
Re: Http Server use a random port
« Reply #9 on: April 25, 2016, 03:43:49 pm »
I use Synapse, and it means: a random port.
Don't be economical with the truth, please. I double checked what does all this mean then? It is from the synapse sources:
Code: Pascal  [Select][+][-]
  1.   FTargetPort := cHttpProtocol;
Now look at that constant and explain why it is 80....
Nothing random there in the constructor. It is port 80 unless you specify otherwise.  >:D >:D

And, by the way, the proxy port also defaults correct to 8080....

An apology would be in place.... 8-)
« Last Edit: April 25, 2016, 03:53:42 pm by Thaddy »
Recovered from removal of tumor in tongue following tongue reconstruction with a part from my leg.

Thaddy

  • Hero Member
  • *****
  • Posts: 18792
  • Glad to be alive.
Re: Http Server use a random port
« Reply #10 on: April 25, 2016, 04:00:48 pm »
There is no random port for http servers.... It is 80 by default (but configurable) for http. Don't ever put people in the wrong position that they start to believe there is something like an http server running on a random port. You have to write code for that. And it doesn't work without a client that also knows the port number. Hence it does not work without pcap or the likes to discover where it connects. (possible, but illogical)
zero means 80 in this case. As Synapse does of course do correctly.

After a handshake on the correct port (which is configurable) any further traffic can be on a "random"port chosen by the server. But the initial handshake is prescribed by the protocol.

Also note ports up to 1024 is a nonsensical remark.... Go over 10.000, not just 1024, and it has nothing to do with linux or windows. It is about governing bodies prescribing/reserving ports for protocols.... <sigh>v See proxy port for over 1024: it's 8080... <sigh, sigh, silly>
« Last Edit: April 25, 2016, 04:14:44 pm by Thaddy »
Recovered from removal of tumor in tongue following tongue reconstruction with a part from my leg.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8835
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Http Server use a random port
« Reply #11 on: April 25, 2016, 07:23:20 pm »
Setting to zero means (should mean) select the default port for the protocol, which is 80 for http.. Anything else is a bug. Did you test that?
fphttpserver wraps TInetServer which wraps fpBind which is a system call. Here are some references for the bind() system call behavior when given 0 as port parameter:
http://unix.stackexchange.com/a/180500
http://stackoverflow.com/a/1077305/549472
http://compnetworking.about.com/od/tcpip/p/port-numbers-0.htm
https://www.dnorth.net/2012/03/17/the-port-0-trick/

mercury

  • Full Member
  • ***
  • Posts: 154
Re: Http Server use a random port
« Reply #12 on: April 26, 2016, 11:43:30 am »
That's why I said to do it inside your server class, it inherits from the base class where GetConnection is defined. And you don't access the private FServer field, but the public Server property.
 
There is no public Server property. Did I missed something?

The port is forbidden to listen to. Like Thaddy said, port number under 10000 requires special permission. Either run it with root or don't use random port.
Forbidden to listen to? I use “netstat” to check which the port is used, and use web browser to open it, it does wok.

Here is what I did with synapse. Now I need is an fcl-web version.
Code: Pascal  [Select][+][-]
  1. in synapse40/source/demo/httpserv/http.pas
  2.  
  3. line 11 : Sock:TTCPBlockSocket;
  4. move to line 13
  5.  
  6. line 55 : bind('0.0.0.0','80');
  7. change to : bind('127.0.0.1','0');
  8.  
  9. Then start the server.
  10.  
  11.   TCPHttpDaemon := TTCPHttpDaemon.Create();
  12.   repeat
  13.     Sleep(1);
  14.   until TCPHttpDaemon.Sock.GetLocalSinPort > 0;
  15.   StartUrl := 'http://127.0.0.1:' + IntToStr(TCPHttpDaemon.Sock.GetLocalSinPort) + '/index.html';
Could anyone give me an example?

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1315
Re: Http Server use a random port
« Reply #13 on: April 26, 2016, 11:55:04 am »
An apology would be in place.... 8-)
Ok, I apologize.

 

TinyPortal © 2005-2018