CURL Post method in c++ - c++

Suppose we have a HTTP request like following:
POST /safebrowsing/downloads?client=Firefox&appver=3.0.8&pver=2.2&wrkey=AKEgNiux-3bBzAgJeFWgqbneh_GLc2OrmgXnpxPrdH1-hFpbAM8k1ovPA8GB_UMRueBHnL3QJ7gsdQOWVm6QJr_VZNgAm8jmLQ== HTTP/1.1
Host: safebrowsing.clients.google.com
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko/2009033100 Ubuntu/9.04 (jaunty) Firefox/3.0.8
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Content-Length: 120
Content-Type: text/plain
Cookie: PREF=ID=551a1b8848e36099:U=e6fa7464d7c48884:FF=0:TM=1327553284:LM=1345022478:S=Qd0IssyrqLi17a4s; NID=62=R9Y5bkQ5iLF8zlyhma1gnRBfxPDoWuG2FibC2wc5u0eAIQgAuo4WCXMeLhdPZ7FXJEpN2Sw1a6da6QUNP7OC5OqTYK0Y39vd6c2fUh4BhY2B5CGsKtHuQ5RCpSnefSkb
goog-malware-shavar;a:83372-91327:s:59904-95254:mac
goog-phish-shavar;a:227421-233955,235041-235401:s:107142-110470:mac
I already built up the part of code to handle the headers. However, the message-body part I'm not sure how to deal with. I have read CURL sample code, they provide solution for HTTP form POST which is not the way to handle my data. Does anyone know what parameter I should use to handle message-body using curl_easy_setopt() function?

FYI: cURL provides a very convenient option that lists the ad-hoc options for a given HTTP request:
--libcurl <file> Dump libcurl equivalent code of this command line
When in doubt you should perform your request via cURL (and corresponding options, e.g. to perform a POST, etc) while using this option since it outputs the list of curl_easy_setopt options:
curl --libcurl out.c http://stackoverflow.com/ > /dev/null
Then open the out.c file within your editor:
...
curl_easy_setopt(hnd, CURLOPT_URL, "http://stackoverflow.com/");
curl_easy_setopt(hnd, CURLOPT_PROXY, NULL);
curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 0);
...

const char *post_data = "any_data";
...
curl_easy_setopt(curl_handle, CURLOPT_POST, 1);
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, post_data);

Related

Read Request Payload in ColdFusion

