C Request Library
C library similar to Python requests library
Loading...
Searching...
No Matches
Classes | Macros | Typedefs | Functions
crequests.h File Reference
#include <curl/curl.h>
Include dependency graph for crequests.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  CREQ_GET_PARAMS
 Structure to hold the GET/POST parameters. More...
 
struct  CREQ_HEADER
 
struct  CREQ_REDIRECTION_CHAIN
 
struct  CREQ_REQUEST_DATA
 
struct  CREQ_RESPONSE_DATA
 
struct  CREQ_CTX
 

Macros

#define CREQ_ERROR_SUCCESS   0
 
#define CREQ_ERROR_MEMORY_ALLOCATION   1
 
#define CREQ_ERROR_CURL   2
 
#define CREQ_ERROR_SETTING_GET_PARAMS   3
 
#define CREQ_ERROR_PARAMS_TOO_LONG   4
 

Typedefs

typedef struct CREQ_GET_PARAMS CREQ_GET_PARAMS
 
typedef struct CREQ_HEADER CREQ_HEADER
 
typedef struct CREQ_REDIRECTION_CHAIN CREQ_REDIRECTION_CHAIN
 

Functions

char * creq_error (CREQ_CTX *)
 Returns the possible error message.
 
CREQ_CTXcreq_init (void)
 Initialize the creq library for a new request.
 
void creq_get (CREQ_CTX *ctx, char *url)
 Sends a GET request to the specified URL.
 
void creq_close (CREQ_CTX *ctx)
 Cleans up the library and memory after using it.
 
char * creq_get_content (CREQ_CTX *)
 Returns the content of the request.
 
void creq_set_allow_redirects (CREQ_CTX *, int)
 Tells the library if it should follow redirection.
 
void creq_set_useragent (CREQ_CTX *ctx, char *ua)
 Add user-agent to the request header.
 
void creq_add_param (CREQ_CTX *ctx, char *key, char *value)
 Sets a GET/POST param.
 
void creq_set_timeout (CREQ_CTX *ctx, long timesec)
 Sets timeout for both connection and data transfer.
 
void creq_add_header (CREQ_CTX *ctx, char *header)
 Adds a header to the header list for sending.
 
void creq_post (CREQ_CTX *ctx, char *url)
 Sends a post request.
 
void creq_head (CREQ_CTX *ctx, char *url)
 Sends a head request.
 
void creq_set_proxy (CREQ_CTX *ctx, char *proxy)
 Sets a proxy for sending requests.
 
void creq_set_verify (CREQ_CTX *ctx, int val)
 Enables/disables SSL/TLS verification.
 
char * creq_get_response_header (CREQ_CTX *ctx, char *header)
 Returns the value for a given header name.
 

Macro Definition Documentation

◆ CREQ_ERROR_CURL

#define CREQ_ERROR_CURL   2

The error is related to cURL library

◆ CREQ_ERROR_MEMORY_ALLOCATION

#define CREQ_ERROR_MEMORY_ALLOCATION   1

Can not allocate memory using malloc() or realloc()

◆ CREQ_ERROR_PARAMS_TOO_LONG

#define CREQ_ERROR_PARAMS_TOO_LONG   4

GET/POST parameter in a form of name=value is too long. it must be smaller than (8MB - len(url))

◆ CREQ_ERROR_SETTING_GET_PARAMS

#define CREQ_ERROR_SETTING_GET_PARAMS   3

Error happened in setting GET/POST parameter

◆ CREQ_ERROR_SUCCESS

#define CREQ_ERROR_SUCCESS   0

Success full operation

Function Documentation

◆ creq_add_header()

void creq_add_header ( CREQ_CTX ctx,
char *  header 
)

Adds a header to the header list for sending.

Parameters
ctxThe context returned by creq_init()
headerThe header you want to set in a form of "header-name: header-value"

This function sets a new header for the request. The header param will be copied by the library. So it's up to the user to free the allocated memory for the passed parameter.

This function has no return value.

