Home | History | Annotate | Download | only in quic
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/quic/quic_reliable_client_stream.h"
      6 
      7 #include "base/callback_helpers.h"
      8 #include "net/base/net_errors.h"
      9 #include "net/quic/quic_session.h"
     10 #include "net/quic/quic_write_blocked_list.h"
     11 
     12 namespace net {
     13 
     14 QuicReliableClientStream::QuicReliableClientStream(QuicStreamId id,
     15                                                    QuicSession* session,
     16                                                    const BoundNetLog& net_log)
     17     : QuicDataStream(id, session),
     18       net_log_(net_log),
     19       delegate_(NULL) {
     20 }
     21 
     22 QuicReliableClientStream::~QuicReliableClientStream() {
     23   if (delegate_)
     24     delegate_->OnClose(connection_error());
     25 }
     26 
     27 uint32 QuicReliableClientStream::ProcessData(const char* data,
     28                                              uint32 data_len) {
     29   // TODO(rch): buffer data if we don't have a delegate.
     30   if (!delegate_) {
     31     DLOG(ERROR) << "Missing delegate";
     32     Reset(QUIC_STREAM_CANCELLED);
     33     return 0;
     34   }
     35 
     36   int rv = delegate_->OnDataReceived(data, data_len);
     37   if (rv != OK) {
     38     DLOG(ERROR) << "Delegate refused data, rv: " << rv;
     39     Reset(QUIC_BAD_APPLICATION_PAYLOAD);
     40     return 0;
     41   }
     42   return data_len;
     43 }
     44 
     45 void QuicReliableClientStream::OnClose() {
     46   if (delegate_) {
     47     delegate_->OnClose(connection_error());
     48     delegate_ = NULL;
     49   }
     50   ReliableQuicStream::OnClose();
     51 }
     52 
     53 void QuicReliableClientStream::OnCanWrite() {
     54   ReliableQuicStream::OnCanWrite();
     55 
     56   if (!HasBufferedData() && !callback_.is_null()) {
     57     base::ResetAndReturn(&callback_).Run(OK);
     58   }
     59 }
     60 
     61 QuicPriority QuicReliableClientStream::EffectivePriority() const {
     62   if (delegate_ && delegate_->HasSendHeadersComplete()) {
     63     return QuicDataStream::EffectivePriority();
     64   }
     65   return QuicWriteBlockedList::kHighestPriority;
     66 }
     67 
     68 int QuicReliableClientStream::WriteStreamData(
     69     base::StringPiece data,
     70     bool fin,
     71     const CompletionCallback& callback) {
     72   // We should not have data buffered.
     73   DCHECK(!HasBufferedData());
     74   // Writes the data, or buffers it.
     75   WriteOrBufferData(data, fin, NULL);
     76   if (!HasBufferedData()) {
     77     return OK;
     78   }
     79 
     80   callback_ = callback;
     81   return ERR_IO_PENDING;
     82 }
     83 
     84 void QuicReliableClientStream::SetDelegate(
     85     QuicReliableClientStream::Delegate* delegate) {
     86   DCHECK((!delegate_ && delegate) || (delegate_ && !delegate));
     87   delegate_ = delegate;
     88 }
     89 
     90 void QuicReliableClientStream::OnError(int error) {
     91   if (delegate_) {
     92     QuicReliableClientStream::Delegate* delegate = delegate_;
     93     delegate_ = NULL;
     94     delegate->OnError(error);
     95   }
     96 }
     97 
     98 bool QuicReliableClientStream::CanWrite(const CompletionCallback& callback) {
     99   bool can_write =  session()->connection()->CanWrite(HAS_RETRANSMITTABLE_DATA);
    100   if (!can_write) {
    101     session()->MarkWriteBlocked(id(), EffectivePriority());
    102     DCHECK(callback_.is_null());
    103     callback_ = callback;
    104   }
    105   return can_write;
    106 }
    107 
    108 }  // namespace net
    109