2 * Copyright 2016 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <folly/Optional.h>
19 #include <folly/io/async/SSLContext.h>
20 #include <folly/io/async/AsyncSocket.h>
21 #include <folly/io/async/AsyncSSLSocket.h>
23 class BlockingSocket : public folly::AsyncSocket::ConnectCallback,
24 public folly::AsyncTransportWrapper::ReadCallback,
25 public folly::AsyncTransportWrapper::WriteCallback
28 explicit BlockingSocket(int fd)
29 : sock_(new folly::AsyncSocket(&eventBase_, fd)) {
32 BlockingSocket(folly::SocketAddress address,
33 std::shared_ptr<folly::SSLContext> sslContext)
34 : sock_(sslContext ? new folly::AsyncSSLSocket(sslContext, &eventBase_) :
35 new folly::AsyncSocket(&eventBase_)),
39 sock_->connect(this, address_);
41 if (err_.hasValue()) {
49 int32_t write(uint8_t const* buf, size_t len) {
50 sock_->write(this, buf, len);
52 if (err_.hasValue()) {
60 int32_t readAll(uint8_t *buf, size_t len) {
61 return readHelper(buf, len, true);
64 int32_t read(uint8_t *buf, size_t len) {
65 return readHelper(buf, len, false);
68 int getSocketFD() const {
69 return sock_->getFd();
73 folly::EventBase eventBase_;
74 folly::AsyncSocket::UniquePtr sock_;
75 folly::Optional<folly::AsyncSocketException> err_;
76 uint8_t *readBuf_{nullptr};
78 folly::SocketAddress address_;
80 void connectSuccess() noexcept override {}
81 void connectErr(const folly::AsyncSocketException& ex) noexcept override {
84 void getReadBuffer(void** bufReturn, size_t* lenReturn) override {
85 *bufReturn = readBuf_;
86 *lenReturn = readLen_;
88 void readDataAvailable(size_t len) noexcept override {
92 sock_->setReadCB(nullptr);
95 void readEOF() noexcept override {
97 void readErr(const folly::AsyncSocketException& ex) noexcept override {
100 void writeSuccess() noexcept override {}
101 void writeErr(size_t /* bytesWritten */,
102 const folly::AsyncSocketException& ex) noexcept override {
106 int32_t readHelper(uint8_t *buf, size_t len, bool all) {
109 sock_->setReadCB(this);
110 while (!err_ && sock_->good() && readLen_ > 0) {
116 sock_->setReadCB(nullptr);
117 if (err_.hasValue()) {
120 if (all && readLen_ > 0) {
121 throw folly::AsyncSocketException(folly::AsyncSocketException::UNKNOWN,
124 return len - readLen_;