philipp.hofmann 4 Posted October 10, 2023 The following curl-test works fine on my machine: curl -X POST https://pushinglimits.club/api/oauth/upload_single_fit_file -H 'Content-Type: multipart/form-data' -H 'Authorization: Bearer ...' -F 'file=@Philipp_(SF6KICKR)_20231003_1941_Freies_Training_Training.fit' But the corresponding Delphi-Code will return 10:29:08.213 16488-Info Response: 404 Not Found: <!DOCTYPE html> <html lang="en"><head><meta charset="utf-8"><title>Error</title></head><body><pre>Cannot POST /oauth/upload_single_fit_file</pre></body></html> What could be a difference between both calls? I try to join the GenerateBoundary in System.Net.Mime but it's still not working. Http: TNetHTTPClient; formData: TMultipartFormData; headers: TNetHeaders; Http:=TNetHTTPClient.create(nil); Http.SecureProtocols := [THTTPSecureProtocol.TLS12]; formData:=TMultipartFormData.create(); headers:=TNetHeaders.create(); setLength(headers, 2); headers[0]:=TNameValuePair.create('Content-Type', 'multipart/form-data'); headers[1]:=TNameValuePair.create('Authorization', 'Bearer ' + bearer); formData.AddFile('file', filename); Http.Post('https://pushinglimits.club/api/oauth/upload_single_fit_file',formData,nil,headers); Share this post Link to post
philipp.hofmann 4 Posted October 10, 2023 Info: I was successful with the following code (using Indy now): with TIdHTTP.Create(nil) do try var FIdSSLIOHandlerSocketOpenSSL:TIdSSLIOHandlerSocketOpenSSL:=TIdSSLIOHandlerSocketOpenSSL.Create(nil); var Params: TIdMultiPartFormDataStream; filename:=StringReplace(Training.filename, '.ictt', '.fit', [rfIgnoreCase]); FIdSSLIOHandlerSocketOpenSSL.SSLOptions.Method := sslvTLSv1_2; FIdSSLIOHandlerSocketOpenSSL.SSLOptions.SSLVersions := [sslvTLSv1_2]; IOHandler := FIdSSLIOHandlerSocketOpenSSL; Request.ContentType := 'multipart/form-data'; Request.CustomHeaders.add('Authorization: Bearer ' + bearer); Params := TIdMultiPartFormDataStream.Create; try params.AddFile('file', filename, GetMIMETypeFromFile(filename)); ResponseStr := Post('https://pushinglimits.club/api/oauth/upload_single_fit_file', Params); finally Params.Free; end; finally Free; end; 1 Share this post Link to post
Die Holländer 20 Posted October 10, 2023 Is it only me wondering why people are using more and more inline variable declarations in Delphi code? with TIdHTTP.Create(nil) do try var FIdSSLIOHandlerSocketOpenSSL:TIdSSLIOHandlerSocketOpenSSL:=TIdSSLIOHandlerSocketOpenSSL.Create(nil); var Params: TIdMultiPartFormDataStream; Share this post Link to post
philipp.hofmann 4 Posted October 10, 2023 Sorry, this was copy and paste from an example and it's only to demonstrate that there is an alternative approach. I won't use inline variables in my projects normally. Share this post Link to post
Uwe Raabe 1891 Posted October 10, 2023 IMHO using inline variables and with together looks somewhat strange. 2 Share this post Link to post
Remy Lebeau 1263 Posted October 10, 2023 (edited) 11 hours ago, philipp.hofmann said: What could be a difference between both calls? Did you notice the URL is different in the response HTML? The leading /api was removed. That implies to me (without proof to the contrary - does TNetHTTPClient offer any kind of debug output?) that the server probably didn't like something about the initial request and issued an HTTP redirect to a new URL that happens to not exist. Sounds like a problem with the way the server is processing TNetHTTPClient's reequest, considering the same request in TIdHTTP works. Edited October 10, 2023 by Remy Lebeau 2 Share this post Link to post
Remy Lebeau 1263 Posted October 10, 2023 (edited) 11 hours ago, philipp.hofmann said: Info: I was successful with the following code (using Indy now): On a side note, you are leaking the SSLIOHandler object. You are not assigning it an Owner, so you need to Free() it. Otherwise, I suggest assigning the TIdHTTP at its Owner, eg: var HTTP := TIdHTTP.Create(nil); try var SSL := TIdSSLIOHandlerSocketOpenSSL.Create(HTTP); SSL.SSLOptions.SSLVersions := [sslvTLSv1_2]; HTTP.IOHandler := SSL; HTTP.Request.CustomHeaders.Values['Authorization'] := 'Bearer ' + bearer; var Params := TIdMultiPartFormDataStream.Create; try filename := StringReplace(Training.filename, '.ictt', '.fit', [rfIgnoreCase]); params.AddFile('file', filename); ResponseStr := HTTP.Post('https://pushinglimits.club/api/oauth/upload_single_fit_file', Params); finally Params.Free; end; finally HTTP.Free; end; Edited October 10, 2023 by Remy Lebeau 1 Share this post Link to post