int main(){
CREQ_CTX * ctx = creq_init();
if (!ctx){
fprintf(stdout, "Fail to init the library....\n");
return 1;
}
// Using stack for the new header. Will be copied to the internal structure.
creq_add_header(ctx, "Authorization: Bearer thisismytoken");
creq_get(ctx, "https://example.org");
creq_close(ctx);
return 0;
}
void creq_close(CREQ_CTX *ctx)
Cleans up the library and memory after using it.
Definition crequests.c:234
CREQ_CTX * creq_init(void)
Initialize the creq library for a new request.
Definition crequests.c:52
void creq_add_header(CREQ_CTX *ctx, char *header)
Adds a header to the header list for sending.
Definition crequests.c:111
void creq_get(CREQ_CTX *ctx, char *url)
Sends a GET request to the specified URL.
Definition crequests.c:651
Definition crequests.h:83

◆ creq_add_param()

void creq_add_param ( CREQ_CTX ctx,
char *  key,
char *  value 
)

Sets a GET/POST param.

Parameters
ctxContext returned by creq_init()
keyPointer to null-terminated string as the name of the parameter
valuePointer to the null-terminated string as the value of the parameter

Sets a parameter for GET/POST request. The parameter must be text. You CAN NOT use this method to set binary values. The function calculates the length of the key and value parameters using strlen() function. Binary data may have null characters which will result in wrong calculation of the length.

The key and value of each param are copied internally. So the caller must free() them (if it's necessary) after the call.

In case your parameter does not have a key (you want to send just a value), set the key to NULL.

'value' can never be NULL.

This function has no return value.

int main(){
CREQ_CTX * ctx = creq_init();
if (!ctx){
fprintf(stderr, "Can not init the library...\n");
return 1;
}
char url[] = "https://httpbin.org/get"
// this will be the same as: https://httpbin.org/get?name=John+Doe
creq_add_param(ctx, "name", "John Doe");
creq_set_timeout(ctx, 10);
creq_get(ctx, url);
fprintf(stderr, "Error(%d:%d): %s\n", ctx->err_code, ctx->curl_code, creq_error(ctx));
creq_close(ctx);
return 1;
}
// now that everything is good, we can print stuff
// print http status code
fprintf(stdout, "Status Code: %d\n", ctx->response->status_code);
// print my ip address
fprintf(stdout, "My IP address is: %s\n", creq_get_content(ctx));
creq_close(ctx);
return 0;
}
void creq_set_timeout(CREQ_CTX *ctx, long timesec)
Sets timeout for both connection and data transfer.
Definition crequests.c:337
void creq_add_param(CREQ_CTX *ctx, char *key, char *value)
Sets a GET/POST param.
Definition crequests.c:953
char * creq_error(CREQ_CTX *ctx)
Returns the possible error message.
Definition crequests.c:894
char * creq_get_content(CREQ_CTX *ctx)
Returns the content of the request.
Definition crequests.c:1024
#define CREQ_ERROR_SUCCESS
Definition crequests.h:8
CURLcode curl_code
possible curl error code
Definition crequests.h:88
CREQ_RESPONSE_DATA * response
response structure
Definition crequests.h:86
int err_code
Any possible error code (0 means success)
Definition crequests.h:84
long status_code
returned HTTP status code
Definition crequests.h:75

◆ creq_close()

void creq_close ( CREQ_CTX ctx)

Cleans up the library and memory after using it.

Parameters
ctxContext returned by creq_init()

Whenever you call creq_init(), you must call this method to clean up all the allocated memory and the internal structure for you.

◆ creq_error()

char * creq_error ( CREQ_CTX ctx)

Returns the possible error message.

Parameters
ctxContext returned by creq_init()

Users should not free the returned pointer by this function. The returned pointer is stack-based and should be consumed or copied after calling this function.

Returns
a pointer to the error message.

◆ creq_get()

void creq_get ( CREQ_CTX ctx,
char *  url 
)

Sends a GET request to the specified URL.

Parameters
ctxContext returned by creq_init()
urlA pointer to the URL

This function sends a GET request to the specified URL. The url param will be copied internally to the library so users can free the memory for url after use.

