User Tools

Site Tools


Libuv web server sample

uv-srv.c
/*
 * Copyright 2004-2019 Oleg Borodin  <borodin@unix7.org>
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <uv.h>
 
uv_loop_t *loop;
struct sockaddr_in addr;
 
void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
    buf->base = (char*) malloc(suggested_size);
    buf->len = suggested_size;
}
 
void on_close(uv_handle_t* handle) {
    free(handle);
}
 
void on_write(uv_write_t *req, int status) {
    if (status) {
        fprintf(stderr, "# write error %s\n", uv_strerror(status));
    }
    free(req);
}
 
void on_read(uv_stream_t *cstream, ssize_t nread, const uv_buf_t *rbuf) {
 
    if (nread > 0) {
        printf("%d\n\n", (int)nread);
        uv_write_t *req = malloc(sizeof(uv_write_t));
        char res[] =
            "HTTP/1.1 200 OK\r\n"
            "Accept-Ranges: bytes\r\n"
            "Content-Type: text/plain\r\n"
            "Content-Length: 0\r\n"
            "Server: Srv11/0.1\r\n"
            "Date: Wed, 15 May 2019 14:05:07 UTC\r\n";
        uv_buf_t wbuf = uv_buf_init(res, strlen(res));
 
        uv_write(req, cstream, &wbuf, 1, on_write);
    }
    if (nread < 0) {
        if (nread != UV_EOF) {
            fprintf(stderr, "# read error %s\n", uv_err_name(nread));
        }
    }
    uv_close((uv_handle_t*) cstream, on_close);
    free(rbuf->base);
}
 
void on_connection(uv_stream_t *server, int status) {
    if (status < 0) {
        fprintf(stderr, "# new connection error %s\n", uv_strerror(status));
        return;
    }
 
    uv_tcp_t *tcp_client = (uv_tcp_t*) malloc(sizeof(uv_tcp_t));
    uv_tcp_init(loop, tcp_client);
 
    if (uv_accept(server, (uv_stream_t*) tcp_client) == 0) {
        uv_read_start((uv_stream_t*) tcp_client, alloc_buffer, on_read);
    }
    else {
        uv_close((uv_handle_t*) tcp_client, on_close);
    }
}
 
 
int main(int argc, char **argv) {
 
    loop = uv_default_loop();
 
    uv_tcp_t server;
    uv_tcp_init(loop, &server);
 
    uv_ip4_addr("0.0.0.0", 1024, &addr);
    uv_tcp_bind(&server, (const struct sockaddr*)&addr, 0);
 
    int r = uv_listen((uv_stream_t*) &server, 1024, on_connection);
    if (r) {
        fprintf(stderr, "# listen error %s\n", uv_strerror(r));
        return 1;
    }
    return uv_run(loop, UV_RUN_DEFAULT);
}

First PagePrevious PageBack to overviewNext PageLast Page