#include <ctype.h>
#include <unistd.h>
#include <stdint.h>
+#include <string.h>
#include <fcntl.h>
#include <libubox/ustream.h>
}
}
-static void
+static int
uclient_http_add_auth_basic(struct uclient_http *uh)
{
struct uclient_url *url = uh->uc.url;
char *auth_buf;
if (auth_len > 512)
- return;
+ return -EINVAL;
auth_buf = alloca(base64_len(auth_len) + 1);
+ if (!auth_buf)
+ return -ENOMEM;
+
base64_encode(url->auth, auth_len, auth_buf);
ustream_printf(uh->us, "Authorization: Basic %s\r\n", auth_buf);
+
+ return 0;
}
static char *digest_unquote_sep(char **str)
*ofs = cur - *buf;
}
-static void
+static int
uclient_http_add_auth_digest(struct uclient_http *uh)
{
+ int err = 0;
struct uclient_url *url = uh->uc.url;
const char *realm = NULL, *opaque = NULL;
const char *user, *password;
- char *buf, *next;
+ char *buf, *next, *buf_orig;
int len, ofs;
char cnonce_str[9];
};
len = strlen(uh->auth_str) + 1;
- if (len > 512)
- return;
+ if (len > 512) {
+ err = -EINVAL;
+ goto fail;
+ }
buf = alloca(len);
+ if (!buf) {
+ err = -ENOMEM;
+ goto fail;
+ }
+
strcpy(buf, uh->auth_str);
/* skip auth type */
- strsep(&buf, " ");
+ buf_orig = strsep(&buf, " ");
next = buf;
while (*next) {
*dest = digest_unquote_sep(&next);
}
- if (!realm || !data.qop || !data.nonce)
- return;
+ if (!realm || !data.qop || !data.nonce) {
+ err = -EINVAL;
+ goto fail_buf;
+ }
sprintf(nc_str, "%08x", uh->nc++);
get_cnonce(cnonce_str);
char *user_buf;
len = password - url->auth;
- if (len > 256)
- return;
+ if (len > 256) {
+ err = -EINVAL;
+ goto fail_buf;
+ }
user_buf = alloca(len + 1);
+ if (!user_buf) {
+ err = -ENOMEM;
+ goto fail_buf;
+ }
+
strncpy(user_buf, url->auth, len);
user_buf[len] = 0;
user = user_buf;
add_field(&buf, &ofs, &len, "opaque", opaque);
ustream_printf(uh->us, "Authorization: Digest nc=%s, qop=%s%s\r\n", data.nc, data.qop, buf);
+
free(buf);
+
+ return 0;
+
+fail_buf:
+ free(buf_orig);
+fail:
+ return err;
}
static void
struct uclient_url *url = uh->uc.url;
struct blob_attr *cur;
enum request_type req_type = uh->req_type;
+ bool literal_ipv6;
int rem;
if (uh->state >= HTTP_STATE_HEADERS_SENT)
if (uh->uc.proxy_url)
url = uh->uc.proxy_url;
+ literal_ipv6 = strchr(url->host, ':');
+
ustream_printf(uh->us,
"%s %s HTTP/1.1\r\n"
- "Host: %s%s%s\r\n",
- request_types[req_type],
- url->location, url->host,
+ "Host: %s%s%s%s%s\r\n",
+ request_types[req_type], url->location,
+ literal_ipv6 ? "[" : "",
+ url->host,
+ literal_ipv6 ? "]" : "",
url->port ? ":" : "",
url->port ? url->port : "");
struct uclient_http *uh;
uh = calloc_a(sizeof(*uh));
+ if (!uh)
+ return NULL;
+
uh->disconnect_t.cb = uclient_http_disconnect_cb;
blob_buf_init(&uh->headers, 0);