summaryrefslogtreecommitdiff
path: root/uclient.h
blob: 4f37364e55ab805bba7fdca5908bb3d1434e921e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
 * uclient - ustream based protocol client library
 *
 * Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
#ifndef __LIBUBOX_UCLIENT_H
#define __LIBUBOX_UCLIENT_H

#include <netinet/in.h>

#include <libubox/blob.h>
#include <libubox/ustream.h>
#include <libubox/ustream-ssl.h>

#define UCLIENT_DEFAULT_TIMEOUT_MS			30000

struct uclient_cb;
struct uclient_backend;

enum uclient_error_code {
	UCLIENT_ERROR_UNKNOWN,
	UCLIENT_ERROR_CONNECT,
	UCLIENT_ERROR_TIMEDOUT,
	UCLIENT_ERROR_SSL_INVALID_CERT,
	UCLIENT_ERROR_SSL_CN_MISMATCH,
	UCLIENT_ERROR_MISSING_SSL_CONTEXT,
	__UCLIENT_ERROR_MAX
};

union uclient_addr {
	struct sockaddr sa;
	struct sockaddr_in sin;
	struct sockaddr_in6 sin6;
};

struct uclient_url {
	const struct uclient_backend *backend;
	int prefix;

	const char *host;
	const char *port;
	const char *location;

	const char *auth;
};

struct uclient {
	const struct uclient_backend *backend;
	const struct uclient_cb *cb;

	union uclient_addr local_addr, remote_addr;

	struct uclient_url *proxy_url;
	struct uclient_url *url;
	int timeout_msecs;
	void *priv;

	bool eof;
	bool data_eof;
	int error_code;
	int status_code;
	int seq;
	struct blob_attr *meta;

	struct uloop_timeout connection_timeout;
	struct uloop_timeout timeout;
};

struct uclient_cb {
	void (*data_read)(struct uclient *cl);
	void (*data_sent)(struct uclient *cl);
	void (*data_eof)(struct uclient *cl);
	void (*header_done)(struct uclient *cl);
	void (*error)(struct uclient *cl, int code);
};

struct uclient *uclient_new(const char *url, const char *auth_str, const struct uclient_cb *cb);
void uclient_free(struct uclient *cl);

int uclient_set_url(struct uclient *cl, const char *url, const char *auth);
int uclient_set_proxy_url(struct uclient *cl, const char *url_str, const char *auth_str);


/**
 * Sets connection timeout.
 *
 * Provided timeout value will be used for:
 * 1) Receiving HTTP response
 * 2) Receiving data
 *
 * In case of timeout uclient will use error callback with
 * UCLIENT_ERROR_TIMEDOUT code.
 *
 * @param msecs timeout in milliseconds
 */
int uclient_set_timeout(struct uclient *cl, int msecs);

int uclient_connect(struct uclient *cl);
void uclient_disconnect(struct uclient *cl);

int uclient_read(struct uclient *cl, char *buf, int len);
int uclient_write(struct uclient *cl, const char *buf, int len);
int uclient_request(struct uclient *cl);

char *uclient_get_addr(char *dest, int *port, union uclient_addr *a);

/* HTTP */
extern const struct uclient_backend uclient_backend_http;

int uclient_http_reset_headers(struct uclient *cl);
int uclient_http_set_header(struct uclient *cl, const char *name, const char *value);
int uclient_http_set_request_type(struct uclient *cl, const char *type);
int uclient_http_redirect(struct uclient *cl);

int uclient_http_set_ssl_ctx(struct uclient *cl, const struct ustream_ssl_ops *ops,
			     struct ustream_ssl_ctx *ctx, bool require_validation);
int uclient_http_set_address_family(struct uclient *cl, int af);
const char *uclient_strerror(unsigned err);

#endif