Конференция "Сети" » Idhttp post и ошибка 405 method not allowed [WinXP]
 
  • megavoid © (05.02.11 18:45) [0]
    Добрый вечер! Имеется функция аплоада картинки на сервер:

    function SendCJB(Path: string): string;
    var
     HTTP: TIdHTTP;
     MPS: TIdMultiPartFormDataStream;
     S: string;
    begin
     Result := '';
     if not FileExists(path) then Exit;
     HTTP := TIdHTTP.Create(nil);
     MPS := TIdMultiPartFormDataStream.Create;
     HTTP.HandleRedirects := True;
     HTTP.Request.Referer := 'http://www.cjb.net/';
     HTTP.ProtocolVersion := pv1_1;
     HTTP.HTTPOptions := [hoKeepOrigProtocol];
       MPS.AddFormField('images', '1');
       MPS.AddFile('image', path, 'multipart/form-data');
       try
         S := HTTP.Post('http://upload.cjb.net/', MPS);    // тут либо 302, либо 405

         result := S;
       finally
         MPS.Free;
         HTTP.Free;
       end;
    end;



    Если HandleRedirects = false, то вылетает  EIdHTTPProtocolException 302 Found.
    Если же дать idhttp обработать редирект, то вылетает уже 405 - method not allowed.

    Мониторинг показал, что инди получает вот такой заголовок от сервера, который и вводит её в затруднения (делали post, а сервер предлагает в ответе перейти по редиректу):
    HTTP/1.1 302 Found
    Server: nginx
    Date: Sat, 05 Feb 2011 13:34:17 GMT
    Content-Type: text/html; charset=iso-8859-1
    Connection: keep-alive
    Cache-Control: no-cache
    Location: http://www.cjb.net/images.html?c1c90.jpg
    Content-Length: 220

    Помогите, пожалуйста, побороть 405-ю ошибку!
  • megavoid © (05.02.11 19:01) [1]
    UPD: если посмотреть HTTP.Response.RawHeaders.GetText, то видим следующую забавную вещь, которая, возможно, объясняет этот 405:

    Server: nginx
    Date: Sat, 05 Feb 2011 15:59:55 GMT
    Content-Type: text/html; charset=iso-8859-1
    Transfer-Encoding: chunked
    Connection: keep-alive
    Allow: GET, HEAD, OPTIONS, TRACE

    То есть upload.cjb.net может принять POST, а редирект идёт на обычный www.cjb.net, который крутится на nginx без POST, верно ли я понимаю?
  • megavoid © (05.02.11 19:15) [2]
    Решено, но очень-очень некрасиво :(

    function SendCJB(Path: string): string;
    var
    HTTP: TIdHTTP;
    MPS: TIdMultiPartFormDataStream;
    S: string;
    begin
    Result := '';
    if not FileExists(path) then Exit;
    HTTP := TIdHTTP.Create(nil);
    MPS := TIdMultiPartFormDataStream.Create;
    HTTP.HandleRedirects := False;
    HTTP.Request.Referer := 'http://www.cjb.net/';
    HTTP.ProtocolVersion := pv1_1;
    HTTP.HTTPOptions := [hoKeepOrigProtocol];
    MPS.AddFormField('images', '1');
    MPS.AddFile('image', path, 'multipart/form-data');
    try
         try
           S := HTTP.Post('http://upload.cjb.net/', MPS);
         except
           S := HTTP.Response.RawHeaders.GetText;
           S2 := Trim(Copy(S, Pos('Location: ', S), 100));
         end;
         S := HTTP.Get(S2);
         S2 := Copy(S, Pos('<a href=\"', S)+9, 200);
         Result := Copy(S2, 0, Pos('\"', S2)-1);
    finally
        MPS.Free;
        HTTP.Free;
    end;
    end;

  • ВладОшин © (28.04.14 23:17) [3]
    похоже так
    такая же ерунда...
  • Anatoly Podgoretsky © (29.04.14 12:19) [4]

    > либо 302, либо 405

    302 не ошибка
  • [ВладОшин] © (29.04.14 22:56) [5]
    понятно, но инди ее как ошибку делает

    если оставить разрешение редиректа, то метод post странно перескакивает на get
    говоришь post url1
    он туда ломится, потом редиректится пару раз, потом вдруг get делает, уже по url3

    не понимаю, как так..
  • ВладОшин © (05.05.14 12:42) [6]
    как-то так работает, вроде
     repeat
       PostHttp302(idHTTP1, v, PostDATA, WD, R_URL);
       v := R_URL;
     until not(WD);

    ----------
    procedure TForm1.PostHttp302(Http: TIdHTTP; URL: string; PostData: TStringList; var WasRedirect:Boolean; var NewUrl: string);
    begin
     WasRedirect := False;
     try
       Http.Post(URL, PostData);
     except
       on e: EIdHTTPProtocolException do
       begin
         if e.ErrorCode = 302 then
         begin
           WasRedirect := True;
           NewUrl :=  Http.Response.Location;
           print(  'e.ErrorCode = 302');
           print(NewUrl);
           print(Format('%s: [%s]',['E.ClassName', E.ClassName]));
           print(Format('%s: [%s]',['E.Message', E.Message]));
           print(Format('%s: [%s]',['E.ErrorMessage', E.ErrorMessage]));
           print(Format('%s: [%s]',['Response.RawHeaders.GetText', Http.Response.RawHeaders.GetText]));
           print(  '---e.ErrorCode = 302----');
         end else
         begin
           print(Format('%s: [%s]',['E.ClassName', E.ClassName]));
           print(Format('%s: [%s]',['E.Message', E.Message]));
           print(Format('%s: [%s]',['E.ErrorMessage', E.ErrorMessage]));
           print(Format('%s: [%s]',['Response.RawHeaders.GetText', Http.Response.RawHeaders.GetText]));
         end;
       end;
     end;
    end;

    procedure TForm1.Print(s: string);
    begin
     mmo1.Lines.Add(s);
    end;
  • megavoid © (07.05.14 10:13) [7]
    О-о, а я тогда так и оставил вложенный except, не было времени, а потом и вообще проект перевёл на PHP/CURL, там
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);

    отрабатывает хорошо, а в Indy код 302 вроде до сих пор так и выкидывает исключение.
 
Конференция "Сети" » Idhttp post и ошибка 405 method not allowed [WinXP]
Есть новые Нет новых   [120562   +199][b:0][p:0.002]