2012-05-26 14 views
12

Mam prosty skrypt php na moim serwerze WWW, który muszę przesłać plik za pomocą HTTP POST, który robię w Delphi.Http Post z indykiem

Oto mój kod z Indy ale aparantely to nie zadziała i nie mogę dowiedzieć się, co robię niewłaściwie. Jak mogę zobaczyć, co wysyłam na serwerze, czy istnieje takie narzędzie?

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

"To nie działa" jest najmniej użyteczną frazą możliwą podczas debugowania czegoś. Co nie działa? Co robi źle? –

+0

@MasonWheeler, jeśli znałem odpowiedź prawdopodobnie nie zadawałem tego pytania. Nie przesyła ona na serwer sieciowy, ale moim zdaniem, nagłówek postu jest zniekształcony, ale nie wiem, co robię źle. – opc0de

+0

dlaczego jest MS.Clear; wywoływana przed http.Post (URL, MS)? – ComputerSaysNo

Odpowiedz

18

Indy ma TIdMultipartFormDataStream do tego celu:

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

Działa, ale chcę wiedzieć, co robiłem źle w moim kodzie ... – opc0de

+1

Użyj wireshark i porównać nagłówek wyprodukowany przez twój kod i Indy? – whosrdaddy

+0

Jest to tak oczywiste, że 'TIdMultipartFormDataStream' jest przesyłanym komponentem, którego szukałem, skąd tęsknię? :) –

2

Wywołanie PHP z Indy może nie ze względu na User-Agent, a następnie pojawi się błąd 403.

Spróbuj w ten sposób, że stała się dla mnie:

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

Straciłeś 2 znaki '-'. Lepiej to zrobić:

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