2012-05-26 21 views
12

Ho un semplice script php sul mio server web che ho bisogno di caricare un file utilizzando HTTP POST, che sto facendo in Delphi.Post Http con indy

Ecco il mio codice con Indy ma in modo non funzionante non funzionerà e non riesco a capire cosa non sto facendo correttamente. Come posso visualizzare ciò che invio sul server: esiste un tale strumento?

procedure TForm1.btn1Click(Sender: TObject); 
var 
    fname : string; 
    MS,dump : TMemoryStream; 
    http : TIdHTTP; 

const 
    CRLF = #13#10; 
begin 
    if PromptForFileName(fname,'','','','',false) then 
    begin 
    MS := TMemoryStream.Create(); 
    MS.LoadFromFile(fname); 
    dump := TMemoryStream.Create(); 
    http := TIdHTTP.Create(); 
    http.Request.ContentType:='multipart/form-data;boundary =-----------------------------7cf87224d2020a'; 
    fname := CRLF + '-----------------------------7cf87224d2020a' + CRLF + 'Content-Disposition: form-data; name=\"uploadedfile\";filename=\"test.png"' + CRLF; 
    dump.Write(fname[1],Length(fname)); 
    dump.Write(MS.Memory^,MS.Size); 
    fname := CRLF + '-----------------------------7cf87224d2020a--' + CRLF; 
    dump.Write(fname[1],Length(fname)); 
    ShowMessage(IntToStr(dump.Size)); 
    MS.Clear; 
    try 
    http.Request.Method := 'POST'; 
    http.Post('http://posttestserver.com/post.php',dump,MS); 
    ShowMessage(PAnsiChar(MS.Memory)); 
    ShowMessage(IntToStr(http.ResponseCode)); 
    except 
    ShowMessage('Could not bind socket'); 
    end; 
    end; 
end; 
+2

"Non funziona" è la frase meno utile possibile quando si esegue il debug di qualcosa. Cosa non funziona? Cosa fa di sbagliato? –

+0

@MasonWheeler se conoscessi la risposta probabilmente non stavo facendo questa domanda. Non caricare sul server web il problema, suppongo che l'intestazione del post sia malformata, ma non so cosa sto facendo male. – opc0de

+0

perché è MS.Clear; chiamato prima di http.Post (URL, MS)? – ComputerSaysNo

risposta

18

Indy ha TIdMultipartFormDataStream per questo scopo:

procedure TForm1.SendPostData; 
var 
    Stream: TStringStream; 
    Params: TIdMultipartFormDataStream; 
begin 
    Stream := TStringStream.Create(''); 
    try 
    Params := TIdMultipartFormDataStream.Create; 
    try 
    Params.AddFile('File1', 'C:\test.txt','application/octet-stream'); 
    try 
    HTTP.Post('http://posttestserver.com/post.php', Params, Stream); 
    except 
    on E: Exception do 
     ShowMessage('Error encountered during POST: ' + E.Message); 
    end; 
    ShowMessage(Stream.DataString); 
    finally 
    Params.Free; 
    end; 
    finally 
    Stream.Free; 
    end; 
end; 
+0

Funziona ma vorrei sapere cosa stavo facendo male nel mio codice ... – opc0de

+1

Usa wireshark e confronta l'intestazione prodotta dal tuo codice e Indy ?? – whosrdaddy

+0

Ovviamente, 'TIdMultipartFormDataStream' è il caricamento di un componente di file che ho cercato come mi è mancato? :) –

2

Chiamare un PHP da Indy può fallire a causa della User-Agent, quindi si ottiene 403 errori.

Prova questo modo, è fissato per me:

var Answer: string; 
begin 
    GetHTML:= TIdHTTP.create(Nil); 
    try 
    GetHTML.Request.UserAgent:= 'Mozilla/3.0'; 
    Answer:= GetHTML.Get('http://www.testserver.com/test.php?id=1'); 
    finally 
    GetHTML.Free; 
    end; 
end; 
0

hai perso 2 caratteri '-'. È meglio farlo:

http.Request.ContentType:='multipart/form-data;boundary='+myBoundery; 
fname := CRLF + '--' + myBoundery + CRLF + 'Content-Disposition: form-data; name=\"uploadedfile\";filename=\"test.png"' + CRLF;