You are not logged in.
Delphi Tokyo, win32
What are the requirements for use TSQLHttpClientCurl client?
I try this class, but I get error:
"returned 404 (Not Found) with message libcurl easy_perform=60"
when other clients work properly.
I should install some additional libraries?
Thx JD!
I can't found Indy forum, links are dead... where is located this forum? thx for help
From SlimJet web browser I get response...
-------------
when I modify in IE address from http:// to https:// then IE work too.
Now address is:
https://api.serveraddress.pl:8090/Companies/Timestamp
but requesting via Indy TCP still not work.
Server work on HTTPAPI, on 8090 port and use SSL. Interface based sevice. Standard mORMot client work with server without problem.
from server log:
2017-12-03 17:10:43.45 http ss.Core.Server.Http.TssHTTPServer(0857C340) {"THttpApiServer(0853DCB0)":{"Cloned":false,"RegisteredUrl":"","HTTPQueueLength":1000,"MaxBandwidth":-1,"MaxConnections":-1,"APIVersion":"HTTP API 2.0","ServerName":"mORMot (Windows)","ProcessName":""}} initialized for
2017-12-03 17:11:38.22 http ss.Core.Server.Http.TssHTTPServer(0857C340) http.sys registration of https://+:8090/Companies
2017-12-03 17:11:38.22 http ss.Core.Server.Http.TssHTTPServer(0857C340) {"TssHTTPServer(0857C340)":{}}.AddServer({"TCompaniesRest(0822F7B0)":{"NoAJAXJSON":false,"Options":[],"HandleAuthentication":false,"BypassORMAuthentication":[],"Stats":{"StartDate":"2017-12-03 16:11:38","Success":0,"ServiceMethod":0,"ServiceInterface":0,"OutcomingFiles":0,"CurrentThreadCount":0,"Created":0,"Read":0,"Updated":0,"Deleted":0,"ClientsCurrent":0,"ClientsMax":0,"CurrentRequestCount":0,"Input":{"Bytes":0,"Text":"0 B"},"Output":{"Bytes":0,"Text":"0 B"},"InputThroughput":{"BytesPerSec":0,"Text":"0 B/s"},"OutputThroughput":{"BytesPerSec":0,"Text":"0 B/s"},"Processing":false,"TaskCount":0,"TotalTime":{"MicroSec":0,"Text":"0us"},"LastTime":{"MicroSec":0,"Text":"0us"},"MinimalTime":{"MicroSec":0,"Text":"0us"},"AverageTime":{"MicroSec":0,"Text":"0us"},"MaximalTime":{"MicroSec":0,"Text":"0us"},"PerSec":0,"Errors":0,"LastError":null},"StatLevels":["mlTables","mlMethods","mlInterfaces","mlSQLite3"],"StaticVirtualTableDirect":true,"ServerTimeStamp":135405044454}},Root=Companies,Port=api.serveraddress.pl:8090,Public=api.serveraddress.pl:8090)=trueRequest from standard mORMot client is served properly:
2017-12-03 17:12:21.00 srvr ss.Rest.Companies.TCompaniesRest(0822F7B0) GET Companies/TimeStamp SOA-Method -> 200 with outlen=12 in 524 usbut request from IE11 (call on host where server is run, Windows Server 2012) not respond too:
http://api.serveraddress.pl:8090/Companies/Timestamp
ps. serveraddress is fake address, I can send real address in priv post
I try connect to my server by Indy 10 and OpenSSL library, connecting is established, but server not response to request.
lTCPClient: TIdTCPClient;
lSSLIOHandler : TIdSSLIOHandlerSocketOpenSSL;
begin
//create and configure TCPclient and SSL handler
lSSLIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
lSSLIOHandler.OnStatus := OnSSLStatus;
lSSLIOHandler.OnStatusInfo := OnSSLStatusInfo;
lSSLIOHandler.OnStatusInfoEx := OnSSLStatusInfoEx;
lTCPClient := TIdTCPClient.Create(nil);
lTCPClient.IOHandler := lSSLIOHandler;
lSSLIOHandler.SSLOptions.SSLVersions := [sslvSSLv3, sslvSSLv2, sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
lSSLIOHandler.SSLOptions.Mode := sslmClient;
lSSLIOHandler.SSLOptions.Method := sslvSSLv23;
lTCPClient.Host := edtServer.Text;
lTCPClient.Port := StrToUInt(edtPort.Text);
lSSLIOHandler.Host := edtServer.Text;
lSSLIOHandler.Port := StrToUInt(edtPort.Text);
//connect is established succesfuly
lTCPClient.Connect;
//write HTTP request (copy from other mORMot client http log)
lTCPClient.IOHandler.WriteLn('GET /Companies/Timestamp HTTP/1.1');
lTCPClient.IOHandler.WriteLn('Cache-Control: no-cache');
lTCPClient.IOHandler.WriteLn('Connection: Keep-Alive');
lTCPClient.IOHandler.WriteLn('Pragma: no-cache');
lTCPClient.IOHandler.WriteLn('Content-Type: application/json; charset=UTF-8');
lTCPClient.IOHandler.WriteLn('Accept: */*');
lTCPClient.IOHandler.WriteLn('User-Agent: Mozilla/5.0 (Windows; mORMot 1.18 TWinINet)');
lTCPClient.IOHandler.WriteLn('Host: ' + edtServer.Text + ':' + edtPort.Text);
lTCPClient.IOHandler.WriteLn('Accept-Encoding: gzip, deflate');
//read data from server... waiting to end of timeout, response size is zero bytes
lReadData := lTCPClient.IOHandler.AllData;in last line client waiting 120sec (timeout) and break waiting without receive any data.
From my Indy SSL log I get info that connection is established properly:
SSL StatusInfoEx SSL version: TLS1.2; type: [Handshake Done], Msg: [SSL negotiation finished successfully]; _type: [SSL_ST_CONNECT]
SSL StatusInfo, msg:: SSL status: "SSL negotiation finished successfully"
SSL StatusInfo, msg:: Cipher: name = ECDHE-RSA-AES256-GCM-SHA384; description = ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
; bits = 256; version = TLSv1/SSLv3; What I'm doing wrong?
Ok, mistake is in wloochacz code, but imho raising AV makes it difficult to find the error. Can this exception talk about the actual reason?
But AV is raised on delphi/mORMot client side when mORMot parser try parse this JSON.
Maybe Array.Trim()?
With one parameter this is not very useful :-( There is no way to tell what is in the blob, probably need to use http header for additional info.
It would be useful to tag/register a method so that its parameters are not serialized.
Maybe worth consider to expand TServiceFactoryServer interface by adding method:
function DoNotEncodeParams(const aMethod: array of RawUTF8): TServiceFactoryServer;Is it possible to realize?
Does this mean that the method can have only one parameter? Eg.
procedure SendBlob (const aBlob: RawByteString);
And if I write the method:
Procedure SendBlob(aBlobKind: Integer; const aBlob: RawByteString);
then aBlob will be encoded with Base64?
Hurrah! :-)
Thx!
Please add the ability to send binary data in raw mode (without base64 encoding) in interface-based services. Maybe some dedicated type like TBinaryBlob or TRAWData?
This would be very useful in some cases!
Ok, I understand... but... would it be possible to add the ability to send data in raw mode? no encoding, binary? of course in interface-based service :-)
This would be very useful in some cases!
Please, think of it...
I captured the request (via OnRequest event) and the .Content data was encoded in base64 :-(
One more question. When I use parameter of TServiceCustomAnswer type in interface-based service then data transmitted will base64 encoded or binary?
Looks like it's ok now, big thanks Arnaud!
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=-4Each request release the thread, probably due to an internal exception:

413 does not change anything, IE still behaves unpredictably.
In polish "dom" means "home" ;-)
Requests eject now works properly.
But IE strangely handle the reject. Maybe this is a IE11 bug.

