diff options
author | mbelshe@chromium.org <mbelshe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-29 03:13:06 +0000 |
---|---|---|
committer | mbelshe@chromium.org <mbelshe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-29 03:13:06 +0000 |
commit | cd314c828215d0ab4fb6ca721272f317014510c2 (patch) | |
tree | 93d58b91d9e1bb4146eca1db3e234cc14f00c17f /net/flip/flip_stream.cc | |
parent | dc93fc6b4a41f8f14ef4f7acef40a9e8b9ef9070 (diff) | |
download | chromium_src-cd314c828215d0ab4fb6ca721272f317014510c2.zip chromium_src-cd314c828215d0ab4fb6ca721272f317014510c2.tar.gz chromium_src-cd314c828215d0ab4fb6ca721272f317014510c2.tar.bz2 |
Rename FlipStreamImpl to FlipStream and separate it out into
its own files. This is a straight refactoring with no other
changes
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/348007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30428 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/flip/flip_stream.cc')
-rwxr-xr-x | net/flip/flip_stream.cc | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/net/flip/flip_stream.cc b/net/flip/flip_stream.cc new file mode 100755 index 0000000..22f8272 --- /dev/null +++ b/net/flip/flip_stream.cc @@ -0,0 +1,127 @@ +// Copyright (c) 2009 The Chromium 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 "net/flip/flip_stream.h" + +#include "net/flip/flip_session.h" +#include "net/http/http_response_info.h" + +namespace net { + +bool FlipStream::AttachDelegate(FlipDelegate* delegate) { + DCHECK(delegate_ == NULL); // Don't attach if already attached. + DCHECK(path_.length() > 0); // Path needs to be set for push streams. + delegate_ = delegate; + + // If there is pending data, send it up here. + + // Check for the OnReply, and pass it up. + if (response_.get()) + delegate_->OnResponseReceived(response_.get()); + + // Pass data up + while (response_body_.size()) { + scoped_refptr<IOBufferWithSize> buffer = response_body_.front(); + response_body_.pop_front(); + delegate_->OnDataReceived(buffer->data(), buffer->size()); + } + + // Finally send up the end-of-stream. + if (download_finished_) { + delegate_->OnClose(net::OK); + return true; // tell the caller to shut us down + } + return false; +} + +void FlipStream::OnReply(const flip::FlipHeaderBlock* headers) { + DCHECK(headers); + DCHECK(headers->find("version") != headers->end()); + DCHECK(headers->find("status") != headers->end()); + + // TODO(mbelshe): if no version or status is found, we need to error + // out the stream. + + metrics_.StartStream(); + + // Server initiated streams must send a URL to us in the headers. + if (headers->find("path") != headers->end()) + path_ = headers->find("path")->second; + + // TODO(mbelshe): For now we convert from our nice hash map back + // to a string of headers; this is because the HttpResponseInfo + // is a bit rigid for its http (non-flip) design. + std::string raw_headers(headers->find("version")->second); + raw_headers.append(" ", 1); + raw_headers.append(headers->find("status")->second); + raw_headers.append("\0", 1); + flip::FlipHeaderBlock::const_iterator it; + for (it = headers->begin(); it != headers->end(); ++it) { + raw_headers.append(it->first); + raw_headers.append(":", 1); + raw_headers.append(it->second); + raw_headers.append("\0", 1); + } + + LOG(INFO) << "FlipStream: SynReply received for " << stream_id_; + + DCHECK(response_ == NULL); + response_.reset(new HttpResponseInfo()); + response_->headers = new HttpResponseHeaders(raw_headers); + // When pushing content from the server, we may not yet have a delegate_ + // to notify. When the delegate is attached, it will notify then. + if (delegate_) + delegate_->OnResponseReceived(response_.get()); +} + +bool FlipStream::OnData(const char* data, int length) { + DCHECK(length >= 0); + LOG(INFO) << "FlipStream: Data (" << length << " bytes) received for " + << stream_id_; + + // If we don't have a response, then the SYN_REPLY did not come through. + // We cannot pass data up to the caller unless the reply headers have been + // received. + if (!response_.get()) { + if (delegate_) + delegate_->OnClose(ERR_SYN_REPLY_NOT_RECEIVED); + return true; + } + + // A zero-length read means that the stream is being closed. + if (!length) { + metrics_.StopStream(); + download_finished_ = true; + if (delegate_) { + delegate_->OnClose(net::OK); + return true; // Tell the caller to clean us up. + } + } + + // Track our bandwidth. + metrics_.RecordBytes(length); + + // We've received data. We try to pass it up to the caller. + // In the case of server-push streams, we may not have a delegate yet assigned + // to this stream. In that case we just queue the data for later. + if (delegate_) { + delegate_->OnDataReceived(data, length); + } else { + // Save the data for use later. + // TODO(mbelshe): We need to have some throttling on this. We shouldn't + // buffer an infinite amount of data. + IOBufferWithSize* io_buffer = new IOBufferWithSize(length); + memcpy(io_buffer->data(), data, length); + response_body_.push_back(io_buffer); + } + return false; +} + +void FlipStream::OnError(int err) { + if (delegate_) + delegate_->OnClose(err); +} + +} // namespace net + |