I'm trying to send https requests (ssl) to an API server (Last.fm) with libcurl. When i try to send http requests it's OK but when i send https requests it isn't. After many searches in google and stack overflow i get this sample code from internet and try to execute it but it doesn’t work and show this error :
curl_easy_perform() failed: Peer certificate cannot be authenticated with given CA certificates
there is the sample code :
#include <stdio.h>
#include <curl/curl.h>
#include <string.h>
int main() {
CURLcode res;
CURL *handle = curl_easy_init();
char url[] = "https://google.com";
curl_easy_setopt(handle, CURLOPT_URL, url);
res=curl_easy_perform(handle);
if(res==CURLE_OK)
{
printf("OK");
}
else{
printf("curl_easy_perform() failed: %s \n", curl_easy_strerror(res));
}
return 0;
}
P.S: I'm compiling with gcc from my terminal.
I fixed the problem by removing libcurl4-gnutls-dev and installing libcurl4-openssl-dev. If you have the same problem you just need this command :
sudo apt-get install libcurl4-openssl-dev
This removed libcurl4-gnutls-dev automatically.
Related
I'm new to curl library, I installed it yesterday from GitHub, I followed the steps to download it and everything seems good by checking the supported protocols; but when I'm trying to use the library in a C program to download data from a https link I get the error 4.
Supported protocols, nothing looks wrong:
curl 7.83.0-DEV (x86_64-pc-linux-gnu) libcurl/7.83.0-DEV OpenSSL/1.1.1m zlib/1.2.11
Release-Date: [unreleased]
Protocols: dict file ftp ftps gopher gophers http https imap imaps mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS HSTS HTTPS-proxy IPv6 Largefile libz NTLM NTLM_WB SSL TLS-SRP UnixSockets
But when I try to run my C program I get this:
./test https://google.com
ERROR: A requested feature, protocol or option was not found built-in in this libcurl due to a build-time decision.
The code I wrote is this:
#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>
void main(int argc, char *argv[])
{
CURL *curl = curl_easy_init();
int success = 0;
FILE *data = fopen("data", "wb");
if(data==NULL)
{
printf("Error making file for data to be stored.\n");
exit(1);
}
curl_easy_setopt(curl, CURLOPT_URL, argv[1]);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, data);
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
success = curl_easy_perform(curl);
if(success==CURLE_OK)
printf("Download successful.\n");
else
printf("ERROR: %s\n", curl_easy_strerror(success));
fclose(data);
curl_easy_cleanup(curl);
}
type here
Someone know what is wrong??
The linked system libcurl.so runtime is another one than 7.83.0-DEV.
sudo apt intstall ibcurl4-openssl-dev
or
sudo apt intstall libcurl4-gnutls-dev
I’m trying to use libcurl to call Rest API.
My server env : Oracle tuxedo(pro *c), AIX 7.1
It does work using command “curl” on prompt.
I can also see the whole log by using verbose option.
But it keeps stopping when I tried to use it on client compiling with libcurl.
According to log.
It says…
Trying 123.456.789.00:443…
Connected to “api url”(123.456.789.00) port 443 (#0)
ALPN, offering http/1.1
Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
successfully set certificate verify locations :
CAfile: /var/ssl/cert.pem
CApath: /var/ssl/certs/
And it stopped here!!!!
When I use curl command on prompt
It says exactly same,
But keeps going…
TLSv1.2 (OUT), TLS header, Certificate Status (22):
TLSv1.2 (OUT), TLS handshake, Client hello (1):
…
…
Etc…
I have no idea what causes this
And what is the difference…
Can anybody give me some advice please?
Or is there any other way to call RestAPI easily on Pro *C or C?
========================================
All I did is using sample of libcurl.
static sample(){
CURL *curl;
CURLcode res;
curl = curl_easy_init();
struct curl_slist *list = NULL;
if(curl){
curl_easy_setopt(curl, CURLOPT_URL, "https://ApiUrl.here");
list = curl_slist_append(list, "Content-Type: application/json");
list = curl_slist_append(list, "ApiKey : realKey");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
curl_easy_setopt(curl, CURLOPT_SSLVERIFYPEER, 1L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1L);
res = curl_easy_perform(curl);
curl_slist_free_all(list);
if(res != CURLE_OK){
fprintf(stderr, "curl_easy_perform() failed : %s \n", curl_easy_strerror(res));
}
curl_easy_cleanup(curl);
}
}
list = curl_slist_append(list, "ApiKey : realKey");
I think that line is the issue.
RFC7230 3.2.4. Field Parsing
No whitespace is allowed between the header field-name and colon. In
the past, differences in the handling of such whitespace have led to
security vulnerabilities in request routing and response handling. A
server MUST reject any received request message that contains
whitespace between a header field-name and colon with a response code
of 400 (Bad Request). A proxy MUST remove any such whitespace from a
response message before forwarding the message downstream.
Remove the space:
list = curl_slist_append(list, "ApiKey: realKey");
I'm trying to submit a simple HTTP GET request in WebAssembly. For this purpose, I wrote this program (copied from Emscripten site with slight modifications):
#include <stdio.h>
#include <string.h>
#ifdef __EMSCRIPTEN__
#include <emscripten/fetch.h>
#include <emscripten.h>
#endif
void downloadSucceeded(emscripten_fetch_t *fetch) {
printf("Finished downloading %llu bytes from URL %s.\n", fetch->numBytes, fetch->url);
// The data is now available at fetch->data[0] through fetch->data[fetch->numBytes-1];
emscripten_fetch_close(fetch); // Free data associated with the fetch.
}
void downloadFailed(emscripten_fetch_t *fetch) {
printf("Downloading %s failed, HTTP failure status code: %d.\n", fetch->url, fetch->status);
emscripten_fetch_close(fetch); // Also free data on failure.
}
unsigned int EMSCRIPTEN_KEEPALIVE GetRequest() {
emscripten_fetch_attr_t attr;
emscripten_fetch_attr_init(&attr);
strcpy(attr.requestMethod, "GET");
attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY;
attr.onsuccess = downloadSucceeded;
attr.onerror = downloadFailed;
emscripten_fetch(&attr, "http://google.com");
return 1;
}
When I compile it using $EMSCRIPTEN/emcc main.c -O1 -s MODULARIZE=1 -s WASM=1 -o main.js --emrun -s FETCH=1 I get the error
ERROR:root:FETCH not yet compatible with wasm (shared.make_fetch_worker is asm.js-specific)
Is there a way to run HTTP requests from WebAssembly? If yes, how can I do it?
Update 1: The following code attempts to send a GET request, but fails due to CORS issues.
#include <stdio.h>
#include <string.h>
#ifdef __EMSCRIPTEN__
#include <emscripten/fetch.h>
#include <emscripten.h>
#endif
unsigned int EMSCRIPTEN_KEEPALIVE GetRequest() {
EM_ASM({
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://google.com");
xhr.send();
});
return 1;
}
No, you cannot execute HTTP request from WebAssembly (or access DOM, or any other browser APIs). WebAssembly by itself doesn’t have any access to its host environment, hence it doesn’t have any built in IO capabilities.
You can however export functions from WebAssembly, and import functions from the host environment. This will allow you to make HTTP requests indirectly via the host.
I recently ran across this issue with esmcripten fixed it in: https://github.com/kripken/emscripten/pull/7010
You should now be able to use FETCH=1 and WASM=1 together.
Unfortunately, there is no way to make a CORS request to Google.com from any website other than Google.com.
From MDN:
For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. For example, XMLHttpRequest and the Fetch API follow the same-origin policy. This means that a web application using those APIs can only request HTTP resources from the same origin the application was loaded from, unless the response from the other origin includes the right CORS headers.
Google does not include those headers.
Because JavaScript/WebAssembly runs on the client's machine (not yours) you could do nasty things if this wasn't in place, like make POST requests to www.mybankingwebsite.com/makeTransaction with the client's cookies.
If you want to point the code you have in Update 1 to your own site, or run it on Node.js, it should work fine.
I saw some c codes relative to the topic. I've tried them but only I get errors saying a heap of errors of curl.h. I googled much but couldn't find a good answer. I'm using CCS C compiler version v5.008. I really want to solve this problem soon.
I tried to compile the code from the following link.
enter link description here
#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://example.com");
/* example.com is redirected, so we tell libcurl to follow redirection */
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
/* 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;
}
Gives me error: "Error 119"C:\Users\Sisitha\Documents\CCS C Projects\ Testing\curl\curlbuild.h" Line 556(145,183): " Unknown non-configure build target" "
I'm on Windows 7(64bit)
Please help me to solve this matter.
Thanks!
curl uses GNU autotools to be built from source. There's a library to be built and configured, for the example program and header file, to link against. The error :
Error 119"C:\Users\Sisitha\Documents\CCS C Projects\ Testing\curl\curlbuild.h" Line 556(145,183): " Unknown non-configure build target"
Suggests that the curl.h you included, hasn't been configured, by the standard GNU ./configure; make; make install build sequence.
Curl installation instructions Install -- how to install curl
This is my very first C program and I'm using this example libcurl code from their website:
#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, "https://google.com/");
#ifdef SKIP_PEER_VERIFICATION
/*
* If you want to connect to a site who isn't using a certificate that is
* signed by one of the certs in the CA bundle you have, you can skip the
* verification of the server's certificate. This makes the connection
* A LOT LESS SECURE.
*
* If you have a CA cert for the server stored someplace else than in the
* default bundle, then the CURLOPT_CAPATH option might come handy for
* you.
*/
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
#endif
#ifdef SKIP_HOSTNAME_VERFICATION
/*
* If the site you're connecting to uses a different host name that what
* they have mentioned in their server certificate's commonName (or
* subjectAltName) fields, libcurl will refuse to connect. You can skip
* this check, but this will make the connection less secure.
*/
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
#endif
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}
So in xcode I created a "group" called it curl and added all the files in the curl directory:
And now I'm getting these Build errors:
What am I doing wrong? Any advice would help, thanks!
Mac OS X comes with a copy of libcurl, so your application doesn't need its own copy.
You didn't mention the version of Xcode you're using. The following applies to 3.2, but may not work in 4.
To use the version of libcurl provided by the system, go to Project, then Add To Project. In the dialog that comes up, type /usr/lib and press enter. Find libcurl.dylib in the list of files and click Add.
For Xcode 4.5:
Click on the project in the left pane.
Click on the target.
Go to the "Build Phases" section.
Under "Link Binary with Libraries", click the plus sign.
From there you should be able to search for "libcurl.dylib".
Now when you build it should be able to link to the library.
For XCode 7, just right click on the project or group you want to put the lib in, then select Add Files to "Project Name"..., and finally find the libcurl.dylib in /usr/lib directory.