You are not logged in.
If I attempt to create an instance of the HTTP Server when the port is already in use, I get an AV:
To reproduce this error, I ran another server that binds the same port (8080 in this case), and then ran the Project14ServerHttpWeak project with this same port:
20141003 18173830 + TSQLHttpServer(008285A8).00515016
20141003 18174030 EXC ECommunicationException ("TSQLHttpServer.Create: Impossible to register URL for root") at 005152E0 stack trace API 0048FA84
20141003 18174030 ERROR TSQLHttpServer(008285A8) {"ECommunicationException":"TSQLHttpServer.Create: Impossible to register URL for root"}{"ECommunicationException(008130C0)":[20141003 18174138 EXCOS EAccessViolation (C0000005) at 0047E7B5 stack trace API 0048FA84 00407CC0 76F7B46B 76F30133 0047F936 00492532 00490DA6 0051533C 0051ACCD 76A2338A 76F59F72 76F59F45
stack trace API 00490DA6 0051533C 0051ACCD 76A2338A 76F59F72 76F59F45
20141003 18174139 - 03.139.726
20141003 18174140 EXCOS EAccessViolation (C0000005) at 0047E7B5 stack trace API 0048FA84 0040816E 76F7B46B 76F30133 0047F936 00492532 00490DA6 0051533C 0051ACCD 76A2338A 76F59F72 76F59F45
20141003 18174140 + TSQLRestServerFullMemory(00791670).Shutdown
20141003 18174140 info CurrentRequestCount=0
20141003 18174140 - 00.004.698
20141003 18174140 info TSQLRestServerFullMemory.Destroy -> null
The problem occurs when the fHttpServer instance is freed in mORMotHttpServer.pas here:
constructor TSQLHttpServer.Create(const aPort: AnsiString;
const aServers: array of TSQLRestServer; const aDomainName: AnsiString;
aHttpServerKind: TSQLHttpServerOptions; ServerThreadPoolCount: Integer;
aHttpServerSecurity: TSQLHttpServerSecurity);
...
{$ifndef USETCPPREFIX}
if aHttpServerKind in [useHttpApi,useHttpApiRegisteringURI] then
try
// first try to use fastest http.sys
fHttpServer := THttpApiServer.Create(false);
for i := 0 to high(aServers) do begin
j := THttpApiServer(fHttpServer).AddUrl(
aServers[i].Model.Root,aPort,(aHttpServerSecurity=secSSL),aDomainName,
(aHttpServerKind=useHttpApiRegisteringURI));
if j<>NO_ERROR then begin
ErrMsg := 'Impossible to register URL';
if j=ERROR_ACCESS_DENIED then
ErrMsg := ErrMsg+' (administrator rights needed)';
raise ECommunicationException.CreateFmt('%s.Create: %s for %s',
[ClassName,ErrMsg,aServers[i].Model.Root]);
break;
end;
end;
except
on E: Exception do begin
{$ifdef WITHLOG}
Log.Log(sllError,'% for %',[E,fHttpServer],self);
{$endif}
FreeAndNil(fHttpServer); // if http.sys initialization failed <<=================================================
end;
end;
{$endif}
...
Also, the next thing it does is try to create a instance of the pure Delphi server, which will also fail:
if fHttpServer=nil then begin
// http.sys failed -> create one instance of our pure Delphi server
fHttpServer := THttpServer.Create(aPort
{$ifdef USETHREADPOOL},ServerThreadPoolCount{$endif});
{$ifdef USETCPPREFIX}
THttpServer(fHttpServer).TCPPrefix := 'magic';
{$endif}
end;
Aside from the error condition being unrecoverable (which is especially problematic for a service application), is there a way to ensure that the 'pure' Delphi server is never used? I don't want to assume a server is running using the kernel http.sys when it might not be.
Thanks
Offline
Done, thanks.
Offline
In fact, I'm afraid this was as design.
Your server code has to protect and handle any exception.
For instance, Project27ServerTest.dpr should be written at least:
SQLite3Log.Family.Level := LOG_VERBOSE;
try
Test;
except
on E: Exception do
; // handle error here
end;
Then, in case of error, there is no Access Violation, but the succession of exceptions, as expected...
Do you have some code to show (a simple .dpr may be enough) to reproduce the issue?
Offline
If you run two instances of the Project14ServerHttpWeak application, you will see the issue when the second instance runs. I just realized that the URL mapping has to be the same for the error to occur, not just the port. Sorry I didn't make that clear.
Please let me know if you need any further clarification.
Offline
If you catch the error in a try...except block, there is no AV any more, right?
Project14ServerHttpWeak is a simple sample which does not catch the error, but on production, you should set the try...except block;
Offline