0

I was wondering if this code from https://www.boost.org/doc/libs/1_70_0/libs/beast/example/http/server/async/http_server_async.cpp

    // Attempt to open the file
    beast::error_code ec;
    http::file_body::value_type body;
    body.open(path.c_str(), beast::file_mode::scan, ec);

could easily be extended to fulfill the http range field information by some file body operations.

I would like to avoid to reimplement available code, to have own (posix, ...) file handling if unnecessary.

Many thanks for your input!

Tom

1 Answers1

0

the easiest way might be to patch the boost beast implementation (see below). However please be sure, you have little knowledge of html in this case e.g.

  • answer an html request with "206 partial content"
  • use the appropriate field (content-range) to recognize the part of the file and to set the response accordingly.

Important information for the html headers can be found here:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests

Then boost beast just needs some small changes to the open() method to deliver partial files (boost/beast/http/basic_file_body.hpp). It was implemented with uint64_t but a boost::optional<> can do the trick as well.

There are two main things, that really matters:

  1. seek() to the file start position and
  2. set the remainder (in form of file_size_) to the data length (the portion lenth between start and end).

Bear in mind, the start and the endpoint is included in the range request. I.e. the length of the part is always end-start+1.

However with this change, please read the overall file size for the range response in advance, as the size() method would return the partitial size.

template<class File>
void
basic_file_body<File>::
value_type::
open(char const* path, file_mode mode, error_code& ec, uint64_t start, uint64_t end)
{
    // Open the file
    file_.open(path, mode, ec);
    if(ec)
        return;

    // Cache the size
    file_size_ = file_.size(ec);
    if(ec)
    {
        close();
        return;
    }

    if (end > file_size_ || end == 0)
        end = file_size_-1;

    if (start <= end) {
        file_.seek(start, ec);
        if(ec)
        {
            close();
            return;
        }
        file_size_ = end - start + 1;
    }

}

And be sure: There may be other ways to do the partial read!

Tom