Download Client Redirect Querry

Hi,

I am using download_client to get a bigger file (100KB) to my memory via LTE-M. The Files are located in a bucket and I use a shortURL to get the signedDownload URL. If I use this short URL in Download Client I get the Error "http/1.1 301 moved permanently". This seems to be correct, the URL is initialy ofcourse a redirect. But how can I handle this in my code? I couldnt find a way to read the header files with download client nor do I see any option for redirect hops or something like this. Is there even a solution? Or is it the limits of the low level integration?

Thanks for helping and best regards

daniel

  • Hi,

    This is one option and decision is yours. It might be the easiest since there is support for HTTP transport in this new downloader library.

    Best regards,
    Dejan

  • I solved the Redirect now manually via socket. I read the complete http response and get my URL. If anybody else ever needs this here is my function:

    #include <zephyr/net/socket.h>
    
    char *redirectHttp(const char *endpoint, const char *path) {
        int fd = 0;
        int err = 0;
        int bytes;
        char send_packet[200];
        char recv_buf[1024] = {};
        struct addrinfo *res;
        struct addrinfo hints = {
            .ai_family = AF_INET,
            .ai_socktype = SOCK_STREAM,
        };
    
        err = getaddrinfo(endpoint, "80", &hints, &res);
        if (err) {
            LOG_ERR("[SOCKET] getaddrinfo err %d", errno);
            return 0;
        }
        ((struct sockaddr_in *)res->ai_addr)->sin_port = htons(80);
    
        fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  // Set socket to tcp without tls
        if (fd == -1) {
            LOG_ERR("[SOCKET] failed to open");
            return 0;
        }
        char ipv4_addr[NET_IPV4_ADDR_LEN];
        inet_ntop(AF_INET, &((struct sockaddr_in *)res->ai_addr)->sin_port, ipv4_addr, sizeof(ipv4_addr));
        LOG_INF("[SOCKET] Connect to Addr IP: %s", ipv4_addr);
        err = connect(fd, res->ai_addr, sizeof(struct sockaddr_in));
        if (err) {
            LOG_ERR("[SOCKET] connect() err: %d", errno);
            return 0;
        }
    
        sprintf(send_packet,
                "GET %s HTTP/1.1\r\n"
                "Host: %s\r\n"
                "Accept: txt/plain\r\n\r\n",
                path, endpoint);
        bytes = send(fd, &send_packet, strlen(send_packet), 0);
        LOG_INF("[SOCKET] Sent %d bytes", bytes);
        bytes = blocking_recv(fd, recv_buf, sizeof(recv_buf), 0);
        LOG_INF("[SOCKET] Received %d bytes", bytes);
    
        const char *location_header = "Location: ";
        const char *start = strstr(recv_buf, location_header);
        if (start) {
            start += strlen(location_header);
    
            const char *end = strstr(start, "\r\n");
            if (!end) {
                end = start + strlen(start);  // End of string if no CRLF
            }
    
            size_t length = end - start;
    
            if (length < 1024) {
                char *url = (char *)malloc(length + 1);  // Allocate memory for the URL
                strncpy(url, start, length);
                url[length] = '\0';  // Null-terminate the string
                return url;
            } else {
                LOG_ERR("[SOCKET] URL is too long to fit in the buffer");
                return 0;
            }
        } else {
            LOG_ERR("[SOCKET] Location header not found in the response");
        }
    
        return 0;
    }

    Example Usage:

    const char *endpoint = "ul1.epaperframe.de";
    const char *path = "/tjoLta9.dl";
    char *url = redirectHttp(endpoint, path);
    printf("Redirected URL: %s\n", url);
    free(url);  // Free the allocated memory


    This ticket is solved for me now.

  • Hi,

    danielboe said:
    I solved the Redirect now manually via socket.

    This is great to hear. Thank you for the update.

    Best regards,
    Dejan

Related