Closed zen010101 closed 3 weeks ago
Which compiler are you using? On which Operating System?
Which compiler are you using? On which Operating System?
FPC 3.2.2 on Windows 11 Target : Linux aarch64
I am not able to reproduce it here.
Can you get what is the content returned by the server? (headers + response body stream)
Is really 404 returned by the server, or returned internally by the class?
Is there any 30x redirection involved?
Can you try not with TSimpleClient but with plain THttpClientSocket?
I am not able to reproduce it here.
Can you get what is the content returned by the server? (headers + response body stream) only headers can be recieved but no body conten:
20240604 13424119 + marsBmcApi.TMarsBMCAPI(7faa849bc0).SendRequest 20240604 13424119 info https://192.168.7.200:18080/login 20240604 13424119 debug Request Headers: ["Accept: application/json; charset=UTF-8"] 20240604 13424126 debug Response: Code: 200, Headers: Strict-Transport-Security: max-age=31536000; includeSubdomains; preload X-Frame-Options: DENY Pragma: no-cache Cache-Control: no-Store,no-Cache X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff Content-Security-Policy: default-src 'none'; img-src 'self' data:; font-src 'self'; style-src 'self'; script-src 'self'; connect-src 'self' wss:; form-action 'none'; frame-ancestors 'none'; plugin-types 'none'; base-uri 'none' Date: Tue, 04 Jun 2024 13:42:41 GMT , Body: { "code": 200, "data": { "auth_token": "6I6B6DsYd9rRSVeSgBVP" } } 20240604 13424126 - 00.119.394 20240604 13424126 debug Auth-Token: 6I6B6DsYd9rRSVeSgBVP 20240604 13424126 + marsBmcApi.TMarsBMCAPI(7faa849bc0).SendRequest 20240604 13424126 info https://192.168.7.200:18080/arm_server/info 20240604 13424126 debug Request Headers: ["Accept: application/json; charset=UTF-8","Auth-Token: 6I6B6DsYd9rRSVeSgBVP"] 20240604 13424126 debug Response: Code: 404, Headers: Strict-Transport-Security: max-age=31536000; includeSubdomains; preload X-Frame-Options: DENY Pragma: no-cache Cache-Control: no-Store,no-Cache X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff Content-Security-Policy: default-src 'none'; img-src 'self' data:; font-src 'self'; style-src 'self'; script-src 'self'; connect-src 'self' wss:; form-action 'none'; frame-ancestors 'none'; plugin-types 'none'; base-uri 'none' Date: Tue, 04 Jun 2024 13:42:41 GMT , Body: 20240604 13424126 - 00.001.556
Is really 404 returned by the server, or returned internally by the class? I am not sure. I wondered why the first api I called that Login can return the correct conten and the remains can't
Is there any 30x redirection involved? no
Can you try not with TSimpleClient but with plain THttpClientSocket? with TSimpleHttpClient.Create(true), it seems to use THttpClientSocket only . I am not sure
when I using proxy just like below all things works
constructor TMarsBMCAPI.Create(const BaseURL: string);
begin
inherited Create;
FHttpClient := TSimpleHttpClient.Create(True);
FHttpClient.IgnoreTlsCertificateErrors := True;
FHttpClient.Proxy := 'http://192.168.7.163:8888'; /// this points to the Fiddler to capture the data
FBaseURL := BaseURL;
end;
But when I disabled the proxy , it not works from the second api ('/arm_server/info') .
I added some log to TSampleHttpClient.RawRequest, and I found it use fHttp to send https request:
20240604 14172308 + marsBmcApi.TMarsBMCAPI(7f8cd75b80).SendRequest
20240604 14172308 info https://192.168.7.200:18080/login
20240604 14172308 debug Request Headers: ["Accept: application/json; charset=UTF-8"]
20240604 14172308 + mormot.net.client.TSimpleHttpClient(7f8ce353a0).RawRequest
20240604 14172308 debug Uri.Address: login, Method: POST, Header: Accept: application/json; charset=UTF-8 , Data: {"user":"root","password":"marsserver.cm"}, DataMineType: application/json; charset=UTF-8
20240604 14172316 debug fHttp: {"THttpClientSocket(7f8ce19e10)":{SocketFamily:"nfIP4",Server:"192.168.7.200",Port:"18080",RawSocket:4,TimeOut:20000,BytesIn:1250,BytesOut:324,UserAgent:"Mozilla/5.0 (Linux aarch64; mORMot) HCS/2.2 test",ContentLength:75,ContentType:"application/json"}}, Uri: login, Result: 200, fHeaders: Strict-Transport-Security: max-age=31536000; includeSubdomains; preload X-Frame-Options: DENY Pragma: no-cache Cache-Control: no-Store,no-Cache X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff Content-Security-Policy: default-src 'none'; img-src 'self' data:; font-src 'self'; style-src 'self'; script-src 'self'; connect-src 'self' wss:; form-action 'none'; frame-ancestors 'none'; plugin-types 'none'; base-uri 'none' Date: Tue, 04 Jun 2024 14:17:23 GMT , fBody: { "code": 200, "data": { "auth_token": "gs5bYYDYDTyuVLp8o4HA" } }
20240604 14172316 - 00.129.678
20240604 14172316 debug Response: Code: 200, Headers: Strict-Transport-Security: max-age=31536000; includeSubdomains; preload X-Frame-Options: DENY Pragma: no-cache Cache-Control: no-Store,no-Cache X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff Content-Security-Policy: default-src 'none'; img-src 'self' data:; font-src 'self'; style-src 'self'; script-src 'self'; connect-src 'self' wss:; form-action 'none'; frame-ancestors 'none'; plugin-types 'none'; base-uri 'none' Date: Tue, 04 Jun 2024 14:17:23 GMT , Body: { "code": 200, "data": { "auth_token": "gs5bYYDYDTyuVLp8o4HA" } }
20240604 14172316 - 00.129.808
20240604 14172316 debug Auth-Token: gs5bYYDYDTyuVLp8o4HA
20240604 14172316 + marsBmcApi.TMarsBMCAPI(7f8cd75b80).SendRequest
20240604 14172316 info https://192.168.7.200:18080/arm_server/info
20240604 14172316 debug Request Headers: ["Accept: application/json; charset=UTF-8","Auth-Token: gs5bYYDYDTyuVLp8o4HA"]
20240604 14172316 + mormot.net.client.TSimpleHttpClient(7f8ce353a0).RawRequest
20240604 14172316 debug Uri.Address: arm_server/info, Method: GET, Header: Accept: application/json; charset=UTF-8 Auth-Token: gs5bYYDYDTyuVLp8o4HA , Data: , DataMineType: application/json; charset=UTF-8
20240604 14172316 debug fHttp: {"THttpClientSocket(7f8ce19e10)":{SocketFamily:"nfIP4",Server:"192.168.7.200",Port:"18080",RawSocket:-1,TimeOut:20000,BytesIn:1250,BytesOut:581,UserAgent:"Mozilla/5.0 (Linux aarch64; mORMot) HCS/2.2 test",ContentLength:75,ContentType:"application/json"}}, Uri: arm_server/info, Result: 404, fHeaders: Strict-Transport-Security: max-age=31536000; includeSubdomains; preload X-Frame-Options: DENY Pragma: no-cache Cache-Control: no-Store,no-Cache X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff Content-Security-Policy: default-src 'none'; img-src 'self' data:; font-src 'self'; style-src 'self'; script-src 'self'; connect-src 'self' wss:; form-action 'none'; frame-ancestors 'none'; plugin-types 'none'; base-uri 'none' Date: Tue, 04 Jun 2024 14:17:23 GMT , fBody:
20240604 14172316 - 00.001.433
20240604 14172316 debug Response: Code: 404, Headers: Strict-Transport-Security: max-age=31536000; includeSubdomains; preload X-Frame-Options: DENY Pragma: no-cache Cache-Control: no-Store,no-Cache X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff Content-Security-Policy: default-src 'none'; img-src 'self' data:; font-src 'self'; style-src 'self'; script-src 'self'; connect-src 'self' wss:; form-action 'none'; frame-ancestors 'none'; plugin-types 'none'; base-uri 'none' Date: Tue, 04 Jun 2024 14:17:23 GMT , Body:
20240604 14172316 - 00.001.509
I think the bug is TLS related.
with TSimpleHttpClient.Create(True), it will raise exception :
raise ENetSock.Create('%s.DoTlsAfter: TLS support not compiled ' +
'- try including mormot.lib.openssl11 in your project',
when I added mormot.lib.openssl11 in my project, no exception raised but the response is soemthing wrong.
the workaround for it is turn on USELIBCURL swtich and using TSimpleHttpClient.Create(False) to tell the mormot to use curl lib for https request.
What if you free and re-create a TSimpleHttpClient instance for the 2nd call to https://192.168.7.200:18080/arm_server/info ?
How is implemented the server?
What is the exact URI value sent at RawRequest on THttpClientSocket ? (perhaps a missing / at the beginning?)
What if you free and re-create a TSimpleHttpClient instance for the 2nd call to https://192.168.7.200:18080/arm_server/info ?
How is implemented the server?
What is the exact URI value sent at RawRequest on THttpClientSocket ? (perhaps a missing / at the beginning?)
when I skip login and call "/arm_server/info" directly, I got the correct unauthorized body, it is correct.
but when I pass the correct auth-token returned by login to /arm_server/info call, not work again, it returns EMPTY body.
Please answer the remaining questions:
How is implemented the server? What is the exact URI value sent at RawRequest on THttpClientSocket ? (perhaps a missing / at the beginning?)
20240606 11590531 ! debug THttpClientSocket.Open, Uri.server: 192.168.7.200, Uri.Port: 18080, Uri.Https: 1, Uri.Address: arm_server/info
20240606 11590523 ! + marsBmcApi.TMarsBMCAPI(7fa1a536a0).SendRequest
20240606 11590523 ! http https://192.168.7.200:18080/login
20240606 11590523 ! http Request Headers: ["Accept: application/json; charset=UTF-8"]
20240606 11590523 ! debug THttpClientSocket.Open, Uri.server: 192.168.7.200, Uri.Port: 18080, Uri.Https: 1, Uri.Address: login
20240606 11590531 ! http Response: Code: 200, Headers: Strict-Transport-Security: max-age=31536000; includeSubdomains; preload X-Frame-Options: DENY Pragma: no-cache Cac>
20240606 11590531 ! - 00.126.576
20240606 11590531 ! debug Auth-Token: BCnlQZROc18eJYch2zpl
20240606 11590531 ! + marsBmcApi.TMarsBMCAPI(7fa1a536a0).SendRequest
20240606 11590531 ! http https://192.168.7.200:18080/arm_server/info
20240606 11590531 ! http Request Headers: ["Accept: application/json; charset=UTF-8","Auth-Token: BCnlQZROc18eJYch2zpl"]
20240606 11590531 ! debug THttpClientSocket.Open, Uri.server: 192.168.7.200, Uri.Port: 18080, Uri.Https: 1, Uri.Address: arm_server/info
20240606 11590533 ! http Response: Code: 404, Headers: , Body:
20240606 11590533 ! - 00.032.879
Here is the test code:
api := TMarsBMCAPI.Create('https://192.168.7.200:18080');
api.Login('root', 'marsserver.cm');
key := api.AuthToken;
api.Free;
api := TMarsBMCAPI.Create('https://192.168.7.200:18080');
api.AuthToken := key;
try
//api.Login('root', 'marsserver.cm');
add(api.GetServerInfo, 'GetServerInfo');
add(api.GetServerMonitorInfo, 'GetServerMonitorInfo');
add(api.GetServerPsuInfo, 'GetServerPsuInfo');
add(api.GetServerFanInfo, 'GetServerFanInfo');
add(api.GetNodeSummary('0'), 'GetNodeSummary');
add(api.GetAllNodeStatus, 'GetAllNodeStatus');
add(api.GetAllNodeInfo, 'GetAllNodeInfo');
add(api.GetAllNodeNetworkInfo, 'GetAllNodeNetworkInfo');
add(api.GetAllNodeMonitorInfo, 'GetAllNodeMonitorInfo');
add(api.GetAllNodeInfoV2, 'GetAllNodeInfoV2');
add(api.GetAllNodePortInfo, 'GetAllNodePortInfo');
writeln('press [enter] to quit');
readln;
finally
api.Free;
end;
Please debug a little and try to check about my question:
What is the exact URI value sent at RawRequest on THttpClientSocket ? (perhaps a missing / at the beginning?)
I think it already insert a '/' at the beginning in the code Request:
function THttpClientSocket.Request(const url, method: RawUtf8;
KeepAlive: cardinal; const Header: RawUtf8; const Data: RawByteString;
const DataMimeType: RawUtf8; retry: boolean; InStream, OutStream: TStream): integer;
var
ctxt: THttpClientRequest;
newuri: TUri;
log: ISynLog;
begin
log := TSynLog.Add.Enter(Self, 'Request');
ctxt.Url := url;
if (url = '') or
(url[1] <> '/') then
insert('/', ctxt.Url, 1); // normalize URI as in RFC (e.g. for Digest auth)
Here is more output in the log:
the log code is here:
SOLVED: at last, I found the reason that I add a redundant header into the request:
Uri := FBaseUrl + Endpoint;
Headers := TStringList.Create;
Headers.Add('Accept: ' + mimetype); // HERE is redundant, when delete this line, everything is working properly
if FAuthToken <> '' then
Headers.Add('Auth-Token: ' + FAuthToken);
Safe.Lock;
try
case Method of
'GET':
Response := FHttpClient.Request(Uri, 'GET', Headers.Text, Params, mimetype);
'POST':
Response := FHttpClient.Request(Uri, 'POST', Headers.Text, Params, mimetype);
'PUT':
Response := FHttpClient.Request(Uri, 'PUT', Headers.Text, Params, mimetype);
'DELETE':
Response := FHttpClient.Request(Uri, 'DELETE', Headers.Text, Params, mimetype);
end;
finally
Safe.UnLock;
Headers.Free;
end;
My guess is more that you should not use TSTRingList for headers, because on POSIX I suspect it uses LF for line feeds, instead of CR+LF as expected by HTTP.
My guess is more that you should not use TSTRingList for headers, because on POSIX I suspect it uses LF for line feeds, instead of CR+LF as expected by HTTP.
So, I should use RawUtf8 and manually add LF for every line ?
When adding something to headers using TStringList.Add
, the request fails. I'm wondering why even when I set Header.LineBreak
to #10
, it still doesn't work. I'm also curious why the curl library works fine.
I guess libcurl
is re-formatting the headers content.
The LineBreak should be #13#10
.
But you can call AppendLine()
from mormot.core.text.pas to generate the HTTP headers directly in a RawUtf8 variable.
You are right! It works when I use #13#10
as TStringList.LineBreak
. It is a better way that use AppendLine
to headers RawUtf8 varaible.
turn off the USELIBCURL switch, and with TSimpleHttpClient.Create(true), we get 404 error , here is the log:
turn on the USELIBCURL swith, and with TSimpleHttpClient.Create(), all thing are right! here is the log: