1 #include <libubox/ustream-ssl.h>
3 #include "uclient-utils.h"
4 #include "uclient-backend.h"
6 static struct uclient_url *uclient_get_url(const char *url_str)
8 static const struct uclient_backend *backends[] = {
12 const struct uclient_backend *backend;
13 const char * const *prefix = NULL;
14 struct uclient_url *url;
18 for (i = 0; i < ARRAY_SIZE(backends); i++) {
21 for (prefix = backends[i]->prefix; *prefix; prefix++) {
22 prefix_len = strlen(*prefix);
24 if (!strncmp(url_str, *prefix, prefix_len))
31 url_str += prefix_len;
32 backend = backends[i];
39 url = calloc_a(sizeof(*url), &url_buf, strlen(url_str) + 1);
40 url->backend = backend;
41 strcpy(url_buf, url_str);
43 next = strchr(url_buf, '/');
46 url->location = next + 1;
52 next = strchr(url_buf, '@');
57 if (uclient_urldecode(url_buf, url_buf, false) < 0)
63 /* Literal IPv6 address */
64 if (*url->host == '[') {
66 next = strrchr(url->host, ']');
74 next = strrchr(url->host, ':');
86 struct uclient *uclient_new(const char *url_str, const struct uclient_cb *cb)
89 struct uclient_url *url;
91 url = uclient_get_url(url_str);
95 cl = url->backend->alloc();
99 cl->backend = url->backend;
106 int uclient_connect_url(struct uclient *cl, const char *url_str)
108 struct uclient_url *url = cl->url;
111 url = uclient_get_url(url_str);
115 if (url->backend != cl->backend)
122 return cl->backend->connect(cl);
125 void uclient_free(struct uclient *cl)
127 struct uclient_url *url = cl->url;
129 if (cl->backend->free)
130 cl->backend->free(cl);
137 int uclient_write(struct uclient *cl, char *buf, int len)
139 if (!cl->backend->write)
142 return cl->backend->write(cl, buf, len);
145 int uclient_request(struct uclient *cl)
147 if (!cl->backend->request)
150 return cl->backend->request(cl);
153 int uclient_read(struct uclient *cl, char *buf, int len)
155 if (!cl->backend->read)
158 return cl->backend->read(cl, buf, len);
161 static void __uclient_backend_change_state(struct uloop_timeout *timeout)
163 struct uclient *cl = container_of(timeout, struct uclient, timeout);
165 if (cl->error && cl->cb->error)
167 else if (cl->eof && cl->cb->data_eof)
168 cl->cb->data_eof(cl);
171 static void uclient_backend_change_state(struct uclient *cl)
173 cl->timeout.cb = __uclient_backend_change_state;
174 uloop_timeout_set(&cl->timeout, 1);
177 void uclient_backend_set_error(struct uclient *cl)
183 uclient_backend_change_state(cl);
186 void __hidden uclient_backend_set_eof(struct uclient *cl)
188 if (cl->eof || cl->error)
192 uclient_backend_change_state(cl);
195 void __hidden uclient_backend_reset_state(struct uclient *cl)
199 uloop_timeout_cancel(&cl->timeout);