Skip to content

Instantly share code, notes, and snippets.

@gkhighelf
Forked from utaal/Makefile
Created July 19, 2016 09:46
Show Gist options
  • Save gkhighelf/8fe74e0964d243de711b4f6f87139c89 to your computer and use it in GitHub Desktop.
Save gkhighelf/8fe74e0964d243de711b4f6f87139c89 to your computer and use it in GitHub Desktop.

Revisions

  1. Andrea Lattuada revised this gist Sep 23, 2011. 1 changed file with 10 additions and 1 deletion.
    11 changes: 10 additions & 1 deletion README
    Original file line number Diff line number Diff line change
    @@ -18,4 +18,13 @@ Stress-test it

    ab -n 5000 -c 500 http://127.0.0.1:8000/

    - Andrea ( https://github.com/utaal - [email protected] )
    Call for coders!
    I have this insane idea of writing a lightweight c++ web framework on top of
    libuv. But. I can't do it by myself.
    Anyone crazy enough to join me? Drop me a tweet / email.

    - Andrea
    https://twitter.com/utaal
    https://github.com/utaal
    [email protected]

  2. Andrea Lattuada revised this gist Sep 23, 2011. 3 changed files with 30 additions and 10 deletions.
    11 changes: 9 additions & 2 deletions Makefile
    Original file line number Diff line number Diff line change
    @@ -1,9 +1,16 @@
    webserver: webserver.c libuv/uv.a http-parser/http_parser.o
    gcc -lrt -lm -lpthread -o webserver webserver.c \
    libuv/uv.a http-parser/http_parser.o
    gcc -I libuv/include \
    -lrt -lm -lpthread -o \
    webserver webserver.c \
    libuv/uv.a http-parser/http_parser.o

    libuv/uv.a:
    $(MAKE) -C libuv

    http-parser/http_parser.o:
    $(MAKE) -C http-parser http_parser.o

    clean:
    rm libuv/uv.a
    rm http-parser/http_parser.o
    rm webserver
    11 changes: 10 additions & 1 deletion README
    Original file line number Diff line number Diff line change
    @@ -3,10 +3,19 @@ http-parser (https://github.com/ry/http-parser) based on Ryan Dahl's tutorial
    http://vimeo.com/24713213 and updated to make it work with the most recent
    libuv API.

    How to build
    Build it

    git clone https://github.com/ry/http-parser.git
    git clone https://github.com/joyent/libuv
    make

    Run it

    ./webserver
    curl http://127.0.0.1:8000/

    Stress-test it

    ab -n 5000 -c 500 http://127.0.0.1:8000/

    - Andrea ( https://github.com/utaal - [email protected] )
    18 changes: 11 additions & 7 deletions webserver.c
    Original file line number Diff line number Diff line change
    @@ -12,6 +12,7 @@
    }
    #define UVERR(err, msg) fprintf(stderr, "%s: %s\n", msg, uv_strerror(err))
    #define LOG(msg) puts(msg);
    #define LOGF(fmt, params...) printf(fmt "\n", params);
    #define LOG_ERROR(msg) puts(msg);

    #define RESPONSE \
    @@ -31,12 +32,14 @@ typedef struct {
    uv_tcp_t handle;
    http_parser parser;
    uv_write_t write_req;
    int request_num;
    } client_t;

    void on_close(uv_handle_t* handle) {
    LOG("connection closed");

    client_t* client = (client_t*) handle->data;

    LOGF("[ %5d ] connection closed", client->request_num);

    free(client);
    }

    @@ -69,15 +72,19 @@ void on_read(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
    free(buf.base);
    }

    static int request_num = 1;

    void on_connect(uv_stream_t* server_handle, int status) {
    CHECK(status, "connect");

    int r;

    assert((uv_tcp_t*)server_handle == &server);
    LOG("new connection");

    client_t* client = malloc(sizeof(client_t));
    client->request_num = request_num;

    LOGF("[ %5d ] new connection", request_num++);

    uv_tcp_init(uv_loop, &client->handle);
    http_parser_init(&client->parser, HTTP_REQUEST);
    @@ -100,7 +107,7 @@ void after_write(uv_write_t* req, int status) {
    int on_headers_complete(http_parser* parser) {
    client_t* client = (client_t*) parser->data;

    LOG("http message!");
    LOGF("[ %5d ] http message parsed", client->request_num);

    uv_write(
    &client->write_req,
    @@ -120,9 +127,6 @@ int main() {
    resbuf.base = RESPONSE;
    resbuf.len = sizeof(RESPONSE);

    LOG("init");
    uv_init();

    uv_loop = uv_default_loop();

    r = uv_tcp_init(uv_loop, &server);
  3. Andrea Lattuada revised this gist Sep 9, 2011. 1 changed file with 4 additions and 1 deletion.
    5 changes: 4 additions & 1 deletion README
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,7 @@
    An hello-world webserver in C using libuv (https://github.com/joyent/libuv) and http-parser (https://github.com/ry/http-parser) based on Ryan Dahl's tutorial http://vimeo.com/24713213 and updated to make it work with the most recent libuv API.
    An hello-world webserver in C using libuv (https://github.com/joyent/libuv) and
    http-parser (https://github.com/ry/http-parser) based on Ryan Dahl's tutorial
    http://vimeo.com/24713213 and updated to make it work with the most recent
    libuv API.

    How to build

  4. Andrea Lattuada revised this gist Sep 9, 2011. 1 changed file with 9 additions and 0 deletions.
    9 changes: 9 additions & 0 deletions README
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,9 @@
    An hello-world webserver in C using libuv (https://github.com/joyent/libuv) and http-parser (https://github.com/ry/http-parser) based on Ryan Dahl's tutorial http://vimeo.com/24713213 and updated to make it work with the most recent libuv API.

    How to build

    git clone https://github.com/ry/http-parser.git
    git clone https://github.com/joyent/libuv
    make

    - Andrea ( https://github.com/utaal - [email protected] )
  5. Andrea Lattuada revised this gist Sep 9, 2011. 1 changed file with 40 additions and 33 deletions.
    73 changes: 40 additions & 33 deletions webserver.c
    Original file line number Diff line number Diff line change
    @@ -1,30 +1,27 @@
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    #include "libuv/uv.h"
    #include "libuv/include/uv.h"
    #include "http-parser/http_parser.h"

    #define CHECK(r, msg) check_result(r, msg)
    #define CHECK(r, msg) \
    if (r) { \
    uv_err_t err = uv_last_error(uv_loop); \
    fprintf(stderr, "%s: %s\n", msg, uv_strerror(err)); \
    exit(1); \
    }
    #define UVERR(err, msg) fprintf(stderr, "%s: %s\n", msg, uv_strerror(err))
    // #define LOG(msg) puts(msg);
    #define LOG(msg)
    #define LOG(msg) puts(msg);
    #define LOG_ERROR(msg) puts(msg);

    void check_result(int r, char* msg) {
    if (r) {
    uv_err_t err = uv_last_error();
    fprintf(stderr, "%s: %s\n", msg, uv_strerror(err));
    exit(1);
    }
    }

    #define RESPONSE \
    "HTTP/1.1 200 OK\r\n" \
    "Content-Type: text/plain\r\n" \
    "Content-Length: 12\r\n" \
    "\r\n" \
    "hello world\n"

    static uv_loop_t* uv_loop;
    static uv_tcp_t server;
    static http_parser_settings parser_settings;

    @@ -33,21 +30,24 @@ static uv_buf_t resbuf;
    typedef struct {
    uv_tcp_t handle;
    http_parser parser;
    uv_req_t write_req;
    uv_write_t write_req;
    } client_t;

    void on_close(uv_handle_t* handle) {
    LOG("connection closed");

    client_t* client = (client_t*) handle->data;
    free(client);
    }

    uv_buf_t on_alloc(uv_tcp_t* client, size_t suggested_size) {
    uv_buf_t on_alloc(uv_handle_t* client, size_t suggested_size) {
    uv_buf_t buf;
    buf.base = malloc(suggested_size);
    buf.len = suggested_size;
    return buf;
    }

    void on_read(uv_tcp_t* tcp, ssize_t nread, uv_buf_t buf) {
    void on_read(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
    size_t parsed;

    client_t* client = (client_t*) tcp->data;
    @@ -60,49 +60,54 @@ void on_read(uv_tcp_t* tcp, ssize_t nread, uv_buf_t buf) {
    uv_close((uv_handle_t*) &client->handle, on_close);
    }
    } else {
    uv_err_t err = uv_last_error();
    if (err.code == UV_EOF) {
    uv_close((uv_handle_t*) tcp, on_close);
    } else {
    uv_err_t err = uv_last_error(uv_loop);
    if (err.code != UV_EOF) {
    UVERR(err, "read");
    }
    }

    free(buf.base);
    }

    void on_connect(uv_tcp_t* server_handle, int status) {
    void on_connect(uv_stream_t* server_handle, int status) {
    CHECK(status, "connect");

    int r;

    assert(server_handle == &server);
    assert((uv_tcp_t*)server_handle == &server);
    LOG("new connection");

    client_t* client = malloc(sizeof(client_t));

    uv_tcp_init(&client->handle);
    uv_tcp_init(uv_loop, &client->handle);
    http_parser_init(&client->parser, HTTP_REQUEST);

    client->parser.data = client;
    client->handle.data = client;

    r = uv_accept(server_handle, &client->handle);
    r = uv_accept(server_handle, (uv_stream_t*)&client->handle);
    CHECK(r, "accept");

    uv_read_start(&client->handle, on_alloc, on_read);
    uv_read_start((uv_stream_t*)&client->handle, on_alloc, on_read);
    }

    void after_write(uv_req_t* req, int status) {
    uv_close(req->handle, on_close);
    void after_write(uv_write_t* req, int status) {
    CHECK(status, "write");

    uv_close((uv_handle_t*)req->handle, on_close);
    }

    int on_headers_complete(http_parser* parser) {
    client_t* client = (client_t*) parser->data;

    LOG("http message!");

    uv_req_init(
    &client->write_req, (uv_handle_t*) &client->handle, after_write);
    uv_write(&client->write_req, &resbuf, 1);
    uv_write(
    &client->write_req,
    (uv_stream_t*)&client->handle,
    &resbuf,
    1,
    after_write);

    return 1;
    }
    @@ -118,16 +123,18 @@ int main() {
    LOG("init");
    uv_init();

    r = uv_tcp_init(&server);
    uv_loop = uv_default_loop();

    r = uv_tcp_init(uv_loop, &server);
    CHECK(r, "bind");

    struct sockaddr_in address = uv_ip4_addr("0.0.0.0", 8000);

    r = uv_bind(&server, address);
    r = uv_tcp_bind(&server, address);
    CHECK(r, "bind");
    uv_listen(&server, 128, on_connect);
    uv_listen((uv_stream_t*)&server, 128, on_connect);

    LOG("listening on port 8000");

    uv_run();
    uv_run(uv_loop);
    }
  6. Andrea Lattuada revised this gist Sep 9, 2011. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion Makefile
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    webserver: webserver.c libuv/uv.a http-parser/http_parser.o
    gcc -lm -o webserver webserver.c \
    gcc -lrt -lm -lpthread -o webserver webserver.c \
    libuv/uv.a http-parser/http_parser.o

    libuv/uv.a:
  7. Andrea Lattuada revised this gist Sep 9, 2011. 1 changed file with 9 additions and 0 deletions.
    9 changes: 9 additions & 0 deletions Makefile
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,9 @@
    webserver: webserver.c libuv/uv.a http-parser/http_parser.o
    gcc -lm -o webserver webserver.c \
    libuv/uv.a http-parser/http_parser.o

    libuv/uv.a:
    $(MAKE) -C libuv

    http-parser/http_parser.o:
    $(MAKE) -C http-parser http_parser.o
  8. Andrea Lattuada renamed this gist Sep 9, 2011. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  9. @utaal utaal created this gist Sep 5, 2011.
    133 changes: 133 additions & 0 deletions gistfile1.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,133 @@
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    #include "libuv/uv.h"
    #include "http-parser/http_parser.h"

    #define CHECK(r, msg) check_result(r, msg)
    #define UVERR(err, msg) fprintf(stderr, "%s: %s\n", msg, uv_strerror(err))
    // #define LOG(msg) puts(msg);
    #define LOG(msg)
    #define LOG_ERROR(msg) puts(msg);

    void check_result(int r, char* msg) {
    if (r) {
    uv_err_t err = uv_last_error();
    fprintf(stderr, "%s: %s\n", msg, uv_strerror(err));
    exit(1);
    }
    }

    #define RESPONSE \
    "HTTP/1.1 200 OK\r\n" \
    "Content-Type: text/plain\r\n" \
    "Content-Length: 12\r\n" \
    "\r\n" \
    "hello world\n"

    static uv_tcp_t server;
    static http_parser_settings parser_settings;

    static uv_buf_t resbuf;

    typedef struct {
    uv_tcp_t handle;
    http_parser parser;
    uv_req_t write_req;
    } client_t;

    void on_close(uv_handle_t* handle) {
    LOG("connection closed");
    }

    uv_buf_t on_alloc(uv_tcp_t* client, size_t suggested_size) {
    uv_buf_t buf;
    buf.base = malloc(suggested_size);
    buf.len = suggested_size;
    return buf;
    }

    void on_read(uv_tcp_t* tcp, ssize_t nread, uv_buf_t buf) {
    size_t parsed;

    client_t* client = (client_t*) tcp->data;

    if (nread >= 0) {
    parsed = http_parser_execute(
    &client->parser, &parser_settings, buf.base, nread);
    if (parsed < nread) {
    LOG_ERROR("parse error");
    uv_close((uv_handle_t*) &client->handle, on_close);
    }
    } else {
    uv_err_t err = uv_last_error();
    if (err.code == UV_EOF) {
    uv_close((uv_handle_t*) tcp, on_close);
    } else {
    UVERR(err, "read");
    }
    }

    free(buf.base);
    }

    void on_connect(uv_tcp_t* server_handle, int status) {
    int r;

    assert(server_handle == &server);
    LOG("new connection");

    client_t* client = malloc(sizeof(client_t));

    uv_tcp_init(&client->handle);
    http_parser_init(&client->parser, HTTP_REQUEST);

    client->parser.data = client;
    client->handle.data = client;

    r = uv_accept(server_handle, &client->handle);
    CHECK(r, "accept");

    uv_read_start(&client->handle, on_alloc, on_read);
    }

    void after_write(uv_req_t* req, int status) {
    uv_close(req->handle, on_close);
    }

    int on_headers_complete(http_parser* parser) {
    client_t* client = (client_t*) parser->data;

    LOG("http message!");

    uv_req_init(
    &client->write_req, (uv_handle_t*) &client->handle, after_write);
    uv_write(&client->write_req, &resbuf, 1);

    return 1;
    }

    int main() {
    int r;

    parser_settings.on_headers_complete = on_headers_complete;

    resbuf.base = RESPONSE;
    resbuf.len = sizeof(RESPONSE);

    LOG("init");
    uv_init();

    r = uv_tcp_init(&server);
    CHECK(r, "bind");

    struct sockaddr_in address = uv_ip4_addr("0.0.0.0", 8000);

    r = uv_bind(&server, address);
    CHECK(r, "bind");
    uv_listen(&server, 128, on_connect);

    LOG("listening on port 8000");

    uv_run();
    }