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_global_init(CURL_GLOBAL_ALL);
	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");

	curl_easy_perform(curl);

Open in new window

AmyLAsked:
Who is Participating?
 
AmyLAuthor Commented:
Hi,
Thanks for your help. It turned out to be an extra character added from the database. I removed it and it worked fine.

I would still like to award you the points since you took the time to respond, however, so I was wondering if you could help with one little thing that still remains a bit of a problem?

I created two of these curl-post applications. They are very similar but not exactly the same, and I wanted to keep them separate for deployment purposes. They both need to be installed on the same machine. I simply copied the original solution folder, renamed the solution, project, and deployment project (which I believe is the free version of installshield). They both run correctly individually, but will not let me install both on the same machine at the same time (I get the "this program is already installed" message). Do you know how I can get around that?

Thanks!
Amy
0
 
jkrCommented:
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.erase();

	sDest = "\"";

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

		string sTmp;

		switch(sSrc[i]) {

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

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

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

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

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

			default:
				sTmp = sSrc[i];
				break;
		};

		sDest += sTmp;
	}

	sDest += '\"';
}

Open in new window

0
 
AmyLAuthor Commented:
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

0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

 
jkrCommented:
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)
0
 
AmyLAuthor Commented:
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.
0
 
jkrCommented:
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)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.