Returns
The function does not return any result. All the results will be stored in the context and cat be retrieved using ctx parameter.
// Send get request to get the IP address and print the status code
int main(){
CREQ_CTX * ctx = creq_init();
if (!ctx){
fprintf(stderr, "Can not init the library...\n");
return 1;
}
char url[] = "https://ipinfo.io/ip"
creq_set_timeout(ctx, 10);
creq_get(ctx, url);
fprintf(stderr, "Error(%d:%d): %s\n", ctx->err_code, ctx->curl_code, creq_error(ctx));
creq_close(ctx);
return 1;
}
// now that everything is good, we can print stuff
// print http status code
fprintf(stdout, "Status Code: %d\n", ctx->response->status_code);
// print my ip address
fprintf(stdout, "My IP address is: %s\n", creq_get_content(ctx));
creq_close(ctx);
return 0;
}

◆ creq_get_content()

char * creq_get_content ( CREQ_CTX ctx)

Returns the content of the request.

Parameters
ctxContext returned by creq_init()

This function returns a pointer to the place where the response body is stored.

You can use this method if you are sure the content does not have any null character in it (e.g., the content is some HTML data or like that).

If you know that the content is some binary data (e.g., a dowloaded binary file), Then you should use ctx->response->mem and ctx->response->len and then iterate over the content. Therefore, I wouldn't use this method unless I am 100% sure the result is text. Look at the example for more information.

int main(){
CREQ_CTX * ctx = creq_init();
if (!ctx){
fprintf(stderr, "Can not init the context\n");
return 1;
}
// let's download a binary file (Internet Download Manager :-D )
char url[] = "https://mirror2.internetdownloadmanager.com/idman641build11.exe?v=lt&filename=idman641build11.exe";
creq_get(ctx, url);
fprintf(stderr, "ERROR(%d:%d): %s\n", ctx->err_code, ctx->curl_code, creq_error(ctx));
return 2;
}
// store the result in a file called idm.exe
FILE * fp = fopen("idm.exe", "wb");
if (!fp){
fprintf(stderr, "Can not open a file to write.....\n");
return 3;
}
// we should not use creq_get_content() method as we have binary content
// instead, we use ctx->response->len and ctx->response->mem
for (unsigned int i=0; i<ctx->response->len; ++i){
fputc(ctx->response->mem[i], fp);
}
fclose(fp);
return 0;
}
size_t len
Length of the body of the request.
Definition crequests.h:78
char * mem
pointer to memory we keep the body of the request
Definition crequests.h:77
Returns
A pointer to the memory related to the content of the request

◆ creq_get_response_header()

char * creq_get_response_header ( CREQ_CTX ctx,
char *  key 
)

Returns the value for a given header name.

Parameters
ctxContext returned by creq_init()
keyA pointer to the null-terminated string specifying the header name.

HTTP headers are case-insensitive. So no matter what you send as a key to this function, it will use strcasecmp() function to compare it to the list of headers and returns the value if there is a match. Otherwise, it returns NULL.

Returns
A pointer to a null-terminated string as the value of a given header or NULL

◆ creq_head()

void creq_head ( CREQ_CTX ctx,
char *  url 
)

Sends a head request.

Parameters
ctxContext returned by creq_init()
urlA pointer to the URL to send HEAD request to.

This function sends a HEAD request to the given URL. It works exactly as creq_get() but there is no body in response just headers.

Look at the creq_get() doc for the example.

This function has no return value.

◆ creq_init()

CREQ_CTX * creq_init ( void  )

Initialize the creq library for a new request.

This must be the first function to call when you want to use this library. This function will initialize all the necessary structures and values.

You should always use a new context for each request. If you want to send 10 requests, call creq_init() 10 times to get 10 context and then close all of them by calling creq_close() for each context.

Returns
A pointer to CREQ_CTX structure on success or NULL on failure.
int main(){
// initialize the library
CREQ_CTX * ctx = creq_init();
if (!ctx){
fprintf(stdout, "Failed to init the library...\n");
return 1;
}
// continue doing stuff here
creq_close(ctx);
return 0;
}

◆ creq_post()

void creq_post ( CREQ_CTX ctx,
char *  url 
)

Sends a post request.

Parameters
ctxContext returned by creq_init()
urlA pointer to the URL

This function sends a post request to the given URL. The library copies the given url to its internal structure so users can free the url after using this function.

Post parameters are added using creq_add_param() method. Note that currently, this method does not support file upload. This means all the params must be text and not binary data.

