Link to home
Start Free TrialLog in
Avatar of AmyL

asked on

libcurl and C++ - Post JSON Data

I have an application that successfully retrieves and parses json data using libcurl. Now I would like to post data. I am able to do it using curl through the command line, but when I attempt to do it programmatically, I get a 400, Bad Request, error. The json data appears to be formatted correctly and goes in through the command line just fine. I have tried both escaping the quotes (\") and leaving them alone for the libcurl code. My curl options look like:

	curl = curl_easy_init();

	headerList = curl_slist_append(headerList, "Authorization: Basic TOKENHERE=");
	sprintf_s(targUrl, "https://myurl/createorder");
	curl_easy_setopt(curl, CURLOPT_URL, targUrl);
	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, dataToPost);
	curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, datalen);
	curl_easy_setopt(curl, CURLOPT_POST, 1);
	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerList);
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &writeCallback);
	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); 
	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
	curl_easy_setopt(curl, CURLOPT_CAINFO, "C:\\path\\cacert.pem");


Open in new window

Avatar of jkr
Flag of Germany image

What does the JSON data look like?

BTW, here's a simple escaping helper for JSON data taken from production code:

void EscapeJSON(const std::string& sSrc, std::string& sDest) {

	size_t sz = sSrc.length();


	sDest = "\"";

	for (size_t i = 0; i < sz; ++i) {

		string sTmp;

		switch(sSrc[i]) {

			case '\"':
				sTmp = "\\\"";

			case '\\':
				sTmp = "\\\\";

			case '\r':
				sTmp = "\\r";

			case '\t':
				sTmp = "\\t";

			case '\n':
				sTmp = "\\n";

				sTmp = sSrc[i];

		sDest += sTmp;

	sDest += '\"';

Open in new window

Avatar of AmyL


The json set looks like this (it works fine from the curl command line):

{ \"orderId\": \"12345\", \"orderDate\": \"2015-04-08T15:30:29\",  \"paymentDate\": \"2015-04-08T15:30:29\",  \"orderStatus\": \"waiting\",  \"customerUsername\": \"usrnm\",  \"customerEmail\": null,  \"billTo\": {    \"name\": \"test\",    \"company\": null,    \"street1\": null,    \"street2\": null,    \"street3\": null,    \"city\": null,    \"state\": null,    \"postalCode\": null,    \"country\": \"US\",    \"phone\": null,    \"residential\": null  },    \"shipTo\": {    \"name\": \"John Doe\",    \"company\": null,    \"street1\": \"123 Test\",    \"street2\": \"test\",    \"street3\": null,    \"city\": \"test\",    \"state\": \"CA\",    \"postalCode\": \"11111\",    \"country\": \"US\",    \"phone\": \"555-1212\",    \"residential\": true  },  \"items\": [  {      \"lineItemKey\": null,      \"sku\": \"11111\",      \"name\": \"test\",      \"imageUrl\": null,      \"weight\": {        \"value\": 24,        \"units\": \"ounces\"      },      \"quantity\": 2,      \"unitPrice\": 6.86,      \"warehouseLocation\": null,	  \"options\": []    } ],  \"amountPaid\": 10.72,  \"taxAmount\": 0,  \"shippingAmount\": 0,  \"customerNotes\": null,  \"internalNotes\": \" \",  \"gift\": false,  \"giftMessage\": null,  \"requestedShippingService\": \"UPS\",  \"paymentMethod\": null,  \"carrierCode\": \"ups\",  \"serviceCode\": \"ups_ground\",  \"packageCode\": null,  \"confirmation\": null,  \"shipDate\": \"2015-04-08\",  \"weight\": {    \"value\": 0,    \"units\": \"ounces\"  },  \"dimensions\": {    \"units\": \"inches\",    \"length\": 7,    \"width\": 5,    \"height\": 6  },  \"insuranceOptions\": {    \"provider\": null,    \"insureShipment\": false,    \"insuredValue\": 0  },	\"internationalOptions\": {    \"contents\": null,    \"customsItems\": null  },  \"advancedOptions\": {    \"warehouseId\": 14933,    \"nonMachinable\": false,    \"saturdayDelivery\": false,    \"containsAlcohol\": false,    \"storeId\": 9,    \"customField1\": \"Some custom data\",    \"customField2\": null,    \"customField3\": null,    \"source\": null  }}

Open in new window

Ah, I see. Well, try the escape helper above, you need the changes to be applied. And it works fine for us for a couple of years now ;o)
Avatar of AmyL


The json is already escaped. I think the problem is that it is stored in SQL Server and then pulled out for the transaction. There must be some modification that is made that I am not seeing.
Yes, it is escaped, but to POST it, it needs to be run through the code - sorry for being a bit breief, my cold isn't really helping.  Mind just giving it a shot? I swear to never mention it again if I am wrong ;o)
Avatar of AmyL

Link to home
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial