// Copyright 2016 The Chromium Embedded Framework Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "libcef/browser/net/source_stream.h" #include #include "net/base/io_buffer.h" // Use TYPE_INVALID so that URLRequestJob::NotifyHeadersComplete() doesn't // assume that the "content-length" header is accurate. CefSourceStream::CefSourceStream(CefRefPtr cef_filter, std::unique_ptr upstream) : net::FilterSourceStream(net::SourceStream::TYPE_INVALID, std::move(upstream)), cef_filter_(cef_filter) {} int CefSourceStream::FilterData(net::IOBuffer* output_buffer, int output_buffer_size, net::IOBuffer* input_buffer, int input_buffer_size, int* consumed_bytes, bool upstream_eof_reached) { if (!output_buffer || output_buffer_size <= 0) return net::ERR_CONTENT_DECODING_FAILED; if (input_buffer_size == 0 && last_status_ == RESPONSE_FILTER_DONE) { // No more input data. Respect the client's desire to be done with // outputting data. *consumed_bytes = 0; return 0; } size_t data_in_size = static_cast(input_buffer_size); size_t data_in_read = 0; size_t data_out_size = static_cast(output_buffer_size); size_t data_out_written = 0; last_status_ = cef_filter_->Filter( data_in_size > 0 ? input_buffer->data() : nullptr, data_in_size, data_in_read, output_buffer->data(), data_out_size, data_out_written); // Return early if there's an error. if (last_status_ == RESPONSE_FILTER_ERROR) return net::ERR_CONTENT_DECODING_FAILED; // Validate the out values. if (data_in_read > data_in_size) { LOG(ERROR) << "potential buffer overflow; data_in_read > data_in_size"; return net::ERR_CONTENT_DECODING_FAILED; } if (data_out_written > data_out_size) { LOG(ERROR) << "potential buffer overflow; data_out_written > data_out_size"; return net::ERR_CONTENT_DECODING_FAILED; } // If FilterData() returns 0, *|consumed_bytes| must be equal to // |input_buffer_size|. if (data_out_written == 0 && data_in_read != data_in_size) { LOG(ERROR) << "when no data is written all input must be consumed; " "data_out_written == 0 && data_in_read != data_in_size"; return net::ERR_CONTENT_DECODING_FAILED; } *consumed_bytes = static_cast(data_in_read); // Output the number of bytes written. return static_cast(data_out_written); } std::string CefSourceStream::GetTypeAsString() const { return "cef_filter"; }