Autor Téma: odeslání cURL prostřednictvím INDY  (Přečteno 221 krát)

Offline Pavel Bílek

  • Nováček
  • *
  • Příspěvků: 3
  • Karma: 0
    • Verze Delphi: Delphi 10
odeslání cURL prostřednictvím INDY
« kdy: 08-11-2017, 21:14:09 »
Prosím o pomoc s odesláním cURL příkazu z Delphi 10 prostřednictvím INDY  (10.6.2..)

curl -v -s -u 'uzivatel:heslo' -H "Content-Type: multipart/form-data" -H "Accept: application/vnd.de.mobile.api+json" -F "image=@c:\foto1.jpg;type=image/jpeg" -XPUT 'https://services.mobile.de/seller-api/sellers/17227442/ads/253118210/images'

JDE o přidání fotografie ke stávajícímu inzerátu vozidla na inzertním serveru MOBILE.DE
dokumentace API rozhraní je zde: https://services.mobile.de/docs/seller-api.html#_upload_images
Upload Images

Volání uvedeného cURL z příkazového řádku použil jsem např. CygWin64 Terminal FUNGUJE ok.

CO NEFUNGUJE:


Function UPLOAD_IMAGES:boolean;
var
HTTP :TidHttp;
Name, Password : string;
HOST, Adress: string;
Vystup, Response_text : string;
Stream: TMemoryStream;
Response : TstringStream;
slPostData: TIdMultiPartFormDataStream;
Response_Code: integer;

uploadStream: TIdMultipartFormDataStream;
oMem: TMemoryStream;

Begin
  Stream:=TMemoryStream.Create;
  slPostData:= TIdMultiPartFormDataStream.Create;
  oMem:=TMemoryStream.Create;
  oMem.LoadFromFile('c:\LOGO.JPEG');
  uploadStream := TIdMultiPartFormDataStream.Create;
  With Form_sAuto do
  Begin
    zipStream := TIdMultiPartFormDataStream.Create;
    Name:='XXXX';
    Password:='ZZZZ';
    Response := TStringStream.Create;
    HTTP:=Form_sAuto.idHttp.Create;
    HOST:='https://services.mobile.de';
    HTTP.Request.Clear;
    HTTP.Request.Accept:='application/vnd.de.mobile.api+json';
    HTTP.Request.ContentType:='multipart/form-data; boundary=vjrLeiXjJaWiU0JzZkUPO1rMcE2HQ-n7XsSx';
    HTTP.Request.BasicAuthentication:=True;
    HTTP.Request.Username:=Name;
    HTTP.Request.Password:=Password;
    uploadStream.AddFormField('image','image/jpeg','', oMem,'LOGO.JPEG');
    Adress :='https://services.mobile.de/seller-api/sellers/17227442/ads/253118210/images';
    Response_text := HTTP.PUT(Adress, uploadStream);
    oMem.Free;
    HTTP.Free;
    uploadStream.Free;
  End
End;

CO JE ZA PROBLÉM:
- funkce proběhne bez chyby, server požadavek zpracuje, foto se na server odešle
STATUS  KOMUNIKACE: HTTP/1.1 200 OK
ŽÁDNÉ PŘIŘAZENÉ FOTO:  {"images":[]}  navrácena by měla být cesta k úspěšně přiřazeným foto.  ŽÁDNÉ FOTO NEPŘIDÁNO

Slovy klasika: "Chodí to dobře, ale neseje to...."

TECHNICKÁ PODPORA MOBILE.DE SE K PROBLÉMU VYJÁDŘILA TAKTO:

Thanks for your response.
The answer quotes directly the working call examples for uploading calls for ads. Otherwise we are not able to check anything particular.
In that case something goes wrong at your end.
We had the same report from another dev. He was able to figure out the problem behind the issue, maybe it helps to enlighten a bit:
Sadly he was working with PHP but maybe you are able to adapt the solution at your end:
The $postfields from his curl_custom_postfields function is an array.
$postfields[0] is for multipart and $postfields[1] is for boundary ( $boundary = "---------------------" . md5(mt_rand() . microtime()); )

The mistake was made with CURLOPT_POSTFIELDS => $postfields[0],
He submitted the complete array with ( CURLOPT_POSTFIELDS => $postfields, ),

The response was 200 but the image[] element was empty.
Below you can find the correct curl command for PHP (if it is usefull for you):
private function updatePictures($url,$images) {
 $postfields = $this->curl_custom_postfields($images);
 $ch = curl_init();
 $options = array(
  CURLOPT_URL => $url,
  CURLOPT_TIMEOUT => 60,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HEADER => true,
  CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
  CURLOPT_USERPWD => "$this->username:$this->password",
  CURLOPT_HTTPHEADER => array("Content-Type: multipart/form-data; boundary=".$postfields[1],"Accept: application/vnd.de.mobile.api+json"),
  CURLOPT_VERBOSE => true,
  CURLOPT_CUSTOMREQUEST => "PUT",
  CURLOPT_POSTFIELDS => $postfields[0],
 );
 curl_setopt_array($ch, $options);
 $result = curl_exec($ch);
 $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
 return array('status'=>$status_code,'data'=>$result);
}

