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/spdy/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     return ERR_ABORTED;
     32 
     33   int rv = delegate_->OnDataReceived(data, data_len);
     34   if (rv != OK) {
     35     DLOG(ERROR) << "Delegate refused data, rv: " << rv;
     36     Reset(QUIC_BAD_APPLICATION_PAYLOAD);
     37     return 0;
     38   }
     39   return data_len;
     40 }
     41 
     42 void QuicReliableClientStream::OnFinRead() {
     43   if (delegate_) {
     44     delegate_->OnClose(connection_error());
     45     delegate_ = NULL;
     46   }
     47   ReliableQuicStream::OnFinRead();
     48 }
     49 
     50 void QuicReliableClientStream::OnCanWrite() {
     51   ReliableQuicStream::OnCanWrite();
     52 
     53   if (!HasBufferedData() && !callback_.is_null()) {
     54     base::ResetAndReturn(&callback_).Run(OK);
     55   }
     56 }
     57 
     58 QuicPriority QuicReliableClientStream::EffectivePriority() const {
     59   if (delegate_ && delegate_->HasSendHeadersComplete()) {
     60     return QuicDataStream::EffectivePriority();
     61   }
     62   return kHighestPriority;
     63 }
     64 
     65 int QuicReliableClientStream::WriteStreamData(
     66     base::StringPiece data,
     67     bool fin,
     68     const CompletionCallback& callback) {
     69   // We should not have data buffered.
     70   DCHECK(!HasBufferedData());
     71   // Writes the data, or buffers it.
     72   WriteOrBufferData(data, fin);
     73   if (!HasBufferedData()) {
     74     return OK;
     75   }
     76 
     77   callback_ = callback;
     78   return ERR_IO_PENDING;
     79 }
     80 
     81 void QuicReliableClientStream::SetDelegate(
     82     QuicReliableClientStream::Delegate* delegate) {
     83   DCHECK((!delegate_ && delegate) || (delegate_ && !delegate));
     84   delegate_ = delegate;
     85 }
     86 
     87 void QuicReliableClientStream::OnError(int error) {
     88   if (delegate_) {
     89     QuicReliableClientStream::Delegate* delegate = delegate_;
     90     delegate_ = NULL;
     91     delegate->OnError(error);
     92   }
     93 }
     94 
     95 bool QuicReliableClientStream::CanWrite(const CompletionCallback& callback) {
     96   bool can_write =  session()->connection()->CanWrite(
     97       NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA,
     98       id() == kCryptoStreamId ? IS_HANDSHAKE : NOT_HANDSHAKE);
     99   if (!can_write) {
    100     session()->MarkWriteBlocked(id(), EffectivePriority());
    101     DCHECK(callback_.is_null());
    102     callback_ = callback;
    103   }
    104   return can_write;
    105 }
    106 
    107 }  // namespace net
    108