summaryrefslogtreecommitdiffstats
path: root/net/flip/flip_stream.cc
diff options
context:
space:
mode:
authormbelshe@chromium.org <mbelshe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-29 03:13:06 +0000
committermbelshe@chromium.org <mbelshe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-29 03:13:06 +0000
commitcd314c828215d0ab4fb6ca721272f317014510c2 (patch)
tree93d58b91d9e1bb4146eca1db3e234cc14f00c17f /net/flip/flip_stream.cc
parentdc93fc6b4a41f8f14ef4f7acef40a9e8b9ef9070 (diff)
downloadchromium_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-xnet/flip/flip_stream.cc127
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
+