Trying out Content Security Policy and using the Report Only method and the data is sending a POST (See edits, supposed to be POST, but Request Headers say GET) to my page which I then use to email myself. In the browser developer tools I can see the data in the Request Payload, but I don't know how to access this scope. The FORM scope is empty and the GetHttpRequestData() doesn't show a Payload key.
How do I access the data in the Request Payload in ColdFusion?
EDIT: In the dev tools I can see in the network tab a POST to the page with 4 sections: General, Response Headers, Request Headers and Request Payload. I need to access the Request Payload data.
Request Headers:
GET /campuses/content-report/ HTTP/1.1
Host: domain.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36
Accept: */*
Referer: http://domain.com/page/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: **[Removed]**
Request Payload:
{
"csp-report":{
"document-uri":"http://domain.com/page/",
"referrer":"http://domain.com/",
"violated-directive":"default-src 'self' 'sha256-L2Tc50iUaBz2udc-dnkwO-FKzrsl5cLnzkFu5LgX5ao=' https://stats.g.doubleclick.net http://netdna.bootstrapcdn.com http://www.google-analytics.com https://www.google.com https://fonts.gstatic.com https://ajax.googleapis.com https://cdn.jsdelivr.net https://maxcdn.bootstrapcdn.com http://www.etutoring.org",
"effective-directive":"img-src",
"original-policy":"default-src 'self' 'sha256-L2Tc50iUaBz2udc-dnkwO-FKzrsl5cLnzkFu5LgX5ao=' https://stats.g.doubleclick.net http://netdna.bootstrapcdn.com http://www.google-analytics.com https://www.google.com https://fonts.gstatic.com https://ajax.googleapis.com https://cdn.jsdelivr.net https://maxcdn.bootstrapcdn.com;style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://maxcdn.bootstrapcdn.com;script-src 'self' https://www.google-analytics.com https://ajax.googleapis.com https://cdn.jsdelivr.net 'nonce-3E89EBDB49F712C7D90D1B39E348BBBF';report-uri /campuses/content-report;",
"blocked-uri":"https://www.google-analytics.com",
"status-code":200
}
}
GetHttpRequestData contains Request Headers but not Request Payload. I did notice that the website I read said the Security policy would send the data via POST but the Headers say GET. Would that cause the issue? Should they be in the URL scope? Not at my machine at the moment.
So I was looking in the right spot, GetHttpRequestData but what I didn't realize was I setup the url to not have a trailing slash and my IIS Rewrite rules was redirecting to the / version of the page and the header data was being lost in the process.

How to set proxy authorization in libcurl

Actually I am trying to post some data to the URL.But I am getting stuck because of proxy.
The below code snippet is always giving proxy authorization required even though setting the values.
Please let me know any thing needs to be changed in the code.
Here is the code snippet that I am using
curl_easy_setopt(curl_handle, CURLOPT_PROXY, "proxy proxy.xyz.com:8080");
curl_easy_setopt(curl_handle, CURLOPT_PROXYTYPE, "CURLPROXY_HTTP");
curl_easy_setopt(curl_handle, CURLOPT_USERPWD, "abc/xyz:pwd");
curl_easy_setopt(curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, jsonResult);
curl_easy_setopt(curl_handle, CURLOPT_URL, "http://username:password#url");
curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, error);
res = curl_easy_perform(curl_handle);
if(res != CURLE_OK)
{
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
return false;
}
I have used the CURLOPT_VERBOSE option
Below is the output
* About to connect() to proxy proxy.xyz.com port 8080 (#0)
* Trying proxy ip... * connected
* Server auth using Basic with user 'abc/xyz'
> POST http://username:password#url HTTP/1.1
Authorization: Basic aW5kaWEvNjY2NTU3Ok5vdkAyMDE0
Host:ip:8080
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 53
Content-Type: application/x-www-form-urlencoded
* upload completely sent off: 53 out of 53 bytes
< HTTP/1.1 407 Proxy Authorization Required
< Date: Thu, 04 Dec 2014 05:17:15 GMT
< Via: 1.1 localhost.localdomain
< Proxy-Connection: keep-alive
< Cache-Control: no-store
< Content-Type: text/html
< Content-Language: en
< Proxy-Authenticate: Negotiate
< Proxy-Authenticate: NTLM
< Content-Length: 322
<
<HEAD><TITLE>Proxy Authorization Required</TITLE></HEAD>
<BODY BGCOLOR="white" FGCOLOR="black"><H1>Proxy Authorization Required</H1><HR>
<FONT FACE="Helvetica,Arial"><B>
Description: Authorization is required for access to this proxy</B></FONT>
<HR>
<!-- default "Proxy Authorization Required" response (407) -->
</BODY>
* Connection #0 to host proxy.xyz.com left intact
Thanks in advance
If you still get a 407 back, it means the proxy rejected the credentials (or method) you used.
Set CURLOPT_VERBOSE and verify that the request looks like you want it and double-check that the proxy really accepts what you send it.
CURLOPT_PROXYTYPE is not a string so the code you shown above will not work. In fact, proxy type HTTP is default if not set so you can just remove that line.
Finally, not related to your problem, but using CUSTOMREQUEST like that is not recommended since POSTFIELDS already implies a POST.

How to invoke REST Webservice from the javascript by Preflight Request?

I am trying to invoke the service which was in another domain from the javascript itself. I could able to request the cross domain service . But I cant retrieve the information from the service. Some how I have been blocked by the same origin policy. Please help me to find the errors in the code.
My Client side Javascript Code :
var requestJsonData;
function crossDomainCall(){ ** It will be called by button click **
requestJsonData = createCORSRequest('POST', 'IPAddress/servicePath');
if (requestJsonData){
requestJsonData.onreadystatechange = handler;
requestJsonData.send();
}
else {
alert('Cross Domain Call is not invoked');
}
}
function handler(evtXHR) {
if(requestJsonData.readyState == 4) {
if(requestJsonData.status == 200) {
var response = requestJsonData.responseText;
}
else {
alert(" Invocation Errors Occured " + requestJsonData.readyState + " and the status is " + requestJsonData.status);
}
}
else {
alert("currently the application is at " + requestJsonData.readyState);
}
}
function createCORSRequest(method, url){
var xhr;
xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
xhr.open(method, url, true);
xhr.setRequestHeader('X-PINGOTHER', 'pingpong');
} else if (typeof XDomainRequest != "undefined"){
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}
Service code :
#OPTIONS
#Path("/servicePath")
#Produces("*/*")
#Consumes("*/*")
public Response corsRequest() {
Response response = null;
ResponseBuilder builder = null;
builder = Response.ok();
builder.header("Access-Control-Allow-Headers", "X-PINGOTHER");
builder.header("Access-Control-Max-Age","1728000");
builder.header("Access-Control-Allow-Origin","Origin_Ip_Address");
builder.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
builder.header("Content-Type","text/plain");
builder.header("Connection", "Keep-Alive");
response = builder.build();
System.out.println("Exited from Options method");
return response;
}
#POST
#Path("/servicePath")
#Produces("application/json")
public String drawRegions() {
System.out.println("Entered inside Post method");
// Some calculation to arrive jsonObject.
return jsonObject;
}
From the code, I have received the following as a results.
OPTIONS Method Request and Response Headers
Request Headers :
OPTIONS /SolartisGeoCodeLookUpService/Service/drawRegions HTTP/1.1
Host: Cross_Domain_IP_Address
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:25.0) Gecko/20100101 Firefox/25.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: Origin_IP_Address
Access-Control-Request-Method: POST
Access-Control-Request-Headers: x-pingother
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Response Headers
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Access-Control-Allow-Headers: X-PINGOTHER
Connection: Keep-Alive
access-control-allow-origin: Origin_IP_Address
Access-Control-Max-Age: 1728000
Access-Control-Allow-Methods: POST, GET, OPTIONS
Content-Type: text/plain
Content-Length: 0
Date: Thu, 12 Dec 2013 12:39:27 GMT
Response Cache Header
Response Headers From Cache
Access-Control-Allow-Head... X-PINGOTHER
Access-Control-Allow-Meth... POST, GET, OPTIONS
Access-Control-Max-Age 1728000
Connection Keep-Alive
Content-Length 0
Content-Type text/plain
Date Thu, 12 Dec 2013 12:39:27 GMT
Server Apache-Coyote/1.1
access-control-allow-original Origin_IP_Address
POST Method Request and Response Headers
Request Headers
POST /servicePath HTTP/1.1
Host: crossDomain_IP_Address
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:25.0) Gecko/20100101 Firefox/25.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
X-PINGOTHER: pingpong
Origin: Origin_IP_Address
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Content-Length: 0
Response Headers
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/json
Content-Length: 128
Date: Thu, 12 Dec 2013 12:39:27 GMT
ADDITIONAL INFO
From the javascript two times the handler method has been called. At the First time, It is comeup with "currently the application is at 2" - readyState value. At the Second time, It is comeup with "Invocation Errors Occured 4(readyState value) and status code is 0 (response status code)". The second time response clearly says, invoking the service has been stopped by the same origin policy. But I dont know How to overcome from this problem and have to access the resource. Please help me by correcting my code.
Instead of dealing with X domain calls in javascript, why don't you develop a service local to your application that consumes the web service in the other domain, then you can call you local service from javascript.
I would suggest also, and alternatively, that you use jQuery to perform that Cross Domain Ajax call, see this link: http://www.pureexample.com/jquery/cross-domain-ajax.html.
There is no need to deal with XHR directly since you have jQuery to do it for you.
Hope this helps,
Regards.

