Skip to content

Instantly share code, notes, and snippets.

@adityapurwa
Last active July 11, 2019 05:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adityapurwa/f0d885d28014d564f997e3bbb50f29aa to your computer and use it in GitHub Desktop.
Save adityapurwa/f0d885d28014d564f997e3bbb50f29aa to your computer and use it in GitHub Desktop.
Libuv HTTP Client Example
#include <stdio.h>
#include <stdlib.h>
#include <uv.h>
#include <assert.h>
void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
// Di sini kita membantu uv untuk mengalokasikan buffer sesuai yang kita inginkan
buf->base = malloc(suggested_size);
buf->len = suggested_size;
}
void on_response(uv_stream_t *stream,
ssize_t nread,
const uv_buf_t *buf) {
// Isi dari response dibungkus oleh uv_buf_t dan bisa dilihat isinya di uv_buf_t.base
printf("%s", buf->base);
}
void on_header_sent(uv_write_t *write, int status) {
// Setelah request header selesai dikirim, kita bisa mulai membaca response dari numbersapi.com
uv_read_start((uv_stream_t *) write->handle, alloc_buffer, on_response);
}
void on_connect(uv_connect_t *req, int status) {
// Kita construct secara manual HTTP header untuk request ke numbersapi.com
char *httpRequestHeader = malloc(sizeof(char *));
sprintf(httpRequestHeader, "GET /%d HTTP/1.1\n"
"Host: numbersapi.com\n"
"Connection: keep-alive\n"
"Cache-Control: max-age=0\n"
"Upgrade-Insecure-Requests: 1\n"
"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36\n"
"DNT: 1\n"
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\n"
"Accept-Encoding: gzip, deflate\n"
"Accept-Language: en-US,en;q=0.9\n\n", arc4random() % 100);
// Proses read dan write di uv dibungkus di dalam uv_buf_t
uv_buf_t httpReqBuffer = uv_buf_init(httpRequestHeader, strlen(httpRequestHeader));
uv_write_t write;
uv_write(&write, req->handle, &httpReqBuffer, 1, on_header_sent);
}
int main() {
// Kita akan menggunakan event loop default dari uv, event loop ini juga yang digunakan di NodeJS
uv_loop_t *loop = uv_default_loop();
// IP untuk numbersapi.com
struct sockaddr_in addr;
uv_ip4_addr("107.170.248.47", 80, &addr);
uv_connect_t req;
uv_tcp_t tcp;
// Tipe-tipe handle di uv harus di init berdasarkan loopnya
uv_tcp_init(loop, &tcp);
// Perhatikan bahwa di sini kita sudah mulai memanfaatkan keasinkronusan dari uv
// on_connect adalah sebuah callback seperti di Node
uv_tcp_connect(&req, &tcp, (const struct sockaddr *) &addr, on_connect);
// Jalankan event loop default,
uv_run(loop, UV_RUN_DEFAULT);
// Baris di bawah uv_run tidak akan berjalan sampai event loop selesai
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment