SLM Application: Unable to specify custom HTTP host header.

Currently it is impossible to specify your own HTTP host header in the SLM-application nRFConnectSDK. The host header is appended automatically by Zephyr by using the host-parameter on the http_request object. Specifying your own Host: header through AT-commands will cause the Host header to be sent twice, making the HTTP-server return an invalid request error such as the user below experienced:

 RE: Format for HTTP request using AT commands in SLM application 

A possible fix is to check if the Host: header is present in the AT command and replace that in the http_request object in the SLM-application. For applications using their own DNS-driver (eg. we are having trouble with some networks supporting only supporting PCO, and some ePCO so we use our own DNS and use IP's in AT-commands) this is troublesome. Also, this isn't documented behavior in the nRFConnectSDK.

  • Hi,

     

    Just to ensure that I understand the scenario fully, it is the "Host: ..." string in the http-template that you want to replace?

    Ie. similar to this one? https://github.com/nrfconnect/sdk-nrf/blob/main/samples/nrf9160/https_client/src/main.c#L22

    If yes, this is a bit of a strange scenario, as it seems to me that you're requesting a http proxy functionality.

    At this point, the DNS (ie. getaddrinfo()) has already been run, and you're connected to the server you're communicating with.

     

    Or is the root problem here the getaddrinfo() call, which is called through slm_util.c::util_resolve_host() ?

     

    Kind regards,

    Håkon

  • Correct, we want to replace the default Host header but not in the https_client example. In the SLM-application (Serial LTE Modem https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/applications/serial_lte_modem/README.html). 

    You implemented the following commands:

    - AT#XHTTPCCON=<op>[,<host>,<port>[,<sec_tag>]] 

    - AT#XHTTPCREQ=<method>,<resource>[,<headers>[,<content_type>,<content_length>[,<chunked_transfer>]]]

    Assume the following situation:

    There is a HTTP-server running at IP 127.0.0.1, and it is hosting the following domains:

    - test1.nordicsemi.com
    - test2.nordicsemi.com

    The webserver uses the "Host: <hostname>" HTTP-header to differentiate which website to serve. Our device wants to send requests to both domains. Hence we connect to the webserver by the following command:

    AT#XHTTPCCON=1,"127.0.0.1",80

    There is now a connection open with the webserver. We want to send two requests, one to test1.nordicsemi.com and one to test2.nordicsemi.com

    We use the following command to specify a request to test1.nordicsemi.com:

    AT#XHTTPCREQ=GET,"/api/version","Host: test1.nordicsemi.com\r\n"

    What we expect to happen is for the SLM to send the following HTTP request:

    GET /api/version HTTP/1.1
    Host: test1.nordicsemi.com

    What actually happens, is that the Nordic Serial LTE Modem application assumes that the IP we provided in XHTTPCON is also the hostname we want to provide in the HTTP-header. The following (invalid) request gets sent out:

    GET /api/version HTTP/1.1
    Host: 127.0.0.1 Host: test1.nordicsemi.com

    Naturally, the HTTP-server responds with status code 400: Invalid request, as there is a duplicate host header in the HTTP-request, which is illegal. We propose that the SLM does not provide its own host-header when the user specifies one themselves.

     
  • Hi,

     

    Ivan Herrera said:
    Correct, we want to replace the default Host header but not in the https_client example. In the SLM-application (Serial LTE Modem

    Yes, I took the https_client sample as it states "host:" in plain text.

     

    Ivan Herrera said:

    Assume the following situation:

    There is a HTTP-server running at IP 127.0.0.1, and it is hosting the following domains:

    - test1.nordicsemi.com
    - test2.nordicsemi.com

    The webserver uses the "Host: <hostname>" HTTP-header to differentiate which website to serve. Our device wants to send requests to both domains. Hence we connect to the webserver by the following command:

    AT#XHTTPCCON=1,"127.0.0.1",80

    There is now a connection open with the webserver. We want to send two requests, one to test1.nordicsemi.com and one to test2.nordicsemi.com

    We use the following command to specify a request to test1.nordicsemi.com:

    You're working around not having DNS.

    Wouldn't the workaround be that you provide a valid DNS?

     

    Have you tried setting a secondary DNS manually, via this function call?

    https://github.com/nrfconnect/sdk-nrfxlib/blob/v2.1.0-rc1/nrf_modem/include/nrf_socket.h#L809

     

    Here's an example implementation:

    struct nrf_in_addr dns;
    int err = nrf_inet_pton(NRF_AF_INET, "8.8.8.8", &dns);
    if (err != 1) {
        LOG_ERR("Failed to convert custom DNS address to %s, err %d", "8.8.8.8", errno);
        return ;
    }
    err = nrf_setdnsaddr(NRF_AF_INET, &dns);
    if (err) {
        LOG_ERR("Failed to set custom DNS address to %s, err %d", "8.8.8.8", errno);
        return ;
    }

     

    Kind regards,

    Håkon

  • Hi Hakon! 

    Thanks for your reply. We will resort to your solution.

Related