Help with handling Range requests.

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

Help with handling Range requests.

Postby sjames1958 » Mon Apr 12, 2021 7:25 am

I am attempting to implement handling range requests for local files in my application. I have create a CefResourceHandler child class and implemented what I believe should work.
I am currently using a stream reader to access the content. (ES_LOG_INFO is our own logging macro). The request comes in with Range: 1-200
These are the headers that I set in the response (size is the total size of the file being served). Start and end are determined from the range header.
I added Access-Control-Expose-Headers just in case. we are using a third party library that is making the request and it

Code: Select all
                std::ostringstream stringStream;
                stringStream << "bytes " << start << "-" << end << "/" << size;
                CefResponse::HeaderMap::value_type contentRange("Content-Range", stringStream.str());
                headerMap.insert(contentRange);
                CefResponse::HeaderMap::value_type acceptRanges("accept-ranges", "bytes");
                headerMap.insert(acceptRanges);
                CefResponse::HeaderMap::value_type AccessContentRange("Access-Control-Expose-Headers", "Content-Range");
                headerMap.insert(AccessContentRange);
                return new MyResourceHandler(206, "Partial Content", mimeType, headerMap, stream, size);

Here is my Resource Handler class
Code: Select all
class MyResourceHandler : public CefResourceHandler {
public:
    MyResourceHandler(int status_code,
                      const CefString& status_text,
                      const CefString& mime_type,
                      CefResponse::HeaderMap header_map,
                      CefRefPtr<CefStreamReader> stream,
                      size_t size) :
    status_code_(status_code), status_text_(status_text), mime_type_(mime_type), header_map_(header_map), stream_(stream),
    size_(size), offset_(0)
    { }
   
    bool Open(CefRefPtr<CefRequest> request,
              bool& handle_request,
              CefRefPtr<CefCallback> callback) OVERRIDE {
        ES_LOG_INFO("Open - %s", request->GetMethod().ToString().c_str());
        handle_request = true;
        return true;
    }
   
    void GetResponseHeaders(CefRefPtr<CefResponse> response,
                            int64& response_length,
                            CefString& redirectUrl) OVERRIDE {
        ES_LOG_INFO("GetResponseHeaders");
        response_length = size_ - offset_;
        response->SetMimeType(mime_type_);
        response->SetHeaderMap(header_map_);
        response->SetStatus(status_code_);
        response->SetStatusText(status_text_);
    }
   
    bool Skip(int64 bytes_to_skip,
              int64& bytes_skipped,
              CefRefPtr<CefResourceSkipCallback> callback) OVERRIDE {
        ES_LOG_INFO("Skip: %d", bytes_to_skip);
        if (offset_ < size_) {
            bytes_skipped = std::min(bytes_to_skip, static_cast<int64>(size_ - offset_));
            std::vector<char> buff(bytes_to_skip);
            stream_->Read(buff.data(), 1, bytes_to_skip);
            offset_ += bytes_skipped;
        } else {
          bytes_skipped = ERR_FAILED;
        }
        return bytes_skipped > 0;
    }
   
    bool Read(void* data_out,
              int bytes_to_read,
              int& bytes_read,
              CefRefPtr<CefResourceReadCallback> callback) OVERRIDE {
        bytes_read = (int)stream_->Read(data_out, 1, bytes_to_read);
        ES_LOG_INFO("Read: %d -> %d", bytes_to_read, bytes_read);
        return bytes_read > 0;
    }
   
    void Cancel() OVERRIDE {
        ES_LOG_INFO("Cancelled");
    }
private:
    const int status_code_;
    const CefString status_text_;
    const CefString mime_type_;
    const CefResponse::HeaderMap header_map_;
    const CefRefPtr<CefStreamReader> stream_;
    size_t size_;
    int offset_;
   
    IMPLEMENT_REFCOUNTING(MyResourceHandler);
    DISALLOW_COPY_AND_ASSIGN(MyResourceHandler);
};
sjames1958
Mentor
 
Posts: 60
Joined: Sun Jun 22, 2014 7:41 am

Re: Help with handling Range requests.

Postby amaitland » Mon Apr 12, 2021 3:21 pm

I wrote a CefSharp example a while back, it's only had minimum testing, might give you some pointers https://github.com/cefsharp/CefSharp/bl ... Handler.cs
Maintainer of the CefSharp project.
amaitland
Virtuoso
 
Posts: 1290
Joined: Wed Jan 14, 2015 2:35 am


Return to Support Forum

Who is online

Users browsing this forum: No registered users and 21 guests