@@ -452,36 +452,43 @@ static size_t channel_callback_headers(char *buffer, size_t size, size_t nitems,
{
channel_data_t *channel_data = (channel_data_t *)userdata;
struct dict *dict = channel_data->received_headers;
- char *info = malloc(size * nitems + 1);
+ char *info;
char *p, *key, *val;
- if (!info) {
- ERROR("No memory allocated for headers, headers not collected !!");
- return nitems * size;
- }
- /*
- * Work on a local copy because the buffer is not
- * '\0' terminated
- */
- memcpy(info, buffer, size * nitems);
- info[size * nitems] = '\0';
- p = memchr(info, ':', size * nitems);
- if (p) {
- *p = '\0';
- key = info;
- val = p + 1; /* Next char after ':' */
- while(isspace((unsigned char)*val)) val++;
- /* Remove '\n', '\r', and '\r\n' from header's value. */
- *strchrnul(val, '\r') = '\0';
- *strchrnul(val, '\n') = '\0';
- /* For multiple same-key headers, only the last is saved. */
- dict_set_value(dict, key, val);
- TRACE("Header processed: %s : %s", key, val);
- } else {
- TRACE("Header not processed: '%s'", info);
+ if (dict) {
+ info = malloc(size * nitems + 1);
+ if (!info) {
+ ERROR("No memory allocated for headers, headers not collected !!");
+ return nitems * size;
+ }
+ /*
+ * Work on a local copy because the buffer is not
+ * '\0' terminated
+ */
+ memcpy(info, buffer, size * nitems);
+ info[size * nitems] = '\0';
+ p = memchr(info, ':', size * nitems);
+ if (p) {
+ *p = '\0';
+ key = info;
+ val = p + 1; /* Next char after ':' */
+ while(isspace((unsigned char)*val)) val++;
+ /* Remove '\n', '\r', and '\r\n' from header's value. */
+ *strchrnul(val, '\r') = '\0';
+ *strchrnul(val, '\n') = '\0';
+ /* For multiple same-key headers, only the last is saved. */
+ dict_set_value(dict, key, val);
+ TRACE("Header processed: %s : %s", key, val);
+ } else {
+ TRACE("Header not processed: '%s'", info);
+ }
+
+ free(info);
}
- free(info);
+ if (channel_data->headers)
+ return channel_data->headers(buffer, size, nitems, userdata);
+
return nitems * size;
}
@@ -608,7 +615,7 @@ channel_op_res_t channel_set_options(channel_t *this, channel_data_t *channel_da
goto cleanup;
}
- if (channel_data->received_headers) {
+ if (channel_data->received_headers || channel_data->headers) {
/*
* Setup supply request and receive reply HTTP headers.
* A LIST_INIT()'d dictionary is expected at channel_data->headers.
@@ -619,7 +626,7 @@ channel_op_res_t channel_set_options(channel_t *this, channel_data_t *channel_da
CURLOPT_HEADERFUNCTION,
channel_callback_headers) != CURLE_OK) ||
(curl_easy_setopt(channel_curl->handle, CURLOPT_HEADERDATA,
- channel_data->received_headers) != CURLE_OK)) {
+ channel_data) != CURLE_OK)) {
result = CHANNEL_EINIT;
goto cleanup;
}
@@ -71,6 +71,8 @@ typedef struct {
bool nofollow;
size_t (*dwlwrdata)(char *streamdata, size_t size, size_t nmemb,
void *data);
+ size_t (*headers)(char *streamdata, size_t size, size_t nmemb,
+ void *data);
struct swupdate_digest *dgst;
char sha1hash[SWUPDATE_SHA_DIGEST_LENGTH * 2 + 1];
sourcetype source;
Headers are handled automatically by the channel. Add an optional callback that the channel can call to handle the headers. Signed-off-by: Stefano Babic <sbabic@denx.de> --- corelib/channel_curl.c | 63 +++++++++++++++++++++++------------------- include/channel_curl.h | 2 ++ 2 files changed, 37 insertions(+), 28 deletions(-)