Error 411 (Length Required) in post request with header, but header has Content-Length. libCurl

I use this options:
curl_easy_setopt(curl, CURLOPT_URL, urlUpload);
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header);
It must be post request with header. And in header variable there is length
***
char sizeStr[50];
sprintf(sizeStr, "Content-Length: %d", body.length());
***
header = curl_slist_append(header, sizeStr);
***
What I'm trying to do is to upload video to YouTube, I'm using their manual
And I receive such error.
<!DOCTYPE html>
<html lang=en>
<meta charset=utf-8>
<title>Error 411 (Length Required)!!1</title>
<style>
*many symbols here*
</style>
<a href=//www.google.com/ id=g><img src=//www.google.com/images/logo_sm.gif alt=Google></a>
<p><b>411.</b> <ins>Thatв€™s an error.</ins>
<p>POST requests require a <code>Content-length</code> header. <ins>Thatв€™s all we know.</ins>
Maybe I must use some other CURLoptions?
UPDATE:
when I set
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
I also receive
* About to connect() to uploads.gdata.youtube.com port 80 (#0)
* Trying 74.125.XX.XXX... * connected
* Connected to uploads.gdata.youtube.com (74.125.XX.XXX) port 80 (#0)
> POST /feeds/api/users/default/uploads HTTP/1.1
Accept: */*
Host: uploads.gdata.youtube.com
Authorization: GoogleLogin auth=DQAAAIkAAACTK9tZPCTY1XQvXGkg4qkaIuZ1QO-Bh6- ZyzOHuigFNC_gR4Piep4NljAjdOP4s-k7vqj-j4LdckXM9jxzlElgtaxr- CShI1vIWkjm5ZtFsj3a9v1YqFmjIkEi3NCP2ON18D9jmXSIarPqprWiOK0n3oxznCBhm4osXwJ1yRstVVM5bG5mOlC331eMCrOKp3E
GData-Version: 2
X-GData-Key: key=AI39si59VMkm6DATDmfG_Df6D23jfto3xRVfbAEMrFBv035pdRZ5AYMPsRXbGLCRXXnK5jz6KCSWSkuXOTrlDIIKWy7Le9fkQQ
Slug: screen.avi
Content-Type: multipart/related; boundary="d31fcjR2"
Content-length: 910273
Connection: close
* HTTP 1.0, assume close after body
< HTTP/1.0 411 Length Required
< Content-Type: text/html; charset=UTF-8
< Content-Length: 11791
< Date: Fri, 02 Sep 2011 16:09:58 GMT
< Server: GFE/2.0
<
* Closing connection #0
This error was because in the authentication string that I receive from YouTube was in the end the new line symbol, I erase it and this error disappeared.
CURLOPT_POSTFIELDS will make a content-length get added automatically by libcurl, no need to make a custom one. However, as you're already sending a content-length header that is clearly not the missing length the server is talking about.
Your request also sends a "Connection: close" so there's something more of the code that you didn't show us.

Django CSRF failure on ajax post requests on Opera only

Ok so AJAX POST requests work fine in Mozilla and Chromium, but fail in Opera. I get the standard CSRF error (403). I tried different versions of Opera and they failed in every one I tried. Btw, I'm using the jquery/django snippet that sets X-CSRFToken in the header, as verified in the "bad Opera request" below.
I made a view in a different project that was very simple and ajax post requests worked fine in Opera. I looked at the request details and see differences. The good request doesn't set any weird X-Opera-Info and other opera params even thought I'm using the same browser. If this is the issue, is there a way to remove those extra params? Or does anyone have any other advice or ideas on what the issue may be? I know it's not my view function because I tried just returning an HttpResponse immediately and even that gets 403'd. Thanks a million guys.
####################
OPERA GOOD REQUEST
##############
Request details
POST /test HTTP/1.1
User-Agent: Opera/9.80 (X11; Linux i686; U; en) Presto/2.7.62 Version/11.00
Host: 127.0.0.1:8000
Accept-Language: en-US,en;q=0.9
Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
Referer: http://127.0.0.1:8000/test
Cookie: csrftoken=1c6441404c991f7ae3b6d7d49f91f280
Cookie2: $Version=1
Connection: Keep-Alive, TE
TE: deflate, gzip, chunked, identity, trailers
Content-Length: 6
Content-Type: application/x-www-form-urlencoded
Accept: */*
X-CSRFToken: 1c6441404c991f7ae3b6d7d49f91f280
X-Requested-With: XMLHttpRequest
Content-Transfer-Encoding: binary
###################
OPERA BAD REQUEST
####################
Request details
POST http://facebook.example.com/remove-person HTTP/1.1
User-Agent: Opera/9.80 (X11; Linux i686; U; en) Presto/2.7.62 Version/11.00
Host: facebook.example.com
Accept-Language: en-US,en;q=0.9
Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
Referer: http://facebook.example.com/
Cookie: signed_request=5-f0_7pZLILrp6MLocsdMoNYAaZr-wCnU2cPbLC1bZg.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImV4cGlyZXMiOjEzMDg4MTYwMDAsImlzc3VlZF9hdCI6MTMwODgxMTQyNywib2F1dGhfdG9rZW4iOiIyMjMyNDY5NDEwMjc3MTR8Mi5BUURVRGM2ZFFLSElnN1h3LjM2MDAuMTMwODgxNjAwMC4xLTU0MDIwMjZ8b2QtX1diNTh3aG1wTnNHYUh4cTNtOVBpWkswIiwidXNlciI6eyJjb3VudHJ5IjoidXMiLCJsb2NhbGUiOiJlbl9VUyIsImFnZSI6eyJtaW4iOjIxfX0sInVzZXJfaWQiOiI1NDAyMDI2In0; csrftoken=d4cdc6a75ed264d295a410dd98982c42; fbs_223246941027714="access_token=223246941027714%7C2.AQBlhzavZjzd8c7J.3600.1308819600.1-5402026%7CdsD6VESpGJb3m0EdD1mhFZtDI24&base_domain=example.com&expires=1308819600&secret=QaTNS988wl0FU6A0LG9qDQ__&session_key=2.AQBlhzavZjzd8c7J.3600.1308819600.1-5402026&sig=61e7e13091501f35793d3cda8c20835b&uid=5402026"
Cookie2: $Version=1
Connection: Keep-Alive, TE
TE: deflate, gzip, chunked, identity, trailers
Content-Length: 14
X-Opera-Info: ID=448, p=4, f=15, sw=1440, sh=900
X-Opera-ID: e79c37b56a58510d26b56882453bddb6d2c2dae858129139113f6346ea23ca6b
X-Opera-Host: r18-02:12420
X-OA: 1322 b5834cb13259fbd50b87b576b5e8b9a8bcc1384478c2ea79cc65614dc1b67c27
X-OB: evenes
Content-Type: application/x-www-form-urlencoded
Accept: */*
X-CSRFToken: d4cdc6a75ed264d295a410dd98982c42
X-Requested-With: XMLHttpRequest
Content-Transfer-Encoding: binary
I recently ran into a similar problem. I was trying to do, for the first time, a post from AJAX on a view where Django wasn't sending a CSRF cookie. For reasons I can't explain, this was working on all browsers I tried except Opera.
This scenario is described in the Django docs, and they suggest using the ensure_csrf_cookie decorator.
Another thing you can do if it is too burdensome to wrap all the potential views with that decorator is to add something like this to your base template:
<script>
var csrf_token = "{{ csrf_token }}";
</script>
And then whenever you do an AJAX post, always include the key pair csrfmiddlewaretoken: csrf_token with your POST data.
Once I did the above, my posts with Opera started working.
Does it work if you disable Opera Turbo? These extra headers seem to be Turbo-related and perhaps this makes some kind of difference.
X-CSRFToken: {{ csrf_token }}}
value should be send from client in AJAX request HTTP headers to be recognized by Django