Upload po HTTP przez Indy

0

Witam,

Chcę przesłać plik do skryptu PHP jako multipart/form-data. Wszystko co udało mi się znaleźć sprowadza się do jednego artykułu, więc się do niego zastosowałem. Użyłem MsMultiPartFormData, przekazuję wszystkie dane i upload jest w trakcie, OnWork jest wywoływane. Ale potem plik "ginie".

Skrypt PHP jest sprawny, mogę do tego samego skryptu przesyłać pliki z formularza HTML w przeglądarce i pliki się zapisują. Ale jeśli przesyłam z programu, nic się nie zapisuje. Sprawdzałem na dwóch serwerach - jednym lokalnym, jednym zdalnym.

Mój skrypt:

<?php
if (!empty($_FILES)) {
  $tempFile = $_FILES['Filedata']['tmp_name'];  
  $targetFile = 'uploads/' . date('ymd_His') . '_' . $_FILES['Filedata']['name'];
  
  move_uploaded_file($tempFile, $targetFile);
  echo str_replace($_SERVER['DOCUMENT_ROOT'], '', $targetFile);
}
?>

Wysyłanie:

procedure TfUpload.bUploadClick(Sender: TObject);
var
  ResponseStream: TMemoryStream;
  MultiPartFormDataStream: TMsMultiPartFormDataStream;
  i: Integer;
  li: TListItem;
begin
  MultiPartFormDataStream := TMsMultiPartFormDataStream.Create;
  ResponseStream := TMemoryStream.Create;
  try
    IdClient.Request.ContentType := MultiPartFormDataStream.RequestContentType;

    // dodawanie POST-ów z listy, pozostawiam pustą - nieistotne
    for i := 0 to lvPost.Items.Count - 1 do
    begin
      li := lvPost.Items[i];
      MultiPartFormDataStream.AddFormField(li.Caption, li.SubItems[0]);
    end;

    MultiPartFormDataStream.AddFile(eField.Text, eFile.Text, eMime.Text); //"Filedata", ścieżka, "application/octet-stream"
    MultiPartFormDataStream.PrepareStreamForDispatch;
    MultiPartFormDataStream.Position := 0;
    IdClient.Post(eUrl.Text, MultiPartFormDataStream, ResponseStream);
  finally
    MultiPartFormDataStream.Free;
    ResponseStream.Free;
  end;
end;

Jeśli ktoś spotkał się z takim problemem, byłbym bardzo wdzięczny za podanie rozwiązania.

Pozdrawiam,
maxi

1

Kod jest prawidłowy wiec powinno działać dobrze i u mnie działa (sprawdziłem na indy 10) więc jedynie czego się mogę doczepić to serwera. Może nie ma uprawnień do tego katalogu sprawdź atrybuty, źle skonfigurowany serwer (brak katalogu temp lub błędna ścieżka lub w co wątpię mylisz nazwę pola typu file. wyrzuć sobie jakimś print_r zawartość $_FILES.

print_r($_FILES);

i pobierz do jakiegoś Memo odpowiedź serwera:

ResponseStream.Position:= 0;
    Memo1.Lines.LoadFromStream(ResponseStream);;

Wśród kodu HTML otrzymasz coś w stylu:

Array
(
    [Filedata] => Array
        (
            [name] => nazwatestowegopliku.txt
            [type] => application/octet-stream
            [tmp_name] => /tmp/phpXJKRR3
            [error] => 0
            [size] => 179
        )

)

Napisz co Ci wyszło to pomyślimy dalej. Innego pomysłu na razie nie mam.

0

Dodałem do skryptu:

echo('=== DEBUG START ===' . "\r");
echo('=== $_FILES ===' . "\r");
var_dump($_FILES);
echo('=== $_POST ===' . "\r");
var_dump($_POST);  
echo('=== DEBUG END ===' . "\r");

Odpowiedź serwera odbierana przez program:

=== DEBUG START ===
=== $_FILES ===
array(0) {
}
=== $_POST ===
array(0) {
}
=== DEBUG END ===

Żadnych plików ani żadnych zmiennych POST nie widzi, nawet jeśli je przesyłam. Ten sam skrypt działa z formularzem HTTP, więc zapis i uprawnienia są na pewno w porządku. Zaczynam podejrzewać klasę TMsMultiPartFormDataStream - korzystam z unitu ms.pas stąd: Jak wyslac plik metoda http post przez delphi

[Edit]
Strzał był ślepy, ale celny - coś nie tak z TMsMultiPartFormDataStream. Wysyłany był pusty strumień. Podmieniłem na TIdMultiPartFormDataStream z IdMultipartFormData i wszystko działa jak należy. Dzięki za pomoc, debug PHP bardzo się przydał.

1 użytkowników online, w tym zalogowanych: 0, gości: 1