Quantcast
Channel: Forum - Recent Threads
Viewing all articles
Browse latest Browse all 5781

Serving a dynamically generated file for download without using FileX

$
0
0

For testing our prototype which uses a webserver without FileX (just request_notify callback) I would like to serve a csv file with measurement data for download. The file is rather large, up to 30 MB, as it's generated from binary data in RAM. I'm testing with the following code:

 

UINT serve_measurement_csv(NX_HTTP_SERVER& server, UINT request_type, const string& resource, NX_PACKET& packet)
{
    SSP_PARAMETER_NOT_USED(request_type);
    SSP_PARAMETER_NOT_USED(packet);
    UINT status;
    //First, calculate file length and generate HTTP header for file download
    const char * header =
            "HTTP/1.0 200 \r\n"
            "Content-Length:%d\r\n"
            "Content-Type: text/plain\r\n"
            "Content-Disposition: attachment; filename=measurement.csv\r\n\r\n";
    ULONG header_length = 200;
    char header_buff[200]; //To be save
    //Line length is (4 characters per 12 bit value, one comma (or \r on last column)
    //plus \n) multiplied with the number of channels
    uint16_t line_length = (5 * ADC_NUM_CHANNELS + 1);
    //Calculate the file length as number of lines * line length
    uint32_t file_length = line_length * ADC_FAST_BUFFER_SIZE;
    header_length = snprintf(header_buff, header_length, header, file_length);

    status = nx_http_server_callback_data_send(&server, header_buff, header_length);
    if(status != NX_SUCCESS)
        log_failed(log_level::ERROR_INTERNAL, "nx_http_server_callback_data_send", status);
    string format_string = "\r\n";
    for(int i = 0; i < ADC_NUM_CHANNELS; i++)
        format_string = string("%d") + (i > 0 ? " " : "") + format_string;

    log_message(log_level::VERBOSE_INTERNAL, format_string);
    char num_buff[5];
    string line;
    line.reserve(line_length);
    //Next, repeatedly send data of the file in a loop
    for(int i = 0; i < ADC_MEASUREMENT_NUM_POINTS; i++)
    {
        line.clear();
        for(int j = 0; j < ADC_NUM_CHANNELS; j++)
        {
            snprintf(num_buff, 5, "%d", last_measurement[j][i]);
            line += num_buff;
            if(j < ADC_NUM_CHANNELS - 1)
                line += " ";
        }
        line += "\r\n";
        if(i == 0)
            log_message(log_level::VERBOSE_INTERNAL, line);
        status = nx_http_server_callback_data_send(&server, const_cast<char*>(line.c_str()), line.length());

        if(status != NX_SUCCESS)
            log_failed(log_level::ERROR_INTERNAL, "nx_http_server_callback_data_send", status);
    }
    /* Return completion status.  */
    return(NX_HTTP_CALLBACK_COMPLETED);
}

 

Firefox will claim that the download failed, wget stops after 4%, and nx_http_server_callback_data_send repeatedly fails with status 0x49. I believe this is the status code

NX_TX_QUEUE_DEPTH (0x49) Maximum transmit queue depth has been reached. 

 

I'm sure that I should not send each line separatedly, but is there anything else I should do to prevent this error? Do I need to wait after a specific number of packets?


Viewing all articles
Browse latest Browse all 5781

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>