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?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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
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
Angular Fundamentals

Learn the fundamentals of Angular 2, a JavaScript framework for developing dynamic single page applications.

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
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.