amit 3 Posted March 31, 2021 (edited) I want to use TIdHttp or THTTPClient to send this following curl command. curl -X POST https://notify-api.line.me/api/notify -H "Authorization: Bearer U4314taadsffhjjjjykllFVissffdfssdfsdfsgfgz" -F "message=abcTest" -F "stickerPackageId=1" -F "stickerId=113" -F "imageFile=@D:/mypic.jpg" Could you please help me convert this command to Delphi Code using indyhttp or THttpClient? Edited March 31, 2021 by amit Share this post Link to post
david_navigator 12 Posted March 31, 2021 (edited) Can you use the in built delphi REST Debugger to help ? Edited March 31, 2021 by david_navigator 1 Share this post Link to post
Uwe Raabe 2057 Posted March 31, 2021 Cannot test it from here, so something is probably still missing, but it might look like this one: uses System.SysUtils, REST.Client, REST.Authenticator.OAuth, REST.Types; procedure Main; var auth: TOAuth2Authenticator; client: TRESTClient; request: TRESTRequest; response: TCustomRESTResponse; begin client := TRESTClient.Create(nil); try client.BaseURL := 'https://notify-api.line.me'; auth := TOAuth2Authenticator.Create(nil); try auth.TokenType := TOAuth2TokenType.ttBearer; auth.AccessToken := 'U4314taadsffhjjjjykllFVissffdfssdfsdfsgfgz'; client.Authenticator := auth; request := TRESTRequest.Create(nil); try request.Client := client; request.Method := rmPOST; request.Resource := 'api/notify'; request.AddParameter('message', 'abcTest', pkREQUESTBODY); request.AddParameter('stickerPackageId', '1', pkREQUESTBODY); request.AddParameter('stickerId', '113', pkREQUESTBODY); request.AddParameter('imageFile', 'D:\mypic.jpg', pkFILE); request.Execute; response := request.Response; if response.Status.Success then begin Writeln('Success: ' + response.Content); end else begin Writeln('Failed with ' + response.StatusText + ': ' + response.Content); end; finally request.Free; end; finally auth.Free; end; finally client.Free; end; end; 1 Share this post Link to post
amit 3 Posted April 1, 2021 I wonder what is the equivalent command for TIdHTTP and THTTPClient if they were used instead of TRESTClient. request.AddParameter('message', 'abcTest', pkREQUESTBODY); request.AddParameter('stickerPackageId', '1', pkREQUESTBODY); request.AddParameter('stickerId', '113', pkREQUESTBODY); request.AddParameter('imageFile', 'D:\mypic.jpg', pkFILE); Share this post Link to post
amit 3 Posted April 1, 2021 Now I knew how to use TIdHttp and THttpClient instead of TRESTClient. For Indy TidHttp, use TIdMultiPartFormDataStream for adding all Parameters. For THttpClient, use TMultipartFormData for adding all Parameters Uwe Raabe, Thank for all helps. Share this post Link to post
Remy Lebeau 1394 Posted April 1, 2021 12 hours ago, amit said: I wonder what is the equivalent command for TIdHTTP and THTTPClient if they were used instead of TRESTClient. The TIdHTTP version would look like this: uses ..., IdHTTP, IdSSLOpenSSL, IdMultipartFormDataStream; var HTTP: TIdHTTP; SSL: TIdSSLIOHandlerSocketOpenSSL; Params: TIdMultipartFormDataStream; begin HTTP := TIdHTTP.Create; try SSL := TIdSSLIOHandlerSocketOpenSSL.Create(HTTP); SSL.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2]; // other options as needed... HTTP.IOHandler := SSL; HTTP.Request.BasicAuthentication := False; HTTP.Request.CustomHeaders.Values['Authorization'] := 'Bearer U4314taadsffhjjjjykllFVissffdfssdfsdfsgfgz'; // or: HTTP.Request.CustomHeaders.AddValue('Authorization', 'Bearer U4314taadsffhjjjjykllFVissffdfssdfsdfsgfgz'); Params := TIdMultipartFormDataStream.Create; try Params.AddFormField('message', 'abcTest'); Params.AddFormField('stickerPackageId', '1'); Params.AddFormField('stickerId', '113'); Params.AddFile('imageFile', 'D:\mypic.jpg'); HTTP.Post('https://notify-api.line.me/api/notify', Params); finally Params.Free; end; finally HTTP.Free; end; end; 1 Share this post Link to post
amit 3 Posted April 2, 2021 (edited) Thank you Remy. I had created the indy version before you reply. in my version, I did not include IdSSLOpenSSL unit in uses clause and no SSL as shown in your code. However, it works. I just wonder if I should use SSL as you suggested. I'm not sure if I did not use it, it may have problem sometime or not. Edited April 2, 2021 by amit Share this post Link to post
Remy Lebeau 1394 Posted April 2, 2021 28 minutes ago, amit said: I had created the indy version before you reply. in my version, I did not include IdSSLOpenSSL unit in uses clause and no SSL as shown in your code. However, it works. Probably due to this feature: https://www.indyproject.org/2014/12/22/new-https-functionality-for-tidhttp/ 28 minutes ago, amit said: I just wonder if I should use SSL as you suggested. You MUST use an SSLIOHandler if you want to access an HTTPS url. Whether you create your own SSLIOHandler object, or let TIdHTTP create one implicitly, is a separate matter. 2 Share this post Link to post
amit 3 Posted April 4, 2021 HI Remy, I wonder why it can be used on my development PC but not on the target PC. I got this error on the Target PC - EIdOSSLCouldNotLoadSSLLibrary: Could not load SSL library. I knew it concerned to SSL libeay32.dll and ssleay32.dll. I copied it to the application folder but it still have this error. Can you suggest what should I do? Share this post Link to post
KodeZwerg 54 Posted April 4, 2021 (edited) 1 hour ago, amit said: I wonder why it can be used on my development PC but not on the target PC. I got this error on the Target PC - EIdOSSLCouldNotLoadSSLLibrary: Could not load SSL library. I knew it concerned to SSL libeay32.dll and ssleay32.dll. I copied it to the application folder but it still have this error. Very possible that you run into a version conflict. Check used Delphi Indy version and use for that proper libraries. //tip To find out the location of the "good" library (on your development pc), download a tool like ProcessHacker, run your application, let it load libraries, open ProcessHacker, doubleclick on your process, switch to "Modules" tab, either move mouse over library or doubleclick library, both result in telling you location. Edited April 4, 2021 by KodeZwerg 1 Share this post Link to post
Remy Lebeau 1394 Posted April 4, 2021 17 hours ago, amit said: I wonder why it can be used on my development PC but not on the target PC. I got this error on the Target PC - EIdOSSLCouldNotLoadSSLLibrary: Could not load SSL library. I knew it concerned to SSL libeay32.dll and ssleay32.dll. I copied it to the application folder but it still have this error. Can you suggest what should I do? You likely copied an incompatible version of the OpenSSL DLLs. For instance, if you copied OpenSSL 1.1.x, as TIdSSLIOHandlerSocketOpenSSL supports only up to OpenSSL 1.0.2 (use this SSLIOHandler instead for 1.1.x). Or, if you copied 32bit DLLs for a 64bit app, or vice versa. What do Indy's OpenSSLVersion() and WhichFailToLoad() functions report? 1 Share this post Link to post
polasss 0 Posted January 28, 2023 (edited) On 4/1/2021 at 6:15 PM, Remy Lebeau said: The TIdHTTP version would look like this: uses ..., IdHTTP, IdSSLOpenSSL, IdMultipartFormDataStream; var HTTP: TIdHTTP; ..... Hi, I'm trying to convert the cUrl for TIdHttp but no success. Can you please tell me where i am wrong? (BAD REQUEST) curl https://api.dropbox.com/oauth2/token \ -d code=<AUTHORIZATION_CODE> \ -d grant_type=authorization_code \ -u <APP_KEY>:<APP_SECRET> My (bad) convert: ( ........ SOLVED !!! - see the solution below ............) IdHTTP := TIdHTTP.Create(nil); try //'curl https://api.dropbox.com/oauth2/token \ -d code=<AUTHORIZATION_CODE> \ -d grant_type=authorization_code \ -u <APP_KEY>:<APP_SECRET>' ssl := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP); ssl.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2]; ssl.SSLOptions.Mode := TidSSLMode.sslmUnassigned; ssl.SSLOptions.VerifyMode := []; ssl.SSLOptions.VerifyDepth := 0; ssl.host := ''; //ssl.OnStatusInfoEx := __IdSSLIOHandlerSocketOpenSSL1StatusInfoEx; ssl.DefStringEncoding := IndyTextEncoding_UTF8; IdHTTP.HandleRedirects := True; IdHTTP.IOHandler := ssl; IdHTTP.Request.BasicAuthentication := False; IdHTTP.Request.Username := 'MY_APP_KEY'; IdHTTP.Request.Password := 'MY_APP_SECRET'; Params := TIdMultipartFormDataStream.Create; try Result := True; Params.AddFormField('code', 'MY_AUTH_CODE'); Params.AddFormField('grant_type', 'authorization_code'); aStatus := IdHTTP.Post('https://api.dropbox.com/oauth2/token', Params); except on E: EIdHTTPProtocolException do begin Result := false; aStatus := ErrorResult(IdHTTP.ResponseText); end; end; (**) finally //SSLstatusInfo := fStatusSSLInfo; ssl.Free; IdHTTP.Free; end; ************* SOLVED ******************************************************* IdHTTP.Request.BasicAuthentication := TRUE; IdHTTP.Request.ContentType := 'application/x-www-form-urlencoded'; ******************************************************************************** and USES is displayed incorrectly uses ..., IdMultipartFormDataStream; correct uses ..., IdMultipartFormData; thanks for Lemy ! Edited January 29, 2023 by polasss Share this post Link to post
Remy Lebeau 1394 Posted January 30, 2023 (edited) On 1/28/2023 at 1:28 AM, polasss said: Hi, I'm trying to convert the cUrl for TIdHttp but no success. Can you please tell me where i am wrong? The original curl request of this discussion thread uses the "-F" parameter, whereas your request uses the "-d" parameter instead. If you read curl's documentation, the "-F" parameter sends an HTTP "multipart/form-data" request, whereas the "-d" parameter sends an HTTP "application/x-www-form-urlencoded" request. The TIdHTTP.Post() method has separate overloads for those types of requests. Your code is using the wrong overload. You need to use the overload that takes a TStrings, not a TIdMultipartFormDataStream, eg: Result := False; IdHTTP := TIdHTTP.Create(nil); try //'curl https://api.dropbox.com/oauth2/token \ -d code=<AUTHORIZATION_CODE> \ -d grant_type=authorization_code \ -u <APP_KEY>:<APP_SECRET>' ssl := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP); ssl.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2]; ssl.SSLOptions.Mode := TidSSLMode.sslmUnassigned; ssl.SSLOptions.VerifyMode := []; ssl.SSLOptions.VerifyDepth := 0; //ssl.OnStatusInfoEx := __IdSSLIOHandlerSocketOpenSSL1StatusInfoEx; IdHTTP.HandleRedirects := True; IdHTTP.IOHandler := ssl; IdHTTP.Request.BasicAuthentication := True; IdHTTP.Request.Username := 'MY_APP_KEY'; IdHTTP.Request.Password := 'MY_APP_SECRET'; try Params := TStringList.Create; try Params.Add('code=MY_AUTH_CODE'); Params.Add('grant_type=authorization_code'); aStatus := IdHTTP.Post('https://api.dropbox.com/oauth2/token', Params); Result := True; finally Params.Free; end; except on E: EIdHTTPProtocolException do begin aStatus := ErrorResult(IdHTTP.ResponseText); end; end; (**) finally IdHTTP.Free; end; Edited January 30, 2023 by Remy Lebeau Share this post Link to post