I am writing code for http request to get string message. i somehow successful in it. here is my code for http request via curl.
#include "stdafx.h"
#include <stdio.h>
#include "curl/curl.h"
int main(void)
{
CURL *curl;
CURLcode res;
/* In windows, this will init the winsock stuff */
curl_global_init(CURL_GLOBAL_ALL);
/* get a curl handle */
curl = curl_easy_init();
if(curl) {
/* First set the URL that is about to receive our POST. This URL can
just as well be a https:// URL if that is what should receive the
data. */
curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.1.7:8080/asigra_1/helloword.jsp");
/* Now specify the POST data */
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=daniel&project=curl");
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
/* always cleanup */
curl_easy_cleanup(curl);
}
curl_global_cleanup();
system("pause");
return 0;
}
I can get following output for it
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.or
g/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
hello word
</body>
</html>Press any key to continue . . .
This is whole web page i just need "hello world" in my output not whole page info how should i can do it with curl.
Here's some resources that you can pick and select from to craft up your code as you wish:
getinmemory.c shows how you download data directly into a memory buffer of your own.
htmltidy.c shows how you can do another trick and parse the HTML directly at download. This particular example uses LibTidy to do that job but you may of course opt to use something else, parse it yourself.
htmltitle.cpp is a C++ example that uses libxml2 to parse out the <title> of the downloaded page, which also serves as an example of almost what you're asking for.
Related
I'm trying to use Dropbox API to get some metadata info of a file inside my dropbox.
Here is my post code
std::ostringstream stream;
curl_slist* headers = NULL;
CURL* curl = curl_easy_init();
char data[50];
snprintf(data, sizeof(data), "{\"path\":\"%s\"}", "/3.png");
curl_easy_setopt(curl, CURLOPT_URL, "https://api.dropboxapi.com/2/files/get_metadata");
headers = curl_slist_append(headers, "Authorization: <MY TOKEN>");
headers = curl_slist_append(headers, "\"Content-Type\":\"application/json\"");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &stream);
/* size of the POST data */
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 30L);
/* pass in a pointer to the data - libcurl will not copy */
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, R"({"path":"/3.png"})"); //Tried data char array it doesn't work too.
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK)
return 0;
/* convert stream to string format */
std::string output = stream.str();
curl_easy_cleanup(curl);
It returns HTTP 400 code
Thats the error I get after http post with curllib
<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Dropbox</title>
<link href="https://cfl.dropboxstatic.com/static/metaserver/static/css/error.css" rel="stylesheet" type="text/css"/>
<link rel="shortcut icon" href="https://cfl.dropboxstatic.com/static/metaserver/static/images/favicon.ico"/>
</head>
<body>
<div class="figure">
<img src="https://cfl.dropboxstatic.com/static/metaserver/static/images/illustration_catalog/sickbox-illo_m1.png" srcset="https://cfl.dropboxstatic.com/static/metaserver/static/images/illustration_catalog/sickbox-illo_m1#2x.png 2x" alt="Error: 5xx"/>
</div>
<div id="errorbox">
<h1>Error</h1>Something went wrong. Don't worry, your files are still safe and the Dropboxers have been notified. Check out our Help Center and forums for help, or head back to home.
</div>
On PostMan it gives good response but in my C++ code it gives me error as you can see on above
Http web request body should be something like this
{
"path": "/3.png"
}
Here is response that I get from PostMan
{
".tag": "file",
"name": "3.png",
"path_lower": "/3.png",
"path_display": "/3.png",
"id": "id:kVJQZOYYiMsAAAAAAAAABg",
"client_modified": "2023-02-01T18:54:24Z",
"server_modified": "2023-02-01T18:54:24Z",
"rev": "015f3a7fa16a9c100000002912dfcc0",
"size": 5160,
"is_downloadable": true,
"content_hash": "feb3516ea07bab6053eecc7367ee9c282846f7bc17751b2819b85aa0f3ddefb5"
}
This line:
headers = curl_slist_append(headers, "\"Content-Type\":\"application/json\"");
Looks suspicous with all the inlined quotes around it.
Shouldn't it just be:
headers = curl_slist_append(headers, "Content-Type: application/json");
What you should do is get a tool like Fiddler, Charles, or similar HTTP capture proxy tool and compare the request/response sent by your application and compare it to the one sent by Postman. I think you'll see a discrepancy or two if the above doesn't fix it.
I need to send html table as email body. I just did the below to mention content type as html, but it did not work.
headers = curl_slist_append(headers, "Content-Type: text/html");
/* pass our list of custom made headers */
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
I couldn't find an example from the library site.
CURLOPT_HTTPHEADER will not work with any of the SMTP options (CURLOPT_MAIL_FROM, CURLOPT_MAIL_RCPT, CURLOPT_MAIL_AUTH). Instead you need to use CURLOPT_READFUNCTION.
/* Disclaimer: untested code */
char *msg = "To: bob#example.com\r\n"
"From: alice#example.com\r\n"
"Content-Type: text/html; charset=us-ascii\r\n"
"Mime-version: 1.0\r\n"
"\r\n"
"<html><head>\r\n"
"<meta http-equiv=\"Content-Type\" content="text/html; charset=us-ascii\">\r\n"
"</head><body>\r\n"
"<p>Hi Bob</p>\r\n"
"</body></html>\r\n"
size_t callback(char *buffer, size_t size, size_t nitems, void *instream) {
/* you actually need to check that buffer <= size * nitems */
strcat(buffer, msg);
return strlen(buffer);
}
curl_easy_setopt(curl, CURLOPT_READFUNCTION, callback);
curl_easy_perform(curl);
The documentation for CURLOPT_READFUNCTION has more info. Although, if you're already sending plain text emails, you have been there.
The only real "trick" here that is not presented in Sending Mail Through Curl linked by sameerkn is that you simply dump the Content-Type header inside the email buffer. There is no clever header setting like with HTTP.
Also: i'm not sure whether you need a Content-Transfer-Encoding header, i've set the charset above to us-ascii but things like utf-8 might need transfer encoding.
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); will set the HTTP Protocol Header in your request.
The header which you are showing applies to E-Mail Data (Header section).
E-Mail Data Format: (It has 2 sections, Header and Body separated by blank line)
Header: value
Header: value
Content-Type: text/html; charset="UTF-8"
//**********************// << this is a blank line between Header and Body
Body Of Mail
Does your email contains only HTML?
Try adding following header to Email Headers as well: Content-Transfer-Encoding
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="UTF-8"
quoted-printable is an encoding done to your HTML data. You can encode data as base64 as well.
Content-Transfer-Encoding: base64
**EDIT: If you are trying to send mail using curl then please refer
Send Mail Through CURL
I want to implement OAuth 1.0 protocol in order to work with COPY. But when i implemented OAuth protocol in C++ in order to get Request Token and sent that request to copy it's return that signature is invalid and i can't figure out what's wrong in my signature. Here are all parameters that i generate by my program:
oauth_nonce=xoviybpokqnxdwlnkeoorawfijgezr
oauth_timestamp=1381745375
oauth_callback=http%3A%2F%2Fcopy-oauth.local%2Fget_access_token.php
oauth_signature_method=HMAC-SHA1
This is base string that i used in order to generate token:
GET&https%3A%2F%2Fapi.copy.com%2Foauth%2Frequest&oauth_consumer_key%3D[my
32 symbols
key]%26oauth_nonce%3Dxoviybpokqnxdwlnkeoorawfijgezr%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1381745375%26oauth_tokey%3D
It's key for generating signature:
[My consumer secret, 48 symbols]&
Here is signature that i received after base64 and percent encoded:
lNaaOaWyGtkJWj%2BVLjLlKTVGYL0%3D
And the last thing is sending all parameters to server. For this purpose i use libcurl:
char * abc="https://api.copy.com/oauth/request/?oauth_callback=http%3A%2F%2Fcopy-oauth.local%2Fget_access_token.php&oauth_consumer_key=[my 32 symbols key]&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1381745375&oauth_nonce=xoviybpokqnxdwlnkeoorawfijgezr&oauth_signature=lNaaOaWyGtkJWj%2BVLjLlKTVGYL0%3D";
CURL *curl;
CURLcode res;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl)
{
curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, TRUE);
curl_easy_setopt(curl, CURLOPT_CAINFO, "C:\\a\\a\\a\\cacert.pem");
curl_easy_setopt(curl, CURLOPT_URL, abc);
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
/* always cleanup */
curl_easy_cleanup(curl);
}
curl_global_cleanup();
Then my console will output:
oauth_error_message=oauth_problem%3Dsignature_invalid%26debug_sbs...
What's wrong in my implementation?
The main problem was that oauth_callback should be two time percent encoded in order to create signature base string. This is string that I send in request:
oauth_callback="http://copy-oauth.local/get_access_token.php"
And this is string that I add to signature base string:
http%253A%252F%252Fcopy-oauth.local%252Fget_access_token.php
Here are a few things that immediately spring to mind:
Your signature base string should include the oauth_callback parameter
oauth_token should not be included in the signature base string as you are not including it in your querystring parameters
The path of your url should not end in a forward slash unless you also include for this in your signature base string:
char * abc="https://api.copy.com/oauth/request?oauth_callback= ...
You should remove the '&' character from the end of your querystring
Ive a problem and i cant figure at all how i can manage to solve the following problem:
I would like to send multiple http request to an axis camera.
Here's my code:
#include <stdio.h>
#include <curl/curl.h>
int main(void)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http:/root:309#IPADDRESS");
/* example.com is redirected, so we tell libcurl to follow redirection */
// curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
res=curl_easy_perform(curl);
curl_easy_setopt(curl, CURLOPT_URL, "http:/IPADDRESS/axis-cgi/com/ptz.cgi?move=left");
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}
All i want to do in this example, is to keep my session alive after being logged to the IPaddress, and then send the order "move=left" to this very ip address.
When i execute this program, i got those messages:
<HTML>
<HEAD>
<META HTTP-EQUIV="Expires" CONTENT="Tue, 01 Jan 1980 1:00:00 GMT">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Refresh" CONTENT="0; URL=/view/index.shtml">
Your browser has JavaScript turned off.<br>For the user interface to work effectively, you must enable JavaScript in your browser and reload/refresh this page.
</noscript>
</HEAD>
<BODY>
</BODY>
</HTML>
<HTML><HEAD><TITLE>401 Unauthorized</TITLE></HEAD>
<BODY><H1>401 Unauthorized</H1>
Your client does not have permission to get URL /axis-cgi/com/ptz.cgi from this server.
</BODY></HTML>
I assume that i wasnt even logged to the ipaddress...
I never really used this kind of method before... Can you help me with this?
Thank you a lot.
You need to add these two options:
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "cookie.txt");
curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "cookie.txt");
From documentation:
CURLOPT_COOKIEFILE
Pass a pointer to a zero terminated string as parameter. It should
contain the name of your file holding cookie data to read. The cookie
data may be in Netscape / Mozilla cookie data format or just regular
HTTP-style headers dumped to a file.
Given an empty or non-existing file or by passing the empty string
(""), this option will enable cookies for this curl handle, making it
understand and parse received cookies and then use matching cookies in
future requests.
If you use this option multiple times, you just add more files to
read. Subsequent files will add more cookies.
CURLOPT_COOKIEJAR
Pass a file name as char *, zero terminated. This will make libcurl
write all internally known cookies to the specified file when
curl_easy_cleanup(3) is called. If no cookies are known, no file will
be created. Specify "-" to instead have the cookies written to stdout.
Using this option also enables cookies for this session, so if you for
example follow a location it will make matching cookies get sent
accordingly.
If the cookie jar file can't be created or written to (when the
curl_easy_cleanup(3) is called), libcurl will not and cannot report an
error for this. Using CURLOPT_VERBOSE or CURLOPT_DEBUGFUNCTION will
get a warning to display, but that is the only visible feedback you
get about this possibly lethal situation
Read more at: http://curl.haxx.se/libcurl/c/curl_easy_setopt.html
I am using the CURL c++ api to get quotes from Yahoo's financial API. The curl api and my code seem to be working fine, however I am getting a "301" redirect message when I tell CURL to visit the url I want. How can I get CURL to follow through to the 301 redirect and get the data I want?
Here is the URL I am using:
http://download.finance.yahoo.com/d/quotes.csv?e=.csv&s=WSF,WSH&f=b2b3s
Here is the response I am getting:
<HEAD><TITLE>Redirect</TITLE></HEAD>
<BODY BGCOLOR="white" FGCOLOR="black">
<FONT FACE="Helvetica,Arial"><B>
"<em>http://download.finance.yahoo.com/d/quotes.csv?e=.csv&s=WSF,WSH,WSM,WSO,WST,WTI,WTM,WTR,WTS,WTU,WTW,WU,WWE,WWW,WX,WXS,WY,WYN,X,XAA,XCJ,XCO,XEC,XEL,XEL-A,XEL-E,XFB,XFD,XFH,XFJ,XFP,XFR,XIN,XJT,XKE,XKK,XKN,XKO,XL,XL-Y,XOM,XRM,XRX,XVF,XVG,Y,YGE,YPF,YSI,YUM,YZC,ZB-A,ZB-B,ZB-C,ZEP,ZF,ZLC,ZMH,ZNH,ZQK,ZTR,ZZ,ZZC&f=b2b3ccd1d2ghjkk2k3l2l3mm2m3m4m5m6m7m8opst7vw</em>".<p></B></FONT>
<!-- default "Redirect" response (301) -->
</BODY>
Here are my CURL init options
CURL *eh = curl_easy_init();
curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, cb);
curl_easy_setopt(eh, CURLOPT_HEADER, 0L);
curl_easy_setopt(eh, CURLOPT_URL, url);
curl_easy_setopt(eh, CURLOPT_PRIVATE, url);
curl_easy_setopt(eh, CURLOPT_VERBOSE, 0L);
curl_multi_add_handle(cm, eh);
I didn't post my code, as it is all working, I just need the general method of following through woth the 301's with CURL.
In the PHP world, the option is named CURLOPT_FOLLOWLOCATION. I assume the constant names are standardized and come from the same header file, so this should work for you.
curl_easy_setopt(eh, CURLOPT_FOLLOWLOCATION, 1);
(or whatever "boolean true" is in this context.)
Alternatively, when receiving a 30x status code, you can parse the Location header manually for the new address. Obviously though, the "follow location" option is much easier, as it doesn't require a second request.