libumumble/src/connection.c

121 lines
2.7 KiB
C

#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <umumble/umumble.h>
#include <tlsuv/tlsuv.h>
#include <uv.h>
void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
buf->base = malloc(suggested_size);
assert(buf->base != NULL);
if (buf->base == NULL) {
buf->len = 0;
return;
}
buf->len = suggested_size;
}
void on_close_cb(uv_handle_t *handle)
{
tlsuv_stream_free((tlsuv_stream_t *) handle);
}
void on_write_cb(uv_write_t *req, int status)
{
if (status < 0) {
tlsuv_stream_close((tlsuv_stream_t *) req->handle, on_close_cb);
}
free(req);
}
void on_read_cb(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf)
{
mumble_ctx_t *ctx = client->data;
if (nread < 0) {
if (nread != UV_EOF) {
ctx->error = nread;
ctx->status = MUMBLE_STATUS_DISCONNECTED;
}
tlsuv_stream_close((tlsuv_stream_t *) client, on_close_cb);
ctx->status = MUMBLE_STATUS_DISCONNECTED;
free(buf->base);
free(client);
return;
}
char *data = (char*) malloc(sizeof(char) * (nread+1));
data[nread] = '\0';
strncpy(data, buf->base, nread);
printf("%s", data);
free(data);
free(buf->base);
}
void on_connect_cb(uv_connect_t *req, int status)
{
mumble_ctx_t *ctx = req->data;
tlsuv_stream_t *tls_stream = (tlsuv_stream_t *) req->handle;
if (status < 0) {
ctx->error = status;
ctx->status = MUMBLE_STATUS_DISCONNECTED;
tlsuv_stream_close((tlsuv_stream_t *) req->handle, on_close_cb);
return;
}
ctx->status = MUMBLE_STATUS_CONNECTED;
tlsuv_stream_read(tls_stream, alloc_buffer, on_read_cb);
uv_write_t *wr = malloc(sizeof(uv_write_t));
char write_req[] = "GET / HTTP/1.1\r\n"
"Accept: */*\r\n"
"Connection: close\r\n"
"Host: www.wttr.in\r\n"
"User-Agent: curl/0.5.0\r\n"
"\r\n";
uv_buf_t buf = uv_buf_init(write_req, sizeof(write_req));
tlsuv_stream_write(wr, tls_stream, &buf, on_write_cb);
}
void on_resolve_cb(uv_getaddrinfo_t *resolver, int status, struct addrinfo *res)
{
mumble_ctx_t *ctx = resolver->data;
assert(status >= 0);
if (status < 0) {
ctx->error = status;
ctx->status = MUMBLE_STATUS_DISCONNECTED;
return;
}
tlsuv_stream_init(&ctx->uv_loop, &ctx->tls_stream, NULL);
//tlsuv_stream_connect_addr(&ctx->uv_connect_req, &ctx->tls_stream, res, on_connect_cb);
uv_freeaddrinfo(res);
}
int mumble_connect(mumble_ctx_t *ctx, const char *host, int port)
{
if (port == 0)
port = 64738;
tlsuv_stream_init(&ctx->uv_loop, &ctx->tls_stream, NULL);
int result = tlsuv_stream_connect(&ctx->uv_connect_req, &ctx->tls_stream, host, port, on_connect_cb);
assert(result == 0);
if (result != 0) {
ctx->error = result;
return result;
}
return 0;
}
int mumble_run(mumble_ctx_t *ctx)
{
return uv_run(&ctx->uv_loop, UV_RUN_DEFAULT);
}