uclient_backend_set_error(&uh->uc, code);
}
+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);
+}
+
static void uclient_notify_eof(struct uclient_http *uh)
{
struct ustream *us = uh->us;
uclient_backend_set_eof(&uh->uc);
if (uh->connection_close)
- uclient_http_disconnect(uh);
+ uclient_http_request_disconnect(&uh->uc);
}
static void uclient_http_reset_state(struct uclient_http *uh)
return start;
}
+static char *digest_sep(char **str)
+{
+ char *cur, *next;
+
+ cur = *str;
+ next = strchr(*str, ',');
+ if (next) {
+ *str = next + 1;
+ *next = 0;
+ } else {
+ *str += strlen(*str);
+ }
+
+ return cur;
+}
+
static bool strmatch(char **str, const char *prefix)
{
int len = strlen(prefix);
next = buf;
while (*next) {
const char **dest = NULL;
+ const char *tmp;
- while (isspace(*next))
+ while (*next && isspace(*next))
next++;
if (strmatch(&next, "realm"))
dest = &data.nonce;
else if (strmatch(&next, "opaque"))
dest = &opaque;
- else
- return;
+ else if (strmatch(&next, "stale") ||
+ strmatch(&next, "algorithm") ||
+ strmatch(&next, "auth-param")) {
+ digest_sep(&next);
+ continue;
+ } else if (strmatch(&next, "domain") ||
+ strmatch(&next, "qop-options"))
+ dest = &tmp;
+ else {
+ digest_sep(&next);
+ continue;
+ }
*dest = digest_unquote_sep(&next);
}
if (uh->eof)
return;
- if (uh->state == HTTP_STATE_RECV_DATA && uc->cb->data_read)
- uc->cb->data_read(uc);
+ if (uh->state == HTTP_STATE_RECV_DATA) {
+ /* Now it's uclient user turn to read some data */
+ uloop_timeout_cancel(&uc->connection_timeout);
+
+ if (uc->cb->data_read)
+ uc->cb->data_read(uc);
+ }
}
static void __uclient_notify_write(struct uclient_http *uh)
struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
int ret;
+ if (!cl->eof || uh->disconnect)
+ uclient_http_disconnect(uh);
+
uclient_http_init_request(uh);
if (uh->us)
}
static int
-uclient_http_send_data(struct uclient *cl, char *buf, unsigned int len)
+uclient_http_send_data(struct uclient *cl, const char *buf, unsigned int len)
{
struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
uclient_notify_eof(uh);
+ /* Now that we consumed something and if this isn't EOF, start timer again */
+ if (!uh->uc.eof && !cl->connection_timeout.pending)
+ uloop_timeout_set(&cl->connection_timeout, cl->timeout_msecs);
+
return len;
}
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,