HTTPS post - что я делаю не так? - PullRequest
       16

HTTPS post - что я делаю не так?

4 голосов
/ 23 декабря 2010

Я делаю запросы к веб-адресу для получения файлов XML через соединение HTTPS. Но эта связь работает как 50%. В большинстве случаев это не удается. Обычная ошибка - «ошибка сокета # 10060». Или "Ошибка соединения с SSL. EOF, который нарушает протокол". Что я делаю не так?

function SendRequest(parameters: string): IXMLDocument;
var
   sPostData: TStringList;
   sHttpSocket: TIdHTTP;
   sshSocketHandler: TIdSSLIOHandlerSocketOpenSSL;
   resStream: TStringStream;
   xDoc: IXMLDocument;

   begin
      sPostData := TStringList.Create;

      try
         sPostData.Add('add some parameter to post' + '&');
         sPostData.Add('add some parameter to post' + '&');
         sPostData.Add('add some parameter to post' + '&');
         sPostData.Add(parameters);

         sHttpSocket := TIdHTTP.Create;
         sshSocketHandler := TIdSSLIOHandlerSocketOpenSSL.Create;
         sHttpSocket.IOHandler := sshSocketHandler;

         sHttpSocket.Request.ContentType := 'application/x-www-form-urlencoded';
         sHttpSocket.Request.Method := 'POST';

         resStream := TStringStream.Create;
         sHttpSocket.Post(Self.sUrl, sPostData, resStream);

         xDoc := CreateXMLDoc;
         xDoc.LoadFromStream(resStream);

         Result := xDoc;

         resStream.Free;
         sHttpSocket.Free;
         sshSocketHandler.Free;
         sPostData.Free;
      except on E: Exception do
      begin
         TCommon.ErrorLog('errorLog.txt', DateTimeToStr(Now) + ' ' + E.Message);
      end
      end;
    end;

Может быть, я могу сделать это другим способом, который работает как 100%, когда доступно подключение к Интернету?

С уважением, evilone

1 Ответ

2 голосов
/ 26 декабря 2010

Ошибка «EOF» предполагает, что вы подключаетесь к серверу, который на самом деле не использует SSL, или данные SSL могут быть повреждены.

Кроме того, почему вы включаете явные символы '&' между параметрами ваших данных? Не делайте этого, Indy просто закодирует их и отправит свои собственные символы '&'. Кроме того, рассмотрите возможность использования TMemoryStream вместо TStringStream, чтобы убедиться, что IXMLDocumect.LoadFromStream () загружает исходные необработанные данные XML сервера как есть, а не измененную версию, которую RTL / VCL создает из-за обработки Unicode (TStringStream поддерживает TEncoding).

Редактировать: Учитывая указанный вами URL, пример вызова verifyUser () будет выглядеть так:

const
  ERPLYAccountCode = '...';

function verifyUser(const user, pass: string; const sessionLength: Integer = 3600): IXMLDocument;
var
  sPostData: TStringList;
  sHttpSocket: TIdHTTP;
  sshSocketHandler: TIdSSLIOHandlerSocketOpenSSL;
  resStream: TMemoryStream;
  xDoc: IXMLDocument;
begin
  Result := nil;
  try
    resStream := TMemoryStream.Create;
    try
      sPostData := TStringList.Create;
      try
        sPostData.Add('clientCode=' + ERPLYAccountCode);
        sPostData.Add('request=verifyUser');
        sPostData.Add('version=1.0');
        sPostData.Add('responseType=XML');
        sPostData.Add('responseMode=normal');
        sPostData.Add('username=' + user);
        sPostData.Add('password=' + pass);
        sPostData.Add('sessionLength=' + IntToStr(sessionLength));
        sHttpSocket := TIdHTTP.Create;
        try
          sshSocketHandler := TIdSSLIOHandlerSocketOpenSSL.Create(sHttpSocket);
          sHttpSocket.IOHandler := sshSocketHandler;
          sHttpSocket.Request.ContentType := 'application/x-www-form-urlencoded';
          sHttpSocket.Post('https://www.erply.net/api/', sPostData, resStream);
        finally
          sHttpSocket.Free;
        end;
      finally
        sPostData.Free;
      end;
      resStream.Position := 0;
      xDoc := CreateXMLDoc;
      xDoc.LoadFromStream(resStream);
      Result := xDoc;
    finally
      resStream.Free;
    end;
  except
    on E: Exception do
    begin
      TCommon.ErrorLog('errorLog.txt', DateTimeToStr(Now) + ' ' + E.Message);
    end;
  end;
end; 
...