You are not logged in.
Pages: 1
Hello.
I'm using THttpApiServer. I need to compress the response data. I discovered the CompressGZip and CompressDeflate functions in the mormot.core.zip module. I enabled these functions using RegisterCompress. But when generating a response, I get error 87. After studying the source code, I discovered that in the THttpApiServer.Execute procedure, after data compression, the data length is not adjusted anywhere. I added the necessary code and sending data worked correctly. Perhaps this is a bug in the source code? Or did I connect the data compression functions incorrectly?
Thanks.
procedure THttpApiServer.Execute;
...
function SendResponse: boolean;
...
if fCompress <> nil then
begin
with resp^.headers.KnownHeaders[reqContentEncoding] do
if RawValueLength = 0 then
begin
// no previous encoding -> try if any compression
CompressContent(compressset, fCompress, ctxt.OutContentType,
ctxt.fOutContent, outcontenc);
pRawValue := pointer(outcontenc);
RawValueLength := length(outcontenc);
end;
// The code I added is below
with resp^.headers.KnownHeaders[reqContentLength] do
begin
DataLength := Length(ctxt.OutContent).ToString;
pRawValue := pointer(DataLength);
RawValueLength := Length(DataLength);
end;
//
end;
resp^.SetContent(datachunkmem, ctxt.OutContent, ctxt.OutContentType);
flags := GetSendResponseFlags(ctxt);
EHttpApiServer.RaiseOnError(hSendHttpResponse,
Http.SendHttpResponse(fReqQueue, req^.RequestId, flags, resp^, nil,
bytessent, nil, 0, nil, fLogData));
...
Offline
This part should not have changed since mORMot 1, and it was reported to work as expected IIRC.
Could you please check against mORMot 1 source, and see if there is something missing during the translation?
Note that your fix about reqContentLength is unsafe and should not work because you are mixing UTF-16 and UTF-8 content on Delphi, over a temporary memory buffer.
My guess is that you are using FPC.
Offline
This code demonstrates the problem. The problem comes from this line: "Ctxt.AddOutHeader(['Content-Length:' + Length(Ctxt.OutContent).ToString]);". If the "Content-Length" header value is not empty, an error will be raised.
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses System.SysUtils, mormot.net.server, mormot.core.zip, mormot.net.http,
mormot.core.base, mormot.core.threads, mormot.lib.winhttp;
type
TMyServer = class(THttpApiServer)
private
function ProcessRequest(Ctxt: THttpServerRequestAbstract): Cardinal;
public
constructor Create(QueueName: SynUnicode = '';
const OnStart: TOnNotifyThread = nil; const OnStop: TOnNotifyThread = nil;
const ProcessName: RawUtf8 = ''; ProcessOptions: THttpServerOptions = []); reintroduce;
end;
const
Port = 2147;
var
Server: TMyServer;
constructor TMyServer.Create(QueueName: SynUnicode; const OnStart,
OnStop: TOnNotifyThread; const ProcessName: RawUtf8;
ProcessOptions: THttpServerOptions);
begin
inherited;
RegisterCompress(CompressGZip, 0);
RegisterCompress(CompressDeflate, 0);
OnRequest := ProcessRequest;
AddUrl('/', UTF8String(Port.ToString), False, '+', False);
end;
function TMyServer.ProcessRequest(Ctxt: THttpServerRequestAbstract): Cardinal;
begin
Ctxt.OutContentType := 'text/plain; charset=utf-8';
Ctxt.OutContent := 'Hello world!';
Ctxt.OutCustomHeaders := string.Empty;
Ctxt.AddOutHeader(['Content-Length:' + Length(Ctxt.OutContent).ToString]);
Ctxt.RespStatus := 200;
Result := Ctxt.RespStatus;
end;
begin
try
Server := TMyServer.Create;
try
while True do
Sleep(10);
finally
Server.RemoveUrl('/', UTF8String(Port.ToString), False, '+');
Server.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Offline
Note that your fix about reqContentLength is unsafe and should not work because you are mixing UTF-16 and UTF-8 content on Delphi, over a temporary memory buffer.
My guess is that you are using FPC.
No. I'm using Delphi. I forgot to say that DataLength: RawUtf8. When assigning, a conversion is performed. That's why this code works for me.
Offline
Pages: 1