1 /* 2 * Copyright (c) Facebook, Inc. and its affiliates. 3 * All rights reserved. 4 * 5 * This source code is licensed under the BSD-style license found in the 6 * LICENSE file in the root directory of this source tree. 7 */ 8 9 #include <proxygen/lib/http/codec/HTTPParallelCodec.h> 10 11 #include <algorithm> 12 #include <boost/algorithm/string.hpp> 13 #include <glog/logging.h> 14 #include <proxygen/lib/http/HTTPMessage.h> 15 16 namespace proxygen { 17 HTTPParallelCodec(TransportDirection direction)18HTTPParallelCodec::HTTPParallelCodec(TransportDirection direction) 19 : transportDirection_(direction), sessionClosing_(ClosingState::OPEN) { 20 switch (transportDirection_) { 21 case TransportDirection::DOWNSTREAM: 22 nextEgressStreamID_ = 2; 23 break; 24 case TransportDirection::UPSTREAM: 25 nextEgressStreamID_ = 1; 26 break; 27 default: 28 LOG(FATAL) << "Unknown transport direction."; 29 } 30 } 31 createStream()32HTTPCodec::StreamID HTTPParallelCodec::createStream() { 33 auto ret = nextEgressStreamID_; 34 nextEgressStreamID_ += 2; 35 return ret; 36 } 37 isWaitingToDrain() const38bool HTTPParallelCodec::isWaitingToDrain() const { 39 return sessionClosing_ == ClosingState::OPEN || 40 sessionClosing_ == ClosingState::FIRST_GOAWAY_SENT; 41 } 42 isReusable() const43bool HTTPParallelCodec::isReusable() const { 44 return (sessionClosing_ == ClosingState::OPEN || 45 sessionClosing_ == ClosingState::OPEN_WITH_GRACEFUL_DRAIN_ENABLED || 46 (transportDirection_ == TransportDirection::DOWNSTREAM && 47 isWaitingToDrain())) && 48 (ingressGoawayAck_ == std::numeric_limits<uint32_t>::max()) && 49 (nextEgressStreamID_ <= std::numeric_limits<int32_t>::max() - 2); 50 } 51 enableDoubleGoawayDrain()52void HTTPParallelCodec::enableDoubleGoawayDrain() { 53 if (sessionClosing_ == ClosingState::OPEN) { 54 sessionClosing_ = ClosingState::OPEN_WITH_GRACEFUL_DRAIN_ENABLED; 55 } else { 56 VLOG(3) << "Cannot enable double goaway because the session is already " 57 "draining or closed"; 58 } 59 } 60 onIngressUpgradeMessage(const HTTPMessage &)61bool HTTPParallelCodec::onIngressUpgradeMessage(const HTTPMessage& /*msg*/) { 62 if (transportDirection_ == TransportDirection::DOWNSTREAM) { 63 lastStreamID_ = 1; 64 } 65 return true; 66 } 67 68 } // namespace proxygen 69