+
+ cur = tb[HTTP_HDR_AUTH];
+ if (cur) {
+ free(uh->auth_str);
+ uh->auth_str = strdup(blobmsg_data(cur));
+ }
+
+ uh->auth_type = uclient_http_update_auth_type(uh);
+}
+
+static void
+uclient_http_add_auth_header(struct uclient_http *uh)
+{
+ struct uclient_url *url = uh->uc.url;
+ char *auth_buf;
+ int auth_len;
+
+ if (!url->auth)
+ return;
+
+ auth_len = strlen(url->auth);
+ if (auth_len > 512)
+ return;
+
+ auth_buf = alloca(base64_len(auth_len) + 1);
+ base64_encode(url->auth, auth_len, auth_buf);
+ ustream_printf(uh->us, "Authorization: Basic %s\r\n", auth_buf);
+}
+
+static void
+uclient_http_send_headers(struct uclient_http *uh)
+{
+ struct uclient_url *url = uh->uc.url;
+ struct blob_attr *cur;
+ enum request_type req_type = uh->req_type;
+ int rem;
+
+ if (uh->state >= HTTP_STATE_HEADERS_SENT)
+ return;
+
+ if (uh->auth_type == AUTH_TYPE_UNKNOWN)
+ req_type = REQ_HEAD;
+
+ ustream_printf(uh->us,
+ "%s /%s HTTP/1.1\r\n"
+ "Host: %s\r\n",
+ request_types[req_type],
+ url->location, url->host);
+
+ blobmsg_for_each_attr(cur, uh->headers.head, rem)
+ ustream_printf(uh->us, "%s: %s\n", blobmsg_name(cur), (char *) blobmsg_data(cur));
+
+ if (uh->req_type == REQ_POST)
+ ustream_printf(uh->us, "Transfer-Encoding: chunked\r\n");
+
+ uclient_http_add_auth_header(uh);
+
+ ustream_printf(uh->us, "\r\n");
+}
+
+static void uclient_http_headers_complete(struct uclient_http *uh)
+{
+ enum auth_type auth_type = uh->auth_type;
+
+ uh->state = HTTP_STATE_RECV_DATA;
+ uh->uc.meta = uh->meta.head;
+ uclient_http_process_headers(uh);
+
+ if (auth_type == AUTH_TYPE_UNKNOWN) {
+ uclient_http_init_request(uh);
+ uclient_http_send_headers(uh);
+ uh->state = HTTP_STATE_REQUEST_DONE;
+ return;
+ }
+
+ if (uh->uc.cb->header_done)
+ uh->uc.cb->header_done(&uh->uc);
+
+ if (uh->req_type == REQ_HEAD) {
+ uh->eof = true;
+ uclient_notify_eof(uh);
+ }