PDA

View Full Version : Send XML 1st line to Amazon



Poonarge
7th July 2014, 17:10
Hi,

I'm having trouble sending XML 1st line to Amazon. I have googled around but haven't been able to implement what I've found. Any help would be much appreciated.

I am using Qt 5.3

Thanks,

Richard

anda_skoa
7th July 2014, 18:28
This does not contain enough information.

At which stage to you get into problems? Creating the XML? Sending it? How does you current code look like? What does it do that you do not expect? What does it not do that you would expect it to do?

Cheers,
_

ChrisW67
7th July 2014, 21:13
What does "XML 1st line" even mean?

Poonarge
8th July 2014, 09:18
At which stage to you get into problems? Creating the XML? Sending it? How does you current code look like? What does it do that you do not expect? What does it not do that you would expect it to do?


Sorry for being brief. I'm having trouble sending the XML, each time I get an invalid reply. See below:

Request:

QByteArray XMLTest;

QXmlStreamWriter swTest(&XMLTest);
swTest.setAutoFormatting(true);
swTest.writeStartDocument();
swTest.writeEndDocument();

QUrl Params(BuildRequest(1, account, marketplaces));

QNetworkRequest request(Params);

QString BodyMD5 = QString(QCryptographicHash::hash((XMLTest),QCrypto graphicHash::Md5).toHex());

request.setRawHeader("Content-Type", "text/xml; charset=iso-8859-1");
request.setRawHeader("Content-MD5", BodyMD5.toLatin1().toBase64());
request.setRawHeader("User-Agent", "TestBuild");
request.setRawHeader("Host", "mws.amazonservices.co.uk");
request.setRawHeader("Transfer-Encoding", "chunked");
request.setRawHeader("MWSClientVersion", "2009-03-09");

QNetworkAccessManager test;

QEventLoop loop2;
connect(&test, SIGNAL(finished(QNetworkReply*)), &loop2, SLOT(quit()));
QNetworkReply *reply = test.post(request, request.url().query().toUtf8());
loop2.exec();

QString str = reply->readAll();

str returns an empty string, and the status code is 0.


BuildRequest:

QUrl req("https://mws.amazonservices.co.uk");

QUrlQuery q;

q.addQueryItem("AWSAccessKeyId", AccessKey);
q.addQueryItem("Action", action);
q.addQueryItem("Merchant", MerchantID);
q.addQueryItem("SignatureVersion", "2");
q.addQueryItem("Timestamp", Timestamp.toString());
q.addQueryItem("Version", "2009-01-01");
q.addQueryItem("Signature", Signature);
q.addQueryItem("SignatureMethod", "HmacSHA256");
q.addQueryItem("FeedType", type);
q.addQueryItem("MarketplaceIdList.Id." + MarketplaceListID, marketplace.value("MarketplaceID").toString());
q.addQueryItem("PurgeAndReplace", "false");

req.setQuery(q);
return req;



What does "XML 1st line" even mean?

I just want to send the XML 1st line (the XML declaration) to Amazon, for testing purposes.

anda_skoa
8th July 2014, 11:20
Aside from your content type header being wrong, have you tried connecting to the QNetworkReply's signals, especially the error signal?
Does this require authentication?

Cheers,
_

Poonarge
8th July 2014, 12:20
Just changed the content type header to text/xml, which I assume is correct?
Also just connected to the error signal, it returned an UnknownContentError(299)?
In my current code, I am not sending the XML, which is something I am having trouble with as I don't know how.

ChrisW67
8th July 2014, 23:32
The XML, which you have to actually put at least an empty top level element in, should be passed as the body of the request using the second argument of the post() function. You are trying to mix a content type of urlencoded data and the xml data: this will not work.

It is unlikely the value you are putting in the Content-md5 header is correct. You are base 64 encoding a hex string.

Poonarge
9th July 2014, 10:19
Thanks, So it should be more like this:



QNetworkReply * reply = test.post(request, XML);


I thought POST parameters were sent as body content though? or is that not the case?
I will try to implement what you said now.

UPDATE:

Have made said changes, although I'm getting a 302 error - Bad Request. Still a bit unsure on the Content-MD5 too.

Regards,

Richard

ChrisW67
9th July 2014, 12:28
If the service is expecting URL endoded form values then you send them as the body and set the Content-Type to application/x-www-form-urlencoded.
If the service is expecting a request in some XML form, e.g. as SOAP request, then you send that as the body and Content-Type to application/soap+xml or text/xml depending on the exact service.
It's also possible the service is expecting something encoded as multipart/form-data, but that seems unlikely.

Amazon MWS looks like the first option (see page 19 here https://images-na.ssl-images-amazon.com/images/G/01/mwsportal/doc/en_US/bde/MWSDeveloperGuide.pdf) so XML has nothing to do with the request. The response is an XML document, see page 22.

Poonarge
9th July 2014, 13:05
I've made a successful request to GetFeedSubmissionList, which is fine as I'm not required to send XML for that call. But when I need to submit a feed, I have to send XML.

Example:
Amazon Scratchpad - HTTP POST



POST /?AWSAccessKeyId=XXXXXXXXXXXXXXXXXX
&Action=SubmitFeed
&Merchant=XXXXXXXXXXXXXXXXXX
&SignatureVersion=2
&Timestamp=2014-07-09T11%3A59%3A18Z
&Version=2009-01-01
&Signature=XXXXXXXXXXXXXXXXXX
&SignatureMethod=HmacSHA256
&FeedType=_POST_PRODUCT_DATA_
&MarketplaceIdList.Id.1=XXXXXXXXXXXXXXXXXX
&PurgeAndReplace=false HTTP/1.1
Host: mws.amazonservices.co.uk
x-amazon-user-agent: AmazonJavascriptScratchpad/1.0 (Language=Javascript)
Content-MD5: XXXXXXXXXXXXXXXXXX
Content-Type: text/xml


I need to then attach my XML to the request somehow.

ChrisW67
10th July 2014, 09:45
As the request body in the second parameter to post()

Poonarge
10th July 2014, 11:28
QNetworkAccessManager test;
QEventLoop loop2;

connect(&test, SIGNAL(finished(QNetworkReply*)), &loop2, SLOT(quit()));
QNetworkReply * reply = test.post(request, XML);
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onError(QNetworkReply::NetworkError)));
loop2.exec();

QString str = reply->readAll();


str suggests a Server timeout waiting for the HTTP request from the client / Bad Request


UPDATE:

All seems to be working great now, thanks for your help.