Imho problem is in server constructor and created threads without event handler:
if ServerThreadPoolCount>1 then
THttpApiServer(fHttpServer).Clone(ServerThreadPoolCount-1);
HTTPAPI and IE11 (from win7)
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?
Thx, I am looking forward to this extension!
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?
Thanks!
I found examples on forum and I build service with upload file:
procedure TFileDownloadUploadRest.Upload(Ctxt: TSQLRestServerURIContext);
var
aFileName: string;
aFilePath: string;
begin
case Ctxt.Method of
mPOST,mPUT:
begin
aFileName := 'R:\test.bin';
FileFromString(Ctxt.Call.InBody, aFileName);
Ctxt.Success;
end;
end;but in saved file (at beginning file) I get unnecessary data:
-----------------------------7e12762010838
Content-Disposition: form-data; name="fileToUpload"; filename="C:\Users\Jacek\Downloads\file.bin"
Content-Type: application/octet-stream
MZP ˙˙ ¸ @ ş ´ Í!¸LÍ!This program must be run under Win32
$7 In fact, the beginning of the file is from the bytes MZP...
How get real data of file, without header data?
I found this information by chance, I ask from curiosity.
thx!
This is normal?

Thx, I will try ReturnFile!
Which method is better? Which method does the server load less?
Framework's HTTP server is able to handle returning a file as response to a method-based service.
The service is interface based ![]()
Can interface based and method based service be registered simultaneously in one http server?
I need to provide downloads files through the browser, by click and download. The website is based on JS and retrieves from the interface based service (mORMot) links to files.
The files are on the disk and I would like them to be accessed by the mORMot server for download. Does mORMot support regular download by link?
Or how else to do it?
Is possible to write MarkDown highlighter for SynMemoEx?
Oops... My total disgrace! Sorry :-)
Thanks for tip with AddToCSV!
But I have one question.
This code:
if Header <> '' then
Header := Header + #13#10;
Header := Header + 'myheader: somedata';is better than:
if Header <> '' then
begin
Header := Header + #13#10 + 'myheader: somedata';
end;...because? You mean better memory management? Less allocations? Or...?
You mean should I do something like this:
if Header <> '' then
begin
Header := Header + #13#10 + 'myheader: somedata';
end;?
I did this:
type
TMySQLHttpClientRequest = class(TSQLHttpClientWinHTTP)
protected
function InternalRequest(const url, method: RawUTF8; var Header, Data, DataType: RawUTF8): Int64Rec; override;
end;
implementation
function TMySQLHttpClientRequest.InternalRequest(const url, method: RawUTF8; var Header, Data, DataType: RawUTF8): Int64Rec;
begin
Header := 'myheader: somedata';
Result := inherited InternalRequest(url, method, Header, Data, DataType);
end;And it works :-)
Are there any hidden side effects here?
I work with interface-based service.
I want add some header for debug purpose. In header because I can add in one place to debug in all services at once.
Any suggestion?
Do I have to override this method:
function TSQLHttpClientRequest.InternalRequest(const url, method: RawUTF8; var Header, Data, DataType: RawUTF8): Int64Rec;?
How to add custom HTTP header to client request?
I know about conversions and other issues, this is simple code to test solution.
Thanks for support!
I create this code:
type
TssRestRoutingREST = class(TSQLRestRoutingREST)
protected
function URIDecodeREST(): boolean; override;
public
end;
implementation
function TssRestRoutingREST.URIDecodeREST(): boolean;
var
l: Integer;
begin
Result := inherited URIDecodeREST;
l := Pos('SomeService', URI);
if l > 0 then
begin
URI := StringReplace(URI, 'SomeService', 'SuperSomeService', [rfReplaceAll]);
URIWithoutSignature := StringReplace(URIWithoutSignature, 'SomeService', 'SuperSomeService', [rfReplaceAll]);
end;
end;and it works well, but is it the best method? What can be the side effects?
I have a interface based service:
ISomeService
Customers use this service, but now I would like to change it's name to ISuperSomeService, and for a moment provide the same service under two names, and in the future, the older interface will be removed.
Is it possible to do this without cloning the interface and class and without registering two, separated services? Some mapping or server routing?
I guess I don't understand completely :-)
Event EchoCustom is in a class TSynLogFamily, so I had only one event? How to distinguish from which the service is an log entry in the event?
...and how create TSynLog in my REST service when I can't call constructor...
/// intialize for a TSynLog class instance
// - WARNING: not to be called directly! Use Enter or Add class function instead
constructor Create(aFamily: TSynLogFamily=nil);Please some example.