AT+HTTPCLIENT headers missing

Stephan
Posts: 12
Joined: Tue Aug 27, 2019 2:42 am

AT+HTTPCLIENT headers missing

Postby Stephan » Wed Jun 23, 2021 9:00 am

For the new AT commands AT+HTTPCLIENT and AT+HTTPCPOST: It seems impossible to get the headers from the server answer? For instance, the client calls a server and gets a cookie (=in the HTTP answer header) in return. How to get the cookie content? It seems impossible.

Stephan
Posts: 12
Joined: Tue Aug 27, 2019 2:42 am

Re: AT+HTTPCLIENT headers missing

Postby Stephan » Wed Jun 23, 2021 7:52 pm

I found the answer myself. The HTTP parser works with callback functions at various points, where additional functionality can be insert. ESP-IDF inits these callback functions as follows (see esp_http_client_init()):

Code: Select all

 
    client->parser_settings->on_message_begin = http_on_message_begin;
    client->parser_settings->on_url = http_on_url;
    client->parser_settings->on_status = http_on_status;
    client->parser_settings->on_header_field = http_on_header_field;
    client->parser_settings->on_header_value = http_on_header_value;
    client->parser_settings->on_headers_complete = http_on_headers_complete;
    client->parser_settings->on_body = http_on_body;
    client->parser_settings->on_message_complete = http_on_message_complete;
    client->parser_settings->on_chunk_complete = http_on_chunk_complete;
Then I could go into http_on_header_value() and take care of header key/value pairs when read. In the example below, I made them simply visible on the Log screen:

Code: Select all

static int http_on_header_value(http_parser *parser, const char *at, size_t length)
{
    esp_http_client_handle_t client = parser->data;
    if (client->current_header_key == NULL) {
        return 0;
    }
    if (strcasecmp(client->current_header_key, "Location") == 0) {
        http_utils_assign_string(&client->location, at, length);
    } else if (strcasecmp(client->current_header_key, "Transfer-Encoding") == 0
               && memcmp(at, "chunked", length) == 0) {
        client->response->is_chunked = true;
    } else if (strcasecmp(client->current_header_key, "WWW-Authenticate") == 0) {
        http_utils_assign_string(&client->auth_header, at, length);
    }
    http_utils_assign_string(&client->current_header_value, at, length);

    //ESP_LOGD(TAG, "HEADER=%s:%s", client->current_header_key, client->current_header_value);
    ESP_LOGE(TAG, "HEADER=%s:%s", client->current_header_key, client->current_header_value);
  …
which gives
  • HTTP_CLIENT: HEADER=Date:Wed, 23 Jun 2021 19:07:25 GMT
    HTTP_CLIENT: HEADER=Server:Apache
    HTTP_CLIENT: HEADER=Content-Type:text/xml;charset=ISO-8859-1
    HTTP_CLIENT: HEADER=Content-Length:483
    HTTP_CLIENT: HEADER=Set-Cookie:JSESSIONID=4CBED8DB34FF062F372D6ADC3EF11655; Path=/dibbsDaisy; HttpOnly
    HTTP_CLIENT: HEADER=Vary:Accept-Encoding
Now it is a small step to include this header key/value pair into the chain of response headers, using http_header_new_item(), to make them retrievable with esp_http_client_get_header() afterwards.

Who is online

Users browsing this forum: dzungpv, Google [Bot] and 98 guests