Ошибка сокета при использовании MWS SubmitFeed в Delphi с использованием TIdHTTP

Я создаю приложение в Delphi 2006 для интеграции с Amazon MWS API, но получаю Ошибка сокета 10061 Отказ в подключении.

Вот мой код Delphi:

// pull out url end point - in my case mws-eu.amazonservices.com:443
url := '';
url := getOption('URL');
if url='' then LogMessage('DEV','No Amazon URL in INI file! ', true);

request := TStringList.Create;

// add standard required fields
//request.Add('Marketplace='+getOption('Marketplace')); 
request.Add('Action='+action);
request.Add('AWSAccessKeyId='+getOption('AWSAccessKeyId'));
//request.Add('MWSAuthToken='+getOption('MWSAuthToken')); 

//request.Add('Merchant='+getOption('SellerId'));
request.Add('SellerId='+getOption('SellerId'));
request.Add('SignatureMethod='+getOption('SignatureMethod')); // HmacSHA256
request.Add('SignatureVersion='+getOption('SignatureVersion')); // 2

request.Add('Version='+getOption('Version')); // not sure where this comes from or whether its common to all calls ?? Version=2009-01-01

// add request specific params (these are sent in to this function)
for loop := 0 to params.Count-1 do
begin
request.Add(paramsloop);
end;

// add timestamp
d:=Now;
dt:=FormatDateTime('yyyy-mm-dd"T"hh:mm:ss"Z"',d);
request.Add('Timestamp='+dt);

// call our custom sort method
LogMessage('DEV','Before='+request.GetText, false);
request.CustomSort(StringListCompareLogical);
LogMessage('DEV','After='+request.GetText, false);

// encode the params as per MWS
stringResult:=MWSEncodeParams(request);
LogMessage('DEV','result:'+stringResult, false);

stringToSign := 'POST' + char(10);
stringToSign := stringToSign + url + char(10);
stringToSign := stringToSign + '/' + char(10);
stringToSign := stringToSign + stringResult;

LogMessage('DEV','stringToSign:'+stringToSign, false);

// call sha method in DLL encrypter
uPugwash.getSH256_HMAC(getOption('SecretKey'),stringResult,True,Signature);
// add result to request as signature
request.Add('Signature='+Signature);
stringResult:=stringResult+'&Signature='+Signature;

// call md5 method in DLL encrypter
uPugwash.getMD5(requestBody,true,MD5) ;

LogMessage('DEV','output signature: '+Signature, true);
LogMessage('DEV','output md5: '+MD5, true);
lHTTP := TIdHTTP.Create(nil);

lIOHandler:=TIdSSLIOHandlerSocketOpenSSL.Create(nil);
lIOHandler.Port := 443; // lIOHandler.Port := 25;

try
lHTTP.IOHandler := lIOHandler;
lHTTP.ConnectTimeout:=5000;
lHTTP.HandleRedirects := True;
lHTTP.ReadTimeout := 20000;
lHTTP.Request.Method := 'POST';
lHTTP.Request.AcceptCharSet := 'UTF-8';
lHTTP.Request.ContentType := 'text/xml';
//lHTTP.Request.ContentType:='application/x-www-form-urlencoded';
lHTTP.Request.ContentEncoding := 'utf-8';
lHTTP.Request.UserAgent := 'POS Amazon Web Integration/'+getOption('posVersion')+' (Language=Delphi/2006; Customer='+getOption('Customer')+')';
lHTTP.Request.Host := url;
lHTTP.Request.CustomHeaders.Add('X-Amazon-User-Agent: '+lHTTP.Request.UserAgent);
lHTTP.Request.CustomHeaders.Add('Content-MD5: '+MD5);
lHTTP.Request.Accept:='text/plain, */*';
lHTTP.ProtocolVersion:=pv1_1;
lHTTP.HTTPOptions:=lHTTP.HTTPOptions+hoKeepOrigProtocol-hoForceEncodeParams;

RBody := TStringStream.Create(requestBody); // this is my feed xml
RBody.Seek(0,0);

LogMessage('DEV','request body:'+requestBody, false);
LogMessage('DEV','request url:'+stringResult, false);

fullURL := 'https://'+url+'?'+stringResult; // this is url with required parameters on end
LogMessage('DEV','fullURL:'+fullURL, false);

// make actual call
rawResp := lHTTP.POST(fullURL,RBody); // falls over here with socket exception

Выше я предположил, что обычные параметры отправляются в URL-адресе, а xml отправляется в теле.

Любые указатели на то, где я могу ошибаться, будут высоко оценены.

Спасибо!


person Andy Baptiste    schedule 05.11.2014    source источник
comment
WSAECONREFUSED означает, что вы пытались подключиться к узлу/порту, который не прослушивает соединения активно, или брандмауэр/маршрутизатор отклоняет соединение. Вы также делаете вещи в своей установке TIdHTTP, которые вы не должны делать. Не устанавливайте lIOHandler.Port, Request.Method, Request.ContentEncoding или Request.Host вообще, TIdHTTP управляет ими за вас. И вы можете удалить :443 из URL-адреса, так как это значение по умолчанию для https://.   -  person Remy Lebeau    schedule 05.11.2014
comment
Внес эти изменения, но все равно получаю ту же ошибку сокета 10061. Я читал в другом месте, что при использовании Indy требуется добавление: 443 в конец конечной точки, иначе подпись не будет совпадать, поэтому пробовал с и без. Когда я не использую, я получаю ошибку сокета # 11004 - могу ли я что-нибудь прочитать в этом?   -  person Andy Baptiste    schedule 06.11.2014
comment
11004 — это WSANO_DATA, что является ошибкой поиска DNS и не имеет ничего общего с номерами портов.   -  person Remy Lebeau    schedule 06.11.2014


Ответы (1)


Я тоже много боролся с веб-сервисами Indy и Amazon. Конкретная ошибка, которую вы получаете, - это ошибка winsock:

WSAECONNREFUSED
10061
Соединение отклонено. Соединение установить не удалось, так как целевой компьютер активно отклонял его. Обычно это происходит из-за попытки подключиться к службе, которая неактивна на внешнем хосте, то есть к службе, на которой не запущено серверное приложение.

По моему опыту ошибка может произойти из-за нескольких вещей:

  1. Неверный адрес сервера или неправильный порт — проверьте URL-адрес и порт службы. Убедитесь, что они верны (я не эксперт в MWS, поэтому не могу вам в этом помочь)

  2. Какой-то брандмауэр на стороне клиента блокирует запрос - попробуйте отключить все виды брандмауэра и повторите запрос

  3. Эта ошибка может быть вызвана очень нестабильным интернет-соединением на стороне клиента.

В общем, я бы не рекомендовал вам использовать Indy, поскольку я видел, как он терпел неудачу во многих ситуациях. Я обнаружил, что WinHTTP API, хотя и немного сложнее, но гораздо более стабилен.

Надеюсь, что что-то из этого поможет.

person Angel Naydenov    schedule 05.11.2014
comment
Какие именно проблемы у вас возникают? Indy прекрасно работает при правильном использовании. - person Remy Lebeau; 05.11.2014
comment
WinHTTP is way more stable - WinHTTP также менее кроссплатформенный. Indy поддерживает все целевые платформы Delphi и работает с Free Pascal (включая Linux). - person mjn; 06.11.2014