The default encoding type of the data is application/x-www-form-urlencoded.

as long as the binary data is base64-encoded or any other human readable characters, it should be fine to send it with this method.

This function has no return value.

int main(){
CREQ_CTX * ctx = creq_init();
if (!ctx){
fprintf(stderr, "Can not init the library...\n");
return 1;
}
char url[] = "https://reqbin.com/echo/post/json"
creq_set_timeout(ctx, 10);
creq_post(ctx, url);
fprintf(stderr, "Error(%d:%d): %s\n", ctx->err_code, ctx->curl_code, creq_error(ctx));
creq_close(ctx);
return 1;
}
// now that everything is good, we can print stuff
// print http status code
fprintf(stdout, "Status Code: %d\n", ctx->response->status_code);
// print the output
fprintf(stdout, "%s\n", creq_get_content(ctx));
creq_close(ctx);
return 0;
}
void creq_post(CREQ_CTX *ctx, char *url)
Sends a post request.
Definition crequests.c:722

◆ creq_set_allow_redirects()

void creq_set_allow_redirects ( CREQ_CTX ctx,
int  val 
)

Tells the library if it should follow redirection.

Parameters
ctxContext returned by creq_init()
val0 to disable redirection and 1 to enable it (default).

By default, the library will follow redirection up to 10 times. You can pass 0 to this function to disable this behavior.

This function has no return value.

int main(){
CREQ_CTX *ctx = creq_init();
if (!ctx){
fprintf(stdout, "Fail to init the library....\n");
return 1;
}
// Let's not follow the redirection
creq_get(ctx, "http://example.com");
return 0;
}
void creq_set_allow_redirects(CREQ_CTX *ctx, int val)
Tells the library if it should follow redirection.
Definition crequests.c:275

◆ creq_set_proxy()

void creq_set_proxy ( CREQ_CTX ctx,
char *  proxy 
)

Sets a proxy for sending requests.

Parameters
ctxContext returned by creq_init()
proxyproxy string (as used in curl command line)

This function sets a proxy for the library.

Proxy is usually in a form of protocol://IP:PORT.

protocol can be http, https, socks5, socks5h and socks4.

For example: socks5h://127.0.0.1:1031

The proxy parameter will be coppied to the internal structure. So it's up the user to free the passed proxy param.

This function has no return value.

int main(){
CREQ_CTX *ctx = creq_init();
if (!ctx){
fprintf(stdout, "Fail to init the library....\n");
return 1;
}
// Let's force it to use socks5
creq_set_proxy(ctx, "socks5://1.2.3.4:1080");
creq_get(ctx, "http://example.com");
return 0;
}
void creq_set_proxy(CREQ_CTX *ctx, char *proxy)
Sets a proxy for sending requests.
Definition crequests.c:151

◆ creq_set_timeout()

void creq_set_timeout ( CREQ_CTX ctx,
long  timesec 
)

Sets timeout for both connection and data transfer.

Parameters
ctxContext returned by creq_init()
timesecMaximum number of second to wait for connection and receiving data

It's always a good practice to set a timeout for each request. This function sets the timeout to timesec seconds. For example, setting the timeout to 10 means that the request has at most 10 seconds to connect to the server and transfer the data. If it takes more than that, the library will return timeout error.

This function has no return value.

◆ creq_set_useragent()

void creq_set_useragent ( CREQ_CTX ctx,
char *  ua 
)

Add user-agent to the request header.

Using this function, you can set your user-agent as a header in the request. You can also use creq_add_header() function to do the same thing. I created a separate function for it since it is used a lot of time.

The library copy the user-agent string internally. So the user should free the ua parameter after use.

Parameters
ctxContext returned by creq_init()
uaA pointer to the new user-agent.

◆ creq_set_verify()

void creq_set_verify ( CREQ_CTX ctx,
int  val 
)

Enables/disables SSL/TLS verification.

Parameters
ctxContext returned by creq_init()
valeither zero (disable verification) or one (enable verification).

By default, the SSL verification is enabled internally by curl library. It's not safe to disable it but if you know what you are doing, you can disable SSL verification by passing zero to this function.

This function has no return value.