Mock HTTP server example using Nilorea network module.
#include <getopt.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#define MOCK_PORT 19090
(void)user_data;
if (strcmp(req->
method,
"GET") == 0 &&
strcmp(req->
path,
"/api/test") == 0) {
} else {
}
}
(void)arg;
return NULL;
}
int main(
int argc,
char* argv[]) {
while ((
getoptret = getopt(argc, argv,
"V:h")) != -1) {
case 'V':
if (strcmp(optarg, "LOG_DEBUG") == 0)
else if (strcmp(optarg, "LOG_INFO") == 0)
else if (strcmp(optarg, "LOG_NOTICE") == 0)
else if (strcmp(optarg, "LOG_ERR") == 0)
break;
case 'h':
default:
fprintf(stderr, "Usage: %s [-V LOG_LEVEL]\n", argv[0]);
return 1;
}
}
fprintf(stderr, "FAIL: could not start mock server\n");
return 1;
}
printf("CHECK start server ... PASS\n");
pthread_t thr;
fprintf(stderr, "FAIL: could not create server thread\n");
return 1;
}
usleep(100000);
int sock_fd = -1;
{
struct addrinfo hints;
struct addrinfo* res = NULL;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(
"127.0.0.1",
port_str, &hints, &res) != 0 || !res) {
fprintf(stderr, "FAIL: getaddrinfo\n");
pthread_join(thr, NULL);
return 1;
}
sock_fd = (int)socket(res->ai_family, res->ai_socktype,
res->ai_protocol);
if (sock_fd < 0 ||
connect(sock_fd, res->ai_addr, res->ai_addrlen) != 0) {
fprintf(stderr, "FAIL: connect\n");
freeaddrinfo(res);
pthread_join(thr, NULL);
return 1;
}
freeaddrinfo(res);
}
const char* http_req =
"GET /api/test HTTP/1.1\r\n"
"Host: localhost\r\n"
"Connection: close\r\n"
"\r\n";
ssize_t sent = send(sock_fd, http_req, strlen(http_req), 0);
if (sent <= 0) {
fprintf(stderr, "FAIL: send\n");
close(sock_fd);
pthread_join(thr, NULL);
return 1;
}
char resp_buf[4096];
memset(resp_buf, 0, sizeof(resp_buf));
ssize_t total = 0;
ssize_t nr = 0;
while ((nr = recv(sock_fd, resp_buf + total,
sizeof(resp_buf) - 1 - (size_t)total, 0)) > 0) {
total += nr;
}
close(sock_fd);
printf("Response:\n%s\n", resp_buf);
int pass = 1;
if (strstr(resp_buf, "200") == NULL) {
fprintf(stderr, "FAIL: expected 200 in response\n");
pass = 0;
}
if (strstr(resp_buf, "{\"status\":\"ok\"}") == NULL) {
fprintf(stderr, "FAIL: expected JSON body in response\n");
pass = 0;
}
printf("CHECK GET /api/test ... %s\n", pass ? "PASS" : "FAIL");
pthread_join(thr, NULL);
printf("CHECK cleanup ... PASS\n");
return pass ? 0 : 1;
}
static void * server_thread(void *arg)
Thread function that runs the server accept loop.
#define MOCK_PORT
mock server port
static void on_request(N_HTTP_REQUEST *req, N_HTTP_RESPONSE *resp, void *user_data)
Request handler: returns JSON for GET /api/test, 404 otherwise.
static N_MOCK_SERVER * g_server
global server pointer for thread
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_DEBUG
debug-level messages
#define LOG_ERR
error conditions
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL )
#define LOG_NOTICE
normal but significant condition
#define LOG_INFO
informational
N_STR * char_to_nstr(const char *src)
Convert a char into a N_STR, short version.
N_STR * body
response body
char path[2048]
request path
char method[16]
HTTP method.
int status_code
HTTP status code.
char content_type[128]
Content-Type header value.
void n_mock_server_free(N_MOCK_SERVER **server)
Free a mock server and close the listening socket.
void n_mock_server_stop(N_MOCK_SERVER *server)
Signal the mock server to stop accepting connections.
void n_mock_server_run(N_MOCK_SERVER *server)
Run the mock server accept loop.
N_MOCK_SERVER * n_mock_server_start(int port, void(*on_request)(N_HTTP_REQUEST *, N_HTTP_RESPONSE *, void *), void *user_data)
Start a mock HTTP server: set up listener and return immediately.
parsed HTTP request for mock server callback
HTTP response to send from mock server callback.
Common headers and low-level functions & define.
N_STR and string function declaration.