Массовая загрузка API Delphi и Walmart - внутренняя ошибка сервера - PullRequest
0 голосов
/ 07 июня 2018

Я использую Delphi XE5 и пытаюсь отправить Предметы в Walmart с помощью Bulk API Upload, но я пытаюсь установить правильное соединение с сервером Walmart.Я уже проверил некоторые подобные проблемы здесь, такие как Walmart API - проблема типа пантомимы полезной нагрузки

Самое странное, что фид фактически принят Walmart (я вижу его в спискеканалы), но я получаю внутреннюю ошибку сервера, а затем бессмысленные символы (вероятно, тип кодировки или просто вид ошибки), например

(# $ D # $ A # $ 1F # $ 008B # 8 # 0 # 0 # #0 # 0 # 0 # 0 # 3 # $ D'A ± '# $ D # $ 0080'0' # $ C # 4'AU ~ '# 2'v? D' # $ 0087 # 4 '?' # 1 # $ 0091'OE' # $ E # $ 008A'O '# $ 1E'® вывода?' # $ 18 # $ 0091 # $ A # $ 0091'M ^ '# $ С';? '# $ 1D'G' # $ A'dR± U? Oip? M '# $ 1A'AVS' # 4 # $ 16'R? IR '# $ 1B # $ 0095'RO?} U' # 0'enIjM '# 0 # 0 # 0)

Поэтому я использую Indy IdHTTP , и я попытался использовать TIdMultipartFormDataStream , а также самостоятельно создать полезную нагрузку, получив внутреннюю ошибку сервера.Я предполагаю, что каким-то образом нарушаю их парсер, потому что если я пропущу один CR LF (# 13 # 10) в начале, я получаю конкретную ошибку

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns2:errors xmlns:ns2="http://walmart.com/"><ns2:error><ns2:code>SYSTEM_ERROR.GMP_GATEWAY_API</ns2:code><ns2:field>PDR-0012</ns2:field><ns2:description></ns2:description><ns2:info>System encountered some internal error.</ns2:info><ns2:severity>ERROR</ns2:severity><ns2:category>SYSTEM</ns2:category><ns2:causes/><ns2:errorIdentifiers/></ns2:error></ns2:errors>

Если я добавлю дополнительный CRLF в конце, то получудругая ошибка, указывающая на то, что в запросе есть несколько каналов.Так что я действительно предполагаю, что есть что-то, что заставляет этот сервер / парсер возвращать Внутреннюю ошибку, но я не получаю то, и снова повторяю, что фид фактически принимается и затем обрабатывается сервером в случае, если я получаю эту ошибку.

Вот пример запроса с полезной нагрузкой, созданной мной самостоятельно:

Заголовки

POST /v3/feeds?feedType=item HTTP/1.1
Content-Type: multipart/form-data; boundary=qwerty
Content-Length: 5077
WM_SVC.NAME: Walmart Marketplace
WM_QOS.CORRELATION_ID: {67F0E2F9-5EAC-4E8C-9C90-650D8F7B3B7A}
WM_SEC.TIMESTAMP: 1528364885909
WM_SEC.AUTH_SIGNATURE: nSHgqzPOtzSR4wJU+U/vQJk+rk6Ke2QwodTHjzkjau2BonXZxiU9e+3NFPzaat2OUyc+vr0jqRk0H0QWTSC21PrI87mvqei5UJCJwNiIx0zVjAGpxsnIuvtIKkQsBpuUAa8C6SjTiTpDRsNt4IOxrk+tLWxlwQubWVCV+009a6o=
WM_CONSUMER.ID: 16248274-1f53-4e6d-880e-b5417698b878
WM_CONSUMER.CHANNEL.TYPE: 0f3e4dd4-0514-4346-b39d-af0e00ea066d
Host: marketplace.walmartapis.com
Accept: application/xml, */*
Accept-Encoding: identity
Accept-Language: en-US
User-Agent: Mozilla/3.0 (compatible; Indy Library)

Запрос

--qwerty

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<MPItemFeed xmlns:ns2="http://walmart.com/">
    <MPItemFeedHeader>
        <version>3.1</version>
        <requestId>{694A5564-7E8E-46C7-B772-C944A8C9CF99}</requestId>
        <mart>WALMART_US</mart>
    </MPItemFeedHeader>
    <MPItem>
        <processMode>REPLACE_ALL</processMode>
        <sku>w-cc-a1-4pk-white-l</sku>
        <productIdentifiers>
            <productIdentifier>
                <productIdType>UPC</productIdType>
                <productId>192082276845</productId>
            </productIdentifier>
        </productIdentifiers>
        <MPProduct>
            <SkuUpdate>Yes</SkuUpdate>
            <productName>Caramel Cantina 4 Pack Sleeping Nursing Cross Front Maternity Bra (Large, White)</productName>
            <ProductIdUpdate>Yes</ProductIdUpdate>
            <category>
                <ClothingCategory>
                    <Clothing>
                        <shortDescription>Stretchy comfort cross front sleep bra by Caramel Cantina. Whether for nursing / maternity or for wearing as a sleep bra (or both nursing and sleep bras) - you&apos;ll experience a wire free regular back strap sleep bra. This mid-weight fabric but light support wireless bra is great for all day wear and comfort.  The straps are wider than a standard bra - offering a longer range of wear time.   Great for wearing indoors (ie when you&apos;re kicking around the home or going to bed). These are padless - most moms use their own favorite nursing pads with these (though no pads are included). The front cups have two layers of fabric to add a bit more support (though we still call them our light support comfort bra). The criss cross front style allows for easy access while nursing your baby. 92% Nylon 8% Spandex fabric washes up nicely.  Cool wash and cool dry. Hang dry for longer life. The straps narrowest point at the shoulders are 1.25-1.5 inches (depending on the size). The bras are super stretchy - if you&apos;re looking for something super supportive (ie - they pull you in really tight - more like a sports bra) these probably aren&apos;t what you&apos;re looking for.  Not recommended for heavy sports activity. Best worn for activities such as walking, sleeping, lounging, light activity, running errands, etc.</shortDescription>
                        <keyFeatures>
                            <keyFeaturesValue>4 Pack Includes 4 Bras of the Same Design - Color Option Above</keyFeaturesValue>
                            <keyFeaturesValue>Soft Cup - Front Double Layered - No padding - Wireless</keyFeaturesValue>
                            <keyFeaturesValue>Super Soft Sleep In Style Bra - Great for Nursing or Sleeping</keyFeaturesValue>
                            <keyFeaturesValue>Criss Cross Front Design Gives Easy Nursing Access</keyFeaturesValue>
                            <keyFeaturesValue>Regular Straps - Scoop Back Design - Strap Width 1.25-1.5 Inches Depending on Size</keyFeaturesValue>
                        </keyFeatures>
                        <brand>Caramel Cantina</brand>
                        <mainImageUrl>https://www.dancecheerskate.com/_inv/D54173DB8F934DB2A4C68D24FAC087F5/wm-cc-a1-4pk-white.jpg</mainImageUrl>
                        <productSecondaryImageURL>
                            <productSecondaryImageURLValue>https://www.dancecheerskate.com/_inv/D54173DB8F934DB2A4C68D24FAC087F5/wm-cc-a1-wht-m1.jpg</productSecondaryImageURLValue>
                        </productSecondaryImageURL>
                        <color>White</color>
                        <clothingSize>Large</clothingSize>
                        <variantGroupId>cc-a1-4pk-parent</variantGroupId>
                        <variantAttributeNames>
                            <variantAttributeName>color</variantAttributeName>
                            <variantAttributeName>clothingSize</variantAttributeName>
                        </variantAttributeNames>
                        <countryOfOriginTextiles>Imported</countryOfOriginTextiles>
                        <fabricCareInstructions>
                            <fabricCareInstruction>Machine wash cold gentle cycle with like colors. Hang Dry. Do Not Bleach. Do Not Iron.</fabricCareInstruction>
                        </fabricCareInstructions>
                        <multipackQuantity>1</multipackQuantity>
                        <countPerPack>4</countPerPack>
                        <count>4</count>
                        <pattern>Solid</pattern>
                        <material>Nylon; Spandex</material>
                        <gender>Female</gender>
                        <ageGroup>
                            <ageGroupValue>Adult</ageGroupValue>
                        </ageGroup>
                        <clothingSizeGroup>Maternity</clothingSizeGroup>
                        <isSet>No</isSet>
                        <requiresTextileActLabeling>Yes</requiresTextileActLabeling>
                        <clothingTopStyle>Sleep Bra</clothingTopStyle>
                        <upperBodyStrapConfiguration>Regular</upperBodyStrapConfiguration>
                        <braStyle>Nursing</braStyle>
                        <clothingStyle>Maternity</clothingStyle>
                        <clothingFit>Maternity</clothingFit>
                        <isMaternity>Yes</isMaternity>
                        <swatchImages>
                            <swatchImage>
                                <swatchVariantAttribute>color</swatchVariantAttribute>
                                <swatchImageUrl>https://www.dancecheerskate.com/_inv/D54173DB8F934DB2A4C68D24FAC087F5/wm-cc-a1-4pk-white.jpg</swatchImageUrl>
                            </swatchImage>
                        </swatchImages>
                    </Clothing>
                </ClothingCategory>
            </category>
        </MPProduct>
        <MPOffer>
            <price>25.00</price>
            <ShippingWeight>
                <measure>11.80</measure>
                <unit>lb</unit>
            </ShippingWeight>
            <ProductTaxCode>2038895</ProductTaxCode>
        </MPOffer>
    </MPItem>
</MPItemFeed>
--qwerty--

Ответ, который я получаю, выглядит следующим образом:

HTTP/1.1 500 Internal Server Error
Method: null
URI: null
WM_CONSUMER.ID: 16248274-1f53-4e6d-880e-b5417698b878
WM_CONSUMER.INTIMESTAMP: 
WM_QOS.CORRELATION_ID: {67F0E2F9-5EAC-4E8C-9C90-650D8F7B3B7A}
WM_SEC.AUTH_TOKEN: 
WM_SEC.REFRESH_AUTH_TOKEN: 
WM_SVC.CLASS_NAME: com.walmart.services.impl.GMPGatewayService$$EnhancerBySpringCGLIB$$c88958a9
WM_SVC.ENV: prod
WM_SVC.INTIMESTAMP: 1528364905439
WM_SVC.METHOD_NAME: doPostMultiPart
WM_SVC.NAME: Walmart Marketplace
WM_SVC.OUTTIMESTAMP: 1528364905567
WM_SVC.SERVER_IP: 10.65.34.219
WM_SVC.SERVER_NAME: PartnerGMPService-5480119-4-96141283
WM_SVC.VERSION: 
X-Powered-By: soari-interceptors-4.4.4
Content-Type: text/plain
Cteonnt-Length: 77
Server: web
Content-Encoding: gzip
Content-Length: 89
Expires: Thu, 07 Jun 2018 09:48:25 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Thu, 07 Jun 2018 09:48:25 GMT
Connection: close

А затем эти символы сверху. Примечание заголовок Cteonnt-Length: 77 , это не мой TYPO, он просто поступает следующим образом.

В зависимости от поддержки, которую они добились, используя следующие заголовкии прошу меня их использовать, но я не вижу никакой разницы в том, что я делаю

WM_SVC.NAME:Walmart Marketplace
WM_QOS.CORRELATION_ID:123456abcdef
WM_SEC.AUTH_SIGNATURE:TnjevCf+voP9dmnafuCTFruwq6leBuAihSvag89WLieDRBsz7aULxgEqV71ZjIp572wVYPI07y6tdMutNLklDGwxvNdlJ2Q2xGvUIqjVPtqlhdcWvsmgqdpio7puQ4G03q1lReWzTquKecDEbB1ztH6ukj9F5rMe7d7PH8QkFsY=
WM_SEC.TIMESTAMP:1528152581896
WM_CONSUMER.ID:16248274-1f53-4e6d-880e-b5417698b878
WM_CONSUMER.CHANNEL.TYPE:0f3e4dd4-0514-4346-b39d-af0e00ea066d
Accept:application/xml
Host:marketplace.walmartapis.com
Content-Type:multipart/form-data

Я уже успешно общаюсь с eBay, Amazon, PayPal, Magento и многими другими, но здесь, очевидно, япропустить что-то и действительно не знаю, как это решить.

Спасибо, что прочитали это, и, надеюсь, кто-то может дать подсказку, что здесь происходит.

РЕДАКТИРОВАТЬ Я добавляю некоторый код Delphi по мере необходимости

Версия 1 без TIdMultipartFormDataStream

function TdmSyncWallmart.CreateItemFeed(aIDPlatforms: String; aLastChanged,
  aCurrDate: TDateTime; var aReqID: String): TStringStream;
var
  aXML: TNativeXML;
  aNode: TXmlNode;
  aItemNode: TXmlNode;
  aCatNode: TXmlNode;
  aTmpNode: TXmlNode;

  aShortDesc: String;
  i: Integer;
  aIDItems: String;
begin
  Result := nil;

  dstListPlatformsSyncItemsWallmart.Close;
  dstListPlatformsSyncItemsWallmart.Parameters.ParamByName('@IDPlatforms').Value := aIDPlatforms;
  dstListPlatformsSyncItemsWallmart.Parameters.ParamByName('@LastChanged').Value := aLastChanged;
  dstListPlatformsSyncItemsWallmart.Parameters.ParamByName('@CurrDate').Value := aCurrDate;
  dstListPlatformsSyncItemsWallmart.Open;

  if dstListPlatformsSyncItemsWallmart.IsEmpty then
    Exit;

  aReqID := GenGuid;

  aXML := TNativeXml.CreateName('MPItemFeed');
  try
    aXML.Declaration.AttributeAdd('standalone', 'yes');
    aXML.Root.AttributeAdd('xmlns:ns2', 'http://walmart.com/');

    //Header
    aNode := aXML.Root.NodeNew('MPItemFeedHeader');
    with aNode.NodeNew('version') do
      Value := '3.1';
    with aNode.NodeNew('requestId') do
      Value := aReqID;
    with aNode.NodeNew('mart') do
      Value := 'WALMART_US';

  //... some code for generating the XML
    Result := TStringStream.Create;
    aXML.XmlFormat := xfReadable;

    Result.WriteString('--qwerty'#13#10#13#10{'Content-Disposition: form-data; filename="wallmartreq.xml"'#13#10}+aXML.WriteToString +'--qwerty--'#13#10);
    Result.Position := 0;

  finally
    aXML.Free;
  end;
end;

function TdmSyncWallmart.CreateHTTP(aContentType: String): TIdHTTP;
begin
  Result := TIdHTTP.Create(nil);
  Result.ConnectTimeout:=5000;
  Result.ReadTimeout:=20000;
  Result.ProtocolVersion:=pv1_1;
  Result.HTTPOptions := [hoForceEncodeParams, hoKeepOrigProtocol];
  Result.HandleRedirects:=True;
  Result.IOHandler := SSLHandler;
  Result.Request.Accept:='application/xml, */*';
  Result.Request.AcceptLanguage:='en-US';
  Result.Request.ContentType:=aContentType;
//  Result.Request.CharSet:='utf-8';
  Result.Intercept := IdLogEvent1;
end;

procedure TdmSyncWallmart.AddCustomHeaders(aHTTP: TIdHTTP; aSign,
  aTimeStamp: String);
begin
  aHTTP.Request.CustomHeaders.AddValue('WM_SVC.NAME', 'Walmart Marketplace');
  aHTTP.Request.CustomHeaders.AddValue('WM_QOS.CORRELATION_ID', GenGuid);
  aHTTP.Request.CustomHeaders.AddValue('WM_SEC.TIMESTAMP', aTimeStamp);
  aHTTP.Request.CustomHeaders.AddValue('WM_SEC.AUTH_SIGNATURE', aSign);
  aHTTP.Request.CustomHeaders.AddValue('WM_CONSUMER.ID', dstPlatformsUserName.AsString);
  aHTTP.Request.CustomHeaders.AddValue('WM_CONSUMER.CHANNEL.TYPE', dstPlatformsPassword.AsString);
end;

//some code for debugging purposes
procedure TdmSyncWallmart.IdLogEvent1Send(ASender: TIdConnectionIntercept;
  var ABuffer: TIdBytes);
var
  aList: TStringList;
begin
  aList := TStringList.Create;
  try
    aList.Text := BytesToString(ABuffer);
    aList.SaveToFile('e:\wm_req_txt.txt');
  finally
    aList.Free;
  end;
end;

procedure TdmSyncWallmart.IdLogEvent1Receive(ASender: TIdConnectionIntercept;
  var ABuffer: TIdBytes);
var
  aList: TStringList;
begin
  aList := TStringList.Create;
  try
    aList.Text := BytesToString(ABuffer);
    aList.SaveToFile('e:\wm_Resp.txt');
  finally
    aList.Free;
  end;
end;

Фактический вызов

procedure TdmSyncWallmart.SendItems(aIDPlatforms: String; aLastChanged,
  aCurrDate: TDateTime);
var
  aSign, aTimeStamp: String;
  aURL: String;
  aHTTP: TIdHTTP;
  aRes: String;
  aStrm: TMemoryStream;
  aReqID: String;

  aXML: TNativeXml;
  aNode: TXmlNode;

  aErrMsg: String;
begin
  aURL := dstPlatformsURLAddress.AsString+'/v3/feeds?feedType=item';
  GenrateSignature(aSign, aTimeStamp, aURL, 'POST');
  if aSign = '' then
    Exit;

  aHTTP := CreateHTTP('multipart/form-data;boundary=qwerty');
  AddCustomHeaders(aHTTP, aSign, aTimeStamp);
  try
    aStrm := CreateItemFeed(aIDPlatforms, aLastChanged, aCurrDate, aReqID);
    if aStrm <> nil then
    begin
      try
        aRes := TIdURI.URLDecode(aHTTP.Post(aURL, aStrm));

        aXML := TNativeXml.Create(nil);
        try
          aXML.ReadFromString(aRes);

          aNode := aXML.Root.FindNode('feedId');

          cmdUpdFeedID.Parameters.ParamByName('ID').Value := aRes;
          cmdUpdFeedID.Parameters.ParamByName('FeedID').Value := aNode.Value;
          cmdUpdFeedID.Execute;
        finally
          aXML.Free;
        end;
      except
        on E:Exception do
        begin
          if E is EIdHTTPProtocolException then
            aErrMsg := E.Message + #13#10 + (E as EIdHTTPProtocolException).ErrorMessage
          else
            aErrMsg := E.Message;

          dmMain.InsLog(cLTError, aErrMsg, aIDPlatforms);

        end;
      end;
      aStrm.Free;
    end;
  finally
    aHTTP.Free;
  end;
end;

EDIT2

procedure TdmSyncWallmart.SendItems(aIDPlatforms: String; aLastChanged,
  aCurrDate: TDateTime);
var
  aSign, aTimeStamp: String;
  aURL: String;
  aHTTP: TIdHTTP;
  aRes: String;
  aStrm: TMemoryStream;
  aReqID: String;

  aXML: TNativeXml;
  aNode: TXmlNode;

  aErrMsg: String;

  aIdStream: TIdMultipartFormDataStream;
begin
  aURL := dstPlatformsURLAddress.AsString+'/v3/feeds?feedType=item';
  GenrateSignature(aSign, aTimeStamp, aURL, 'POST');
  if aSign = '' then
    Exit;

  aHTTP := CreateHTTP('multipart/form-data');
  AddCustomHeaders(aHTTP, aSign, aTimeStamp);
  try
    aStrm := TStringStream.Create();
    begin
      try
        aIdStream := TIdMultiPartFormDataStream.Create;
        aIdStream.AddFile('file', 'e:\wm_req.xml', 'multipart/form-data');
        aIdStream.Position := 0;
        astrm.LoadFromStream(aIdStream);

        aRes := TIdURI.URLDecode(aHTTP.Post(aURL, aStrm));

        aXML := TNativeXml.Create(nil);
        try
          aXML.ReadFromString(aRes);

          aNode := aXML.Root.FindNode('feedId');

          cmdUpdFeedID.Parameters.ParamByName('ID').Value := aRes;
          cmdUpdFeedID.Parameters.ParamByName('FeedID').Value := aNode.Value;
          cmdUpdFeedID.Execute;
        finally
          aXML.Free;
        end;
      except
        on E:Exception do
        begin
          if E is EIdHTTPProtocolException then
            aErrMsg := E.Message + #13#10 + (E as EIdHTTPProtocolException).ErrorMessage
          else
            aErrMsg := E.Message;

          dmMain.InsLog(cLTError, aErrMsg, aIDPlatforms);

        end;
      end;
      aStrm.Free;
    end;
  finally
    aHTTP.Free;
  end;
end;

Этоотправленные данные

----------060718213723831
Content-Disposition: form-data; name="file"; filename="wm_req.xml"
Content-Type: multipart/form-data
Content-Transfer-Encoding: binary

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<MPItemFeed xmlns:ns2="http://walmart.com/">
    <MPItemFeedHeader>
        <version>3.1</version>
        <requestId>{164726BF-288E-4953-A1DA-1EC7595C5725}</requestId>
        <mart>WALMART_US</mart>
    </MPItemFeedHeader>
    <MPItem>
        <processMode>REPLACE_ALL</processMode>
        <sku>w-cc-a1-4pk-white-l</sku>
        <productIdentifiers>
            <productIdentifier>
                <productIdType>UPC</productIdType>
                <productId>192082276845</productId>
            </productIdentifier>
        </productIdentifiers>
        <MPProduct>
        ..... the other part of the XML
        </MPProduct>
        <MPOffer>
            <price>25.00</price>
            <ShippingWeight>
                <measure>11.80</measure>
                <unit>lb</unit>
            </ShippingWeight>
            <ProductTaxCode>2038895</ProductTaxCode>
        </MPOffer>
    </MPItem>
</MPItemFeed>
----------060718213723831--

Возвращенные данные, полученные перехваченной частью, совпадают с данными, уже отправленными с заголовком Cteonnt-Length: 77 , но я предполагаю, что мне удастсячитая данные gzip, я могу получить сообщение об ошибке, которое можно переслать в службу поддержки.

HTTP/1.1 500 Internal Server Error
Method: null
URI: null
WM_CONSUMER.ID: 16248274-1f53-4e6d-880e-b5417698b878
WM_CONSUMER.INTIMESTAMP: 
WM_QOS.CORRELATION_ID: {CB0208AB-2135-4A12-B45F-DD2889273971}
WM_SEC.AUTH_TOKEN: 
WM_SEC.REFRESH_AUTH_TOKEN: 
WM_SVC.CLASS_NAME: com.walmart.services.impl.GMPGatewayService$$EnhancerBySpringCGLIB$$2ca3f3b6
WM_SVC.ENV: prod
WM_SVC.INTIMESTAMP: 1528396669253
WM_SVC.METHOD_NAME: doPostMultiPart
WM_SVC.NAME: Walmart Marketplace
WM_SVC.OUTTIMESTAMP: 1528396669365
WM_SVC.SERVER_IP: 10.65.34.2
WM_SVC.SERVER_NAME: PartnerGMPService-5480119-1-96141274
WM_SVC.VERSION: 
X-Powered-By: soari-interceptors-4.4.4
Content-Type: text/plain
Cteonnt-Length: 77
Server: web
Content-Encoding: gzip
Content-Length: 89
Vary: Accept-Encoding
Expires: Thu, 07 Jun 2018 18:37:49 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Thu, 07 Jun 2018 18:37:49 GMT
Connection: close

EDIT3

Для моего Edit1 я не добавляю Content-Распоряжение вообще (это комментируется) - с таким количеством тестов я оставил его в своем посте здесь, извините за путаницу.

Для Edit2 - спасибо за указание на это, на самом деле я сделал свои первые тесты безпревращаясь в TStringStream, но я хотел посмотреть, что именно идет к ним.

В любом случае, теперь я напрямую использовал TIdMultipartFormDataStream и изменил код таким образом

    aIdStream := TIdMultiPartFormDataStream.Create;
    with aIdStream.AddFile('xml', 'e:\wm_req.xml', 'application/xml') do
    begin
      FileName := '';
      //ContentType := '';
      FileName := 'wmreq.xml';//somewhere I think I saw that only letters are allowed here
    end;
    aIdStream.Position := 0;

    aStrm := TMemoryStream.Create;

    //aRes := TIdURI.URLDecode(aHTTP.Post(aURL, aIdStream));
    aHTTP.Post(aURL, aIdStream, aStrm);

, и благодаря Реми я добавил TIdCompressorZLib, и теперь я получаю значимую ошибку:

HTTP / 1.1 500 Внутренняя ошибка сервера Не ​​найден модуль записи тела сообщения для класса ответа FeedAcknowledgement.

Полагаю, это от них, а не от меня, потребуетсясвяжитесь с ними.

EDIT4 Решение

Хорошо, сумасшедший или нет, может быть, моя проблема, но однажды Реми сказал, что я не прошу сжатый ответ, и они отправили мне такой, я решил изменить // Result.Request.Accept:='application/xml, */*'; на // Result.Request.Accept:='application/xml'; и все стало работать правильно!На самом деле наличие */* означает, что я принимаю все, не так ли?Не имеет значения, используете ли вы TIdMultipartFormDataStream или тело подготовлено вручную, оно просто работает.Спасибо, Реми, за другую точку зрения, всегда помогает другая пара глаз.Сумасшедший ... одна неделя глупых испытаний!

1 Ответ

0 голосов
/ 07 июня 2018

При первом редактировании вы неправильно заполняете TStringStream.Используйте это вместо:

Result.WriteString('--qwerty'#13#10{'Content-Disposition: form-data; name="file"; filename="wallmartreq.xml"'#13#10}#13#10 + aXML.WriteToString + #13#10'--qwerty--'#13#10);

Во втором редактировании вы предоставляете неправильный ContentType для TIdMultipartFormDataStream.AddFile().Вам нужно использовать application/xml вместо multipart/form-data:

aIdStream.AddFile('file', 'e:\wm_req.xml', 'application/xml');

или оставить поле ContentType пустым (в этом случае вместо него будет использоваться application/octet-stream):

aIdStream.AddFile('file', 'e:\wm_req.xml');

Если вы вообще не хотите отправлять ContentType, вы можете установить для свойства TIdFormDataField.ContentType пустую строку:

with aIdStream.AddFile('file', 'e:\wm_req.xml') do
begin 
  FileName := ''; // needed so ContentType setter will not use a default value...
  ContentType := '';
  FileName := 'wm_req.xml'; // or whatever you want, or leave blank...
end;

Но, что более важно, вы НЕ указываете атрибут boundaryдля заголовка TIdHTTP.Request.ContentType больше.Фактически, вы НЕ ДОЛЖНЫ сохранять TIdMultipartFormDataStream в TStringStream и затем публиковать TStringStream вообще.Вы ДОЛЖНЫ размещать вместо себя TIdMultipartFormDataStream.Это автоматически установит TIdHTTP.Request.ContentType на multipart/form-data, а также даст ему правильный атрибут boundary (значение которого генерируется TIdMultipartFormDataStream):

aHTTP.Post(aURL, aIdStream)

Теперь, когдакак говорится, в обоих случаях вам необходимо удалить вызов на TIdURI.URLDecode() на возвращаемое значение TIdHTTP.Post().Сервер должен отправлять вам raw XML, а не XML-кодированный URL, поэтому вам нужно обработать XML как есть , а не URL-декодировать его вообще.

Кроме того, поскольку XML - это технически двоичные данные, которые могут быть закодированы в любую кодировку, которая может присутствовать или не присутствовать в заголовках ответа HTTP, вам СЛЕДУЕТ, чтобы ваш анализатор XML обрабатывал XML точно как отправлено сервером.Для этого используйте перегруженную версию TIdHTTP.Post(), которая заполняет TStream, а не возвращает String.Пусть он получит XML-код сервера в TMemoryStream, а затем загрузит этот поток в ваш анализатор (TNativeXml имеет метод LoadFromStream()).


Наконец, вы показываете, что ответ сервера имеетзаголовок ответа Content-Encoding: gzip, но я не вижу, чтобы вы присваивали какой-либо объект свойству TIdHTTP.Compressor или вручную устанавливали свойство TIdHTTP.Request.AcceptEncoding, поэтому серверу НЕ СЛЕДУЕТ отправлять тело ответа в сжатом формате, поскольку вы непросить этот формат.TIdHTTP не будет автоматически распаковывать данные без назначенного Compressor.

Если сервер действительно отправляет сжатые данные без запроса, это ошибка на стороне сервера, о которой вы должны сообщить Walmart.

...