- Simple API for making HTTP requests
- Support for GET and POST requests
- JSON sending and receiving capabilities
- Built-in JSON parsing and creation
- No external library dependencies - uses only standard C libraries and POSIX APIs
- Socket-based communication
- Configurable timeouts
- Detailed error reporting
- C compiler (gcc, clang, etc.)
- POSIX-compatible operating system (Linux, macOS, *BSD, etc.)
- CMake 3.10 or higher
For quick installation on Linux systems:
./install.shmkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make
sudo make install
sudo ldconfigAfter installation, you can use Conduit in your CMake project:
find_package(conduit REQUIRED)
add_executable(your_app your_app.c)
target_link_libraries(your_app PRIVATE Conduit::conduit)For non-CMake projects, you can use pkg-config:
gcc -o your_app your_app.c $(pkg-config --cflags --libs conduit)conduit/
├── include/ # Public header files
│ ├── conduit.h # Main library interface
│ ├── failures.h # Error handling definitions
│ ├── http_client.h # HTTP client implementation
│ └── json_parser.h # JSON parsing utilities
├── src/ # Implementation files
│ ├── conduit.c
│ ├── failures.c
│ ├── http_client.c
│ └── json_parser.c
├── examples/ # Example applications
│ ├── simple_get.c
│ └── simple_post.c
├── cmake/ # CMake configuration files
│ └── conduit-config.cmake.in
├── conduit.pc.in # pkg-config template
└── install.sh # Installation script
mkdir build
cd build
cmake ..
makemkdir build
cd build
cmake ..
makesequenceDiagram
participant App as Application
participant Conduit as Conduit Library
participant Server as Web Server
%% GET Request Flow
App->>Conduit: conduit_connect(hostname, port)
Conduit->>Server: TCP Connection
Server-->>Conduit: Connection Established
Conduit-->>App: socket descriptor
App->>Conduit: conduit_send_request(sockfd, hostname, path)
Conduit->>Server: HTTP GET Request
App->>Conduit: conduit_receive_response(sockfd)
Server-->>Conduit: HTTP Response
Conduit-->>App: ConduitResponse structure
%% POST Request Flow
App->>Conduit: conduit_post_json(sockfd, hostname, path, json_body)
Conduit->>Server: HTTP POST Request with JSON
App->>Conduit: conduit_receive_response(sockfd)
Server-->>Conduit: HTTP Response
Conduit-->>App: ConduitResponse structure
App->>Conduit: conduit_free_response(response)
#include <stdio.h>
#include <conduit.h>
int main() {
// Connect to a server
int sockfd = conduit_connect("jsonplaceholder.typicode.com", 80);
if (sockfd < 0) {
fprintf(stderr, "Connection failed\n");
return 1;
}
// Send a GET request
if (conduit_send_request(sockfd, "jsonplaceholder.typicode.com", "/todos/1") < 0) {
fprintf(stderr, "Failed to send request\n");
return 1;
}
// Receive the response
ConduitResponse* response = conduit_receive_response(sockfd);
if (!response) {
fprintf(stderr, "Failed to receive response\n");
return 1;
}
// Process the response data
printf("Status code: %d\n", response->status_code);
// Parse and use JSON data if available
if (response->json && response->json->type == JSON_OBJECT) {
JsonObject* obj = response->json->value.object;
int userId = json_get_int(obj, "userId");
int id = json_get_int(obj, "id");
const char* title = json_get_string(obj, "title");
int completed = json_get_bool(obj, "completed");
printf("User ID: %d\n", userId);
printf("ID: %d\n", id);
printf("Title: %s\n", title);
printf("Completed: %s\n", completed ? "true" : "false");
}
// Free the response resources
conduit_free_response(response);
return 0;
}#include <stdio.h>
#include <conduit.h>
int main() {
// Connect to a server
int sockfd = conduit_connect("jsonplaceholder.typicode.com", 80);
if (sockfd < 0) {
fprintf(stderr, "Connection failed\n");
return 1;
}
// Prepare JSON data to send
const char* json_body = "{\"title\":\"foo\",\"body\":\"bar\",\"userId\":1}";
// Send a POST request with JSON data
if (conduit_post_json(sockfd, "jsonplaceholder.typicode.com", "/posts", json_body) < 0) {
fprintf(stderr, "Failed to send POST request\n");
return 1;
}
// Receive the response
ConduitResponse* response = conduit_receive_response(sockfd);
if (!response) {
fprintf(stderr, "Failed to receive response\n");
return 1;
}
// Process the response data
printf("Status code: %d\n", response->status_code);
printf("Response body: %s\n", response->body);
// Free the response resources
conduit_free_response(response);
return 0;
}int conduit_connect(const char* hostname, int port);Establishes a connection to the specified server.
Parameters:
hostname: The server hostname or IP addressport: The port number
Returns:
- A socket file descriptor if successful
- A negative error code if an error occurs
int conduit_send_request(int sockfd, const char* hostname, const char* path);Sends an HTTP GET request to the server.
Parameters:
sockfd: The socket file descriptor fromconduit_connecthostname: The hostname for the Host headerpath: The path for the request URL
Returns:
- 0 if successful
- A negative error code if an error occurs
int conduit_post_json(int sockfd, const char* hostname, const char* path, const char* json_body);Sends an HTTP POST request with a JSON body to the server.
Parameters:
sockfd: The socket file descriptor fromconduit_connecthostname: The hostname for the Host headerpath: The path for the request URLjson_body: The JSON data to send as a string
Returns:
- 0 if successful
- A negative error code if an error occurs
ConduitResponse* conduit_receive_response(int sockfd);Receives and processes the HTTP response.
Parameters:
sockfd: The socket file descriptor fromconduit_connect
Returns:
- A pointer to a
ConduitResponsestructure if successful - NULL if an error occurs
void conduit_free_response(ConduitResponse* response);Frees all memory allocated for a response.
Parameters:
response: The response structure to free
int json_get_int(JsonObject* obj, const char* key);
const char* json_get_string(JsonObject* obj, const char* key);
int json_get_bool(JsonObject* obj, const char* key);
JsonValue* conduit_parse_json(const char* json_string);Extract values from a parsed JSON object or parse a JSON string.
Parameters:
obj: The JSON object to extract fromkey: The key to look upjson_string: The JSON string to parse
Returns:
- The requested value if found
- Default value (0, NULL, or false) if not found or wrong type
- Parsed JSON value pointer for
conduit_parse_json
JsonValue* json_create_null();
JsonValue* json_create_boolean(int boolean_value);
JsonValue* json_create_number(double number_value);
JsonValue* json_create_string(const char* string_value);
JsonValue* json_create_object();Create JSON values for building JSON data structures.
Returns:
- A pointer to a new JsonValue structure of the specified type
typedef struct {
int status_code; // HTTP status code
char* body; // Response body as string
char* headers; // Response headers
char* content_type; // Content-Type header value
JsonValue* json; // Parsed JSON (if response is JSON)
} ConduitResponse;The library provides detailed error reporting via error codes and messages:
typedef enum {
ERR_HOSTNAME_RESOLUTION,
ERR_SOCKET_CREATION,
ERR_SEVER_CONNECTION,
ERR_SEND_HTTP_REQ,
ERR_BUFF_OVERFLOW,
ERR_RECEIVING_DATA
} ErrorCode;
const char* get_error_message(ErrorCode code);This project is licensed under the MIT License - see the LICENSE file for details.
