/* * Author, Copyright: Oleg Borodin <onborodin@gmail.com> */ #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); }