You are not logged in.
Pages: 1
I have a service with a method for uploading files.
TFileDownloadUploadRest = class(TRestService)
[...]
procedure Upload(Ctxt: TSQLRestServerURIContext);
The service uses another method to register a file, which is then uploaded using the Upload() method.
However, I would like to protect server from receiving unregistered (and often big!) file, to not waste the transfer, because only after receiving the whole file the server can reject it.
Is it possible to intercept the start of a transfer (call Upload()) and break it when transfer is unplanned?
Last edited by jaclas (2017-10-26 12:06:08)
Offline
When requests do arrive to TSQLRestServer.URI, the body has been fully downloaded in the HTTP server class.
There is currently no callback at HTTP server level, to check for headers, and reject the request.
I will add this feature.
Offline
Thx, I am looking forward to this extension!
Offline
@AB - please, look at branch HTTPServerEvents - I'm implement where all necessery events (for HTTP.sys based server). branch description.
I'm use it on hi-load productions without problems and will be very happy if it be merged to trunk
Offline
I've just introduced THttpServerGeneric.OnBeforeBody event, allowing request abortion just after the headers are retrieved.
See https://synopse.info/fossil/info/e9ae45e587
It will work for both Socket and HTTP.sys servers.
@mpv
Yes I will merge the branches, but I was not pleased by the fact that new units were introduced in the branch.
Offline
Ups. I try to merge HTTPServerEvents with trunk, but you implement a OnBeforeBody event. @AB, please, take a look in my implementation - it add 4 event, one of it is near the same as OnBeforeBody
Code from branch:
/// event handler called after HTTP request headers retrieved
// but before HTTP body is readed from a socket.
// The main purpose is to analyse a request headers (for example Content-Length)
// and make some decisions BEFORE recive a request body.
// In case handler return a non 2XX code server will send a responce to client
// without reading a request body (for example 413 Payload Too Large)
// - warning: this handler must be thread-safe (can be called by several
// threads simultaneously)
property OnAfterHeaderRetrieved: TOnHttpServerRequest
Last edited by mpv (2017-10-26 15:33:02)
Offline
Offline
I try use this new event, but... something is wrong.
My event body:
function TssHTTPServer.OnBeforeBodyEvent(const aURL,aMethod,aInHeaders, aInContentType,aRemoteIP: SockString; aContentLength: integer): Cardinal;
begin
TSQLLog.Family.SynLog.Log(sllDebug, 'TssHTTPServer.OnBeforeBodyEvent(%, %)', [aURL,aMethod]);
Result := STATUS_NOTFOUND;
end;
And I send from IE post requests:
first is catched:
2017-10-27 08:52:35.50 debug TssHTTPServer.OnBeforeBodyEvent(/file/upload/service/7865865875fgfiug786tg76, POST)
...but after this IE still wait for response for looong time (turns the wheel)...
next request from IE is ...handled normally!
2017-10-27 09:08:30.39 + ss.Rest.FileDownloads.TFileDownloadUploadRest(08063CC0).URI(POST file/upload/service/7865865875fgfiug786tg76 inlen=37516350)
what is wrong?
Last edited by jaclas (2017-10-27 07:12:50)
Offline
HTTPAPI and IE11 (from win7)
Offline
Imho problem is in server constructor and created threads without event handler:
if ServerThreadPoolCount>1 then
THttpApiServer(fHttpServer).Clone(ServerThreadPoolCount-1);
Offline
Please check https://synopse.info/fossil/info/f81cd8395f
Offline
The OnAfterHeaderRetrieved() signature can't work with socket-based service, since at that time there is no THttpServerRequest instance.
But we may merge the other callbacks.
May be modify the THttpServer.Execute method and include where code from ClientCrtSock.GetRequest? In this case we can create a Context: THttpServerRequest inside the THttpServer.Execute like it done in the THttpApiServer.Execute. IMHO this make both server implementation more similar..
Offline
Requests eject now works properly.
But IE strangely handle the reject. Maybe this is a IE11 bug.
Offline
413 does not change anything, IE still behaves unpredictably.
Offline
I've just introduced THttpServerGeneric.MaximumAllowedContentLength property, which should work on any kind of Http server.
It returns STATUS_PAYLOADTOOLARGE = 413 error if "Content-Length" header overflows this value.
See https://synopse.info/fossil/info/9b189d64e0
Offline
Hmmm... still exist some problems.
I add this line:
Self.fHttpServer.MaximumAllowedContentLength := 5000;
and I post 4 times the same request, in log I get:
2017-10-29 13:55:30.54 trace TFileDownloadUploadRest(07FA3CC0) EndCurrentThread(THttpApiServer) ThreadID=00000430 ThreadCount=-1
2017-10-29 13:55:49.45 trace TFileDownloadUploadRest(07FA3CC0) EndCurrentThread(THttpApiServer) ThreadID=000011BC ThreadCount=-2
2017-10-29 13:55:59.47 trace TFileDownloadUploadRest(07FA3CC0) EndCurrentThread(THttpApiServer) ThreadID=00000E5C ThreadCount=-3
2017-10-29 13:56:08.54 trace TFileDownloadUploadRest(07FA3CC0) EndCurrentThread(THttpApiServer) ThreadID=00001220 ThreadCount=-4
Each request release the thread, probably due to an internal exception:
Last edited by jaclas (2017-10-29 15:40:54)
Offline
Please check https://synopse.info/fossil/info/7de5aa5961
There was indeed a problem in my implementation.
Offline
Looks like it's ok now, big thanks Arnaud!
Offline
Pages: 1