struct ustream_fd ufd;
struct ustream_ssl ussl;
+ struct uloop_timeout disconnect_t;
+
bool ssl_require_validation;
bool ssl;
bool eof;
bool connection_close;
+ bool disconnect;
enum request_type req_type;
enum http_state state;
static void uclient_http_disconnect(struct uclient_http *uh)
{
+ uloop_timeout_cancel(&uh->disconnect_t);
if (!uh->us)
return;
{
struct ustream *us = uh->us;
+ if (uh->disconnect)
+ return;
+
if (!uh->eof) {
if (!us->eof && !us->write_error)
return;
uh->read_chunked = -1;
uh->content_length = -1;
uh->eof = false;
+ uh->disconnect = false;
uh->connection_close = false;
uh->state = HTTP_STATE_INIT;
if (uh->uc.cb->header_done)
uh->uc.cb->header_done(&uh->uc);
+ if (uh->eof)
+ return;
+
if (uh->req_type == REQ_HEAD || uh->uc.status_code == 204) {
uh->eof = true;
uclient_notify_eof(uh);
ustream_consume(uh->us, cur_len);
len -= cur_len;
+ if (uh->eof)
+ return;
+
data = ustream_get_read_buf(uh->us, &len);
} while (data && uh->state < HTTP_STATE_RECV_DATA);
return;
}
+ if (uh->eof)
+ return;
+
if (uh->state == HTTP_STATE_RECV_DATA && uc->cb->data_read)
uc->cb->data_read(uc);
}
return ret;
}
+static void uclient_http_disconnect_cb(struct uloop_timeout *timeout)
+{
+ struct uclient_http *uh = container_of(timeout, struct uclient_http, disconnect_t);
+
+ uclient_http_disconnect(uh);
+}
+
static struct uclient *uclient_http_alloc(void)
{
struct uclient_http *uh;
uh = calloc_a(sizeof(*uh));
+ uh->disconnect_t.cb = uclient_http_disconnect_cb;
blob_buf_init(&uh->headers, 0);
return &uh->uc;
return 0;
}
+static void uclient_http_request_disconnect(struct uclient *cl)
+{
+ struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
+
+ if (!uh->us)
+ return;
+
+ uh->eof = true;
+ uh->disconnect = true;
+ uloop_timeout_set(&uh->disconnect_t, 1);
+}
+
const struct uclient_backend uclient_backend_http = {
.prefix = uclient_http_prefix,
.alloc = uclient_http_alloc,
.free = uclient_http_free,
.connect = uclient_http_connect,
+ .disconnect = uclient_http_request_disconnect,
.update_url = uclient_http_free_url_state,
.read = uclient_http_read,
return cl->backend->read(cl, buf, len);
}
+void uclient_disconnect(struct uclient *cl)
+{
+ if (!cl->backend->disconnect)
+ return;
+
+ cl->backend->disconnect(cl);
+}
+
static void __uclient_backend_change_state(struct uloop_timeout *timeout)
{
struct uclient *cl = container_of(timeout, struct uclient, timeout);
int uclient_set_url(struct uclient *cl, const char *url, const char *auth);
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, char *buf, int len);