Hope this helps a bit.


DOKÁŽE PROSÍM NĚKDO PORADIT, KDE BYCH MOHL DĚLAT CHYBU ČI CO VYZKOUŠET, JAK POSTUPOVAT PŘI ŘEŠENÍ PROBLÉMU, PŘÍPADNĚ JAK JINAK PŘÍKAZ cURL v Delphi zpracovat..

DÍKY MOC ZA KAŽDÝ POSUN V ŘEŠENÍ PROBLÉMU.

Offline mirus

  • Nováček
  • *
  • Příspěvků: 31
  • Karma: 8
    • Verze Delphi: Delphi 10.2
Re:odeslání cURL prostřednictvím INDY
« Odpověď #1 kdy: 09-11-2017, 08:58:31 »
Excellent
Rated 1 time
Zdravím,
zkus, přidat řádek oMem.Seek.

Kód: Delphi [Vybrat]
  1.   ...
  2.   oMem:=TMemoryStream.Create;
  3.   oMem.LoadFromFile('c:\LOGO.JPEG');
  4.   oMem.Seek(0,soFromBeginning); // nové
  5.   ...
  6.  

Offline Pavel Bílek

  • Nováček
  • *
  • Příspěvků: 3
  • Karma: 0
    • Verze Delphi: Delphi 10
Re:odeslání cURL prostřednictvím INDY
« Odpověď #2 kdy: 09-11-2017, 09:17:39 »
DÍKY ZA SNAHU, VYZKOUŠEL JSEM PŘIDAT
 oMem.Seek(0,soFromBeginning); // nové

VÝSLEDEK JE BOHUŽEL STEJNÝ.... máte nějaký další nápad?

P.B.

Offline Ján Masaryk

  • Nováček
  • *
  • Příspěvků: 47
  • Karma: 5
    • Verze Delphi: 2010
Re:odeslání cURL prostřednictvím INDY
« Odpověď #3 kdy: 09-11-2017, 13:05:16 »
Máš tam toto 'https://services.mobile.de/seller-api/sellers/17227442/ads/253118210/images'

skús toto

'https://services.mobile.de/seller-api/sellers/17227442/ads/253118210/images/'  :)

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 1845
  • Karma: 87
    • Verze Delphi: D2007, XE3, DX10
Re:odeslání cURL prostřednictvím INDY
« Odpověď #4 kdy: 09-11-2017, 13:47:29 »
Excellent
Rated 1 time
Volání uvedeného cURL z příkazového řádku použil jsem např. CygWin64 Terminal FUNGUJE ok.
[...]
- funkce proběhne bez chyby, server požadavek zpracuje, foto se na server odešle
Ja bych udelal capture komunikace HTTP protokolem v pripade commad line a Indy.

Nejaky WireShark, TcpDump nebo Microsoft Network monitor, co mi umozni exportovat komunikaci do textoveho souboru a ty soubory bych nejakym vyspelym textovym comparatorem jako je Araxis Merge porovnal, v cem se to lisi.

Offline < z >

  • Administrátoři
  • Guru
  • *****
  • Příspěvků: 1083
  • Karma: 38
    • Verze Delphi: 7, 2010
Re:odeslání cURL prostřednictvím INDY
« Odpověď #5 kdy: 09-11-2017, 17:38:29 »
Excellent
Rated 1 time
V tom tvým kódu aby se ... vyznalo.

Tím nastavením ContentType jsi to rozbil. Nemůžeš si tam jen tak náhodně okopírovat jejich hodnotu.
U Post to běžně Indy nastaví samy, protože TIdMultiPartFormDataStream si boundary generuje při vytvoření.
Tobě by mělo stačit přečíst si z property Boundary a přiřadit tam správnou hodnotu.

Offline Pavel Bílek

  • Nováček
  • *
  • Příspěvků: 3
  • Karma: 0
    • Verze Delphi: Delphi 10
Re:odeslání cURL prostřednictvím INDY
« Odpověď #6 kdy: 09-11-2017, 20:35:44 »
Guru má palec nahoru, problém díky jeho návodu vyřešen.

Problém byl opravdu v ContentType resp. chybně uvedeném Boundary, po přiřazené správného, které vygenerovalo Indy je komunikace v pořádku. Foto se odešle správně.

Díky moc za pomoc!

 

S rychlou odpovědí můžete používat BB kódy a emotikony jako v běžném okně pro odpověď, ale daleko rychleji.

Jméno: E-mail:
Ověření:
Křestní jméno zpěváka Gotta: