diff --git a/lib/cpp/CMakeLists.txt b/lib/cpp/CMakeLists.txt
index d705bb3..29caad4 100755
--- a/lib/cpp/CMakeLists.txt
+++ b/lib/cpp/CMakeLists.txt
@@ -57,6 +57,8 @@
    src/thrift/transport/TServerSocket.cpp
    src/thrift/transport/TTransportUtils.cpp
    src/thrift/transport/TBufferTransports.cpp
+   src/thrift/transport/TWebSocketServer.h
+   src/thrift/transport/TWebSocketServer.cpp
    src/thrift/server/TConnectedClient.cpp
    src/thrift/server/TServerFramework.cpp
    src/thrift/server/TSimpleServer.cpp
diff --git a/lib/cpp/Makefile.am b/lib/cpp/Makefile.am
index 9b5fb4c..f699f83 100755
--- a/lib/cpp/Makefile.am
+++ b/lib/cpp/Makefile.am
@@ -87,6 +87,7 @@
                        src/thrift/transport/TNonblockingSSLServerSocket.cpp \
                        src/thrift/transport/TTransportUtils.cpp \
                        src/thrift/transport/TBufferTransports.cpp \
+                       src/thrift/transport/TWebSocketServer.cpp \
                        src/thrift/server/TConnectedClient.cpp \
                        src/thrift/server/TServer.cpp \
                        src/thrift/server/TServerFramework.cpp \
@@ -140,7 +141,8 @@
                          src/thrift/TApplicationException.h \
                          src/thrift/TLogging.h \
                          src/thrift/TToString.h \
-                         src/thrift/TBase.h
+                         src/thrift/TBase.h \
+                         src/thrift/portable_endian.h
 
 include_concurrencydir = $(include_thriftdir)/concurrency
 include_concurrency_HEADERS = \
@@ -198,7 +200,8 @@
                          src/thrift/transport/TTransportUtils.h \
                          src/thrift/transport/TBufferTransports.h \
                          src/thrift/transport/TShortReadTransport.h \
-                         src/thrift/transport/TZlibTransport.h
+                         src/thrift/transport/TZlibTransport.h \
+                         src/thrift/transport/TWebSocketServer.h
 
 include_serverdir = $(include_thriftdir)/server
 include_server_HEADERS = \
diff --git a/lib/cpp/src/thrift/portable_endian.h b/lib/cpp/src/thrift/portable_endian.h
new file mode 100644
index 0000000..e07010e
--- /dev/null
+++ b/lib/cpp/src/thrift/portable_endian.h
@@ -0,0 +1,131 @@
+//
+// endian.h
+//
+// https://gist.github.com/panzi/6856583
+//
+// I, Mathias Panzenböck, place this file hereby into the public domain. Use
+// it at your own risk for whatever you like. In case there are
+// jurisdictions that don't support putting things in the public domain you
+// can also consider it to be "dual licensed" under the BSD, MIT and Apache
+// licenses, if you want to. This code is trivial anyway. Consider it an
+// example on how to get the endian conversion functions on different
+// platforms.
+
+#ifndef PORTABLE_ENDIAN_H__
+#define PORTABLE_ENDIAN_H__
+
+#if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__)
+
+#	define __WINDOWS__
+
+#endif
+
+#if defined(__linux__) || defined(__CYGWIN__)
+
+#	include <endian.h>
+
+#elif defined(__APPLE__)
+
+#	include <libkern/OSByteOrder.h>
+
+#	define htobe16(x) OSSwapHostToBigInt16(x)
+#	define htole16(x) OSSwapHostToLittleInt16(x)
+#	define be16toh(x) OSSwapBigToHostInt16(x)
+#	define le16toh(x) OSSwapLittleToHostInt16(x)
+
+#	define htobe32(x) OSSwapHostToBigInt32(x)
+#	define htole32(x) OSSwapHostToLittleInt32(x)
+#	define be32toh(x) OSSwapBigToHostInt32(x)
+#	define le32toh(x) OSSwapLittleToHostInt32(x)
+
+#	define htobe64(x) OSSwapHostToBigInt64(x)
+#	define htole64(x) OSSwapHostToLittleInt64(x)
+#	define be64toh(x) OSSwapBigToHostInt64(x)
+#	define le64toh(x) OSSwapLittleToHostInt64(x)
+
+#	define __BYTE_ORDER    BYTE_ORDER
+#	define __BIG_ENDIAN    BIG_ENDIAN
+#	define __LITTLE_ENDIAN LITTLE_ENDIAN
+#	define __PDP_ENDIAN    PDP_ENDIAN
+
+#elif defined(__OpenBSD__)
+
+#	include <sys/endian.h>
+
+#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
+
+#	include <sys/endian.h>
+
+#	define be16toh(x) betoh16(x)
+#	define le16toh(x) letoh16(x)
+
+#	define be32toh(x) betoh32(x)
+#	define le32toh(x) letoh32(x)
+
+#	define be64toh(x) betoh64(x)
+#	define le64toh(x) letoh64(x)
+
+#elif defined(__WINDOWS__)
+
+#	include <winsock2.h>
+
+#	if BYTE_ORDER == LITTLE_ENDIAN
+
+#		define htobe16(x) htons(x)
+#		define htole16(x) (x)
+#		define be16toh(x) ntohs(x)
+#		define le16toh(x) (x)
+
+#		define htobe32(x) htonl(x)
+#		define htole32(x) (x)
+#		define be32toh(x) ntohl(x)
+#		define le32toh(x) (x)
+
+#	if defined(__MINGW32__)
+#		define htobe64(x) __builtin_bswap64(x)
+#		define htole64(x) (x)
+#		define be64toh(x) __builtin_bswap64(x)
+#		define le64toh(x) (x)
+#	else
+#		define htobe64(x) htonll(x)
+#		define htole64(x) (x)
+#		define be64toh(x) ntohll(x)
+#		define le64toh(x) (x)
+#	endif
+
+#	elif BYTE_ORDER == BIG_ENDIAN
+
+		/* that would be xbox 360 */
+#		define htobe16(x) (x)
+#		define htole16(x) __builtin_bswap16(x)
+#		define be16toh(x) (x)
+#		define le16toh(x) __builtin_bswap16(x)
+
+#		define htobe32(x) (x)
+#		define htole32(x) __builtin_bswap32(x)
+#		define be32toh(x) (x)
+#		define le32toh(x) __builtin_bswap32(x)
+
+#		define htobe64(x) (x)
+#		define htole64(x) __builtin_bswap64(x)
+#		define be64toh(x) (x)
+#		define le64toh(x) __builtin_bswap64(x)
+
+#	else
+
+#		error byte order not supported
+
+#	endif
+
+#	define __BYTE_ORDER    BYTE_ORDER
+#	define __BIG_ENDIAN    BIG_ENDIAN
+#	define __LITTLE_ENDIAN LITTLE_ENDIAN
+#	define __PDP_ENDIAN    PDP_ENDIAN
+
+#else
+
+#	error platform not supported
+
+#endif
+
+#endif
diff --git a/lib/cpp/src/thrift/transport/THttpServer.cpp b/lib/cpp/src/thrift/transport/THttpServer.cpp
index 94ac681..98518fd 100644
--- a/lib/cpp/src/thrift/transport/THttpServer.cpp
+++ b/lib/cpp/src/thrift/transport/THttpServer.cpp
@@ -124,12 +124,7 @@
   writeBuffer_.getBuffer(&buf, &len);
 
   // Construct the HTTP header
-  std::ostringstream h;
-  h << "HTTP/1.1 200 OK" << CRLF << "Date: " << getTimeRFC1123() << CRLF << "Server: Thrift/"
-    << PACKAGE_VERSION << CRLF << "Access-Control-Allow-Origin: *" << CRLF
-    << "Content-Type: application/x-thrift" << CRLF << "Content-Length: " << len << CRLF
-    << "Connection: Keep-Alive" << CRLF << CRLF;
-  string header = h.str();
+  string header = getHeader(len);
 
   // Write the header, then the data, then flush
   // cast should be fine, because none of "header" is under attacker control
@@ -142,6 +137,15 @@
   readHeaders_ = true;
 }
 
+std::string THttpServer::getHeader(uint32_t len) {
+  std::ostringstream h;
+  h << "HTTP/1.1 200 OK" << CRLF << "Date: " << getTimeRFC1123() << CRLF << "Server: Thrift/"
+    << PACKAGE_VERSION << CRLF << "Access-Control-Allow-Origin: *" << CRLF
+    << "Content-Type: application/x-thrift" << CRLF << "Content-Length: " << len << CRLF
+    << "Connection: Keep-Alive" << CRLF << CRLF;
+  return h.str();
+}
+
 std::string THttpServer::getTimeRFC1123() {
   static const char* Days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
   static const char* Months[]
diff --git a/lib/cpp/src/thrift/transport/THttpServer.h b/lib/cpp/src/thrift/transport/THttpServer.h
index 0e83399..d219691 100644
--- a/lib/cpp/src/thrift/transport/THttpServer.h
+++ b/lib/cpp/src/thrift/transport/THttpServer.h
@@ -35,6 +35,7 @@
   void flush() override;
 
 protected:
+  virtual std::string getHeader(uint32_t len);
   void readHeaders();
   void parseHeader(char* header) override;
   bool parseStatusLine(char* status) override;
diff --git a/lib/cpp/src/thrift/transport/TWebSocketServer.cpp b/lib/cpp/src/thrift/transport/TWebSocketServer.cpp
new file mode 100644
index 0000000..9822a7f
--- /dev/null
+++ b/lib/cpp/src/thrift/transport/TWebSocketServer.cpp
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <functional>
+#include <memory>
+#include <string>
+
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+
+#include <thrift/Thrift.h>
+
+using std::string;
+
+namespace apache {
+namespace thrift {
+namespace transport {
+
+std::string base64Encode(unsigned char* data, int length) {
+  std::unique_ptr<BIO, std::function<void(BIO*)>> base64(BIO_new(BIO_f_base64()),
+                                                         [](BIO* b) { BIO_free_all(b); });
+  BIO_set_flags(base64.get(), BIO_FLAGS_BASE64_NO_NL);
+
+  BIO* dest = BIO_new(BIO_s_mem());
+  BIO_push(base64.get(), dest);
+  BIO_write(base64.get(), data, length);
+  int ret = BIO_flush(base64.get());
+  THRIFT_UNUSED_VARIABLE(ret);
+
+  char* encoded;
+  length = BIO_get_mem_data(dest, &encoded);
+  return std::string(encoded, length);
+}
+} // namespace transport
+} // namespace thrift
+} // namespace apache
diff --git a/lib/cpp/src/thrift/transport/TWebSocketServer.h b/lib/cpp/src/thrift/transport/TWebSocketServer.h
new file mode 100644
index 0000000..8edc286
--- /dev/null
+++ b/lib/cpp/src/thrift/transport/TWebSocketServer.h
@@ -0,0 +1,416 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _THRIFT_TRANSPORT_TWEBSOCKETSERVER_H_
+#define _THRIFT_TRANSPORT_TWEBSOCKETSERVER_H_ 1
+
+#include <thrift/portable_endian.h>
+
+#include <cstdlib>
+#include <iostream>
+#include <sstream>
+
+#include <openssl/sha.h>
+
+#include <thrift/config.h>
+#include <thrift/transport/TSocket.h>
+#include <thrift/transport/THttpServer.h>
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#include <Shlwapi.h>
+#define THRIFT_strncasecmp(str1, str2, len) _strnicmp(str1, str2, len)
+#define THRIFT_strcasestr(haystack, needle) StrStrIA(haystack, needle)
+#else
+#define THRIFT_strncasecmp(str1, str2, len) strncasecmp(str1, str2, len)
+#define THRIFT_strcasestr(haystack, needle) strcasestr(haystack, needle)
+#endif
+#if defined(__CYGWIN__)
+#include <alloca.h>
+#endif
+
+using std::string;
+
+namespace apache {
+namespace thrift {
+namespace transport {
+
+std::string base64Encode(unsigned char* data, int length);
+
+template <bool binary>
+class TWebSocketServer : public THttpServer {
+public:
+  TWebSocketServer(std::shared_ptr<TTransport> transport)
+    : THttpServer(transport) {
+      resetHandshake();
+  }
+
+  ~TWebSocketServer() override = default;
+
+  uint32_t readAll_virt(uint8_t* buf, uint32_t len) override {
+    // If we do not have a good handshake, the client will attempt one.
+    if (!handshakeComplete()) {
+      resetHandshake();
+      THttpServer::read(buf, len);
+      // If we did not get everything we expected, the handshake failed
+      // and we need to send a 400 response back.
+      if (!handshakeComplete()) {
+        sendBadRequest();
+        return 0;
+      }
+      // Otherwise, send back the 101 response.
+      THttpServer::flush();
+    }
+
+    uint32_t want = len;
+    auto have = readBuffer_.available_read();
+
+    // If we have some data in the buffer, copy it out and return it.
+    // We have to return it without attempting to read more, since we aren't
+    // guaranteed that the underlying transport actually has more data, so
+    // attempting to read from it could block.
+    if (have > 0 && have >= want) {
+      return readBuffer_.read(buf, want);
+    }
+
+    // Read another frame.
+    if (!readFrame()) {
+      // EOF.  No frame available.
+      return 0;
+    }
+
+    // Hand over whatever we have.
+    uint32_t give = (std::min)(want, readBuffer_.available_read());
+    return readBuffer_.read(buf, give);
+  }
+
+  void flush() override {
+    writeFrameHeader();
+    uint8_t* buffer;
+    uint32_t length;
+    writeBuffer_.getBuffer(&buffer, &length);
+    transport_->write(buffer, length);
+    transport_->flush();
+    writeBuffer_.resetBuffer();
+  }
+
+protected:
+  std::string getHeader(uint32_t len) override {
+    THRIFT_UNUSED_VARIABLE(len);
+    std::ostringstream h;
+    h << "HTTP/1.1 101 Switching Protocols" << CRLF << "Server: Thrift/" << PACKAGE_VERSION << CRLF
+      << "Upgrade: websocket" << CRLF << "Connection: Upgrade" << CRLF
+      << "Sec-WebSocket-Accept: " << acceptKey_ << CRLF << CRLF;
+    return h.str();
+  }
+
+  void parseHeader(char* header) override {
+    char* colon = strchr(header, ':');
+    if (colon == nullptr) {
+      return;
+    }
+    size_t sz = colon - header;
+    char* value = colon + 1;
+
+    if (THRIFT_strncasecmp(header, "Upgrade", sz) == 0) {
+      if (THRIFT_strcasestr(value, "websocket") != nullptr) {
+        upgrade_ = true;
+      }
+    } else if (THRIFT_strncasecmp(header, "Connection", sz) == 0) {
+      if (THRIFT_strcasestr(value, "Upgrade") != nullptr) {
+        connection_ = true;
+      }
+    } else if (THRIFT_strncasecmp(header, "Sec-WebSocket-Key", sz) == 0) {
+      std::string toHash = value + 1;
+      toHash += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+      unsigned char hash[20];
+      SHA1((const unsigned char*)toHash.c_str(), toHash.length(), hash);
+      acceptKey_ = base64Encode(hash, 20);
+      secWebSocketKey_ = true;
+    } else if (THRIFT_strncasecmp(header, "Sec-WebSocket-Version", sz) == 0) {
+      if (THRIFT_strcasestr(value, "13") != nullptr) {
+        secWebSocketVersion_ = true;
+      }
+    }
+  }
+
+  bool parseStatusLine(char* status) override {
+    char* method = status;
+
+    char* path = strchr(method, ' ');
+    if (path == nullptr) {
+      throw TTransportException(string("Bad Status: ") + status);
+    }
+
+    *path = '\0';
+    while (*(++path) == ' ') {
+    };
+
+    char* http = strchr(path, ' ');
+    if (http == nullptr) {
+      throw TTransportException(string("Bad Status: ") + status);
+    }
+    *http = '\0';
+
+    if (strcmp(method, "GET") == 0) {
+      // GET method ok, looking for content.
+      return true;
+    }
+    throw TTransportException(string("Bad Status (unsupported method): ") + status);
+  }
+
+private:
+  enum class CloseCode : uint16_t {
+    NormalClosure = 1000,
+    GoingAway = 1001,
+    ProtocolError = 1002,
+    UnsupportedDataType = 1003,
+    NoStatusCode = 1005,
+    AbnormalClosure = 1006,
+    InvalidData = 1007,
+    PolicyViolation = 1008,
+    MessageTooBig = 1009,
+    ExtensionExpected = 1010,
+    UnexpectedError = 1011,
+    NotSecure = 1015
+  };
+
+  enum class Opcode : uint8_t {
+    Continuation = 0x0,
+    Text = 0x1,
+    Binary = 0x2,
+    Close = 0x8,
+    Ping = 0x9,
+    Pong = 0xA
+  };
+
+  void failConnection(CloseCode reason) {
+    writeFrameHeader(Opcode::Close);
+    auto buffer = htobe16(static_cast<uint16_t>(reason));
+    transport_->write(reinterpret_cast<const uint8_t*>(&buffer), 2);
+    transport_->flush();
+    transport_->close();
+  }
+
+  bool handshakeComplete() {
+    return upgrade_ && connection_ && secWebSocketKey_ && secWebSocketVersion_;
+  }
+
+  void pong() {
+    writeFrameHeader(Opcode::Pong);
+    uint8_t* buffer;
+    uint32_t size;
+    readBuffer_.getBuffer(&buffer, &size);
+    transport_->write(buffer, size);
+    transport_->flush();
+  }
+
+  bool readFrame() {
+    uint8_t headerBuffer[8];
+
+    auto read = transport_->read(headerBuffer, 2);
+    if (read < 2) {
+      return false;
+    }
+    // Since Thrift has its own message end marker and we read frame by frame,
+    // it doesn't really matter if the frame is marked as FIN.
+    // Capture it only for debugging only.
+    auto fin = (headerBuffer[0] & 0x80) != 0;
+    THRIFT_UNUSED_VARIABLE(fin);
+
+    // RSV1, RSV2, RSV3
+    if ((headerBuffer[0] & 0x70) != 0) {
+      failConnection(CloseCode::ProtocolError);
+      throw TTransportException(TTransportException::CORRUPTED_DATA,
+                                "Reserved bits must be zeroes");
+    }
+
+    auto opcode = (Opcode)(headerBuffer[0] & 0x0F);
+
+    // Mask
+    if ((headerBuffer[1] & 0x80) == 0) {
+      failConnection(CloseCode::ProtocolError);
+      throw TTransportException(TTransportException::CORRUPTED_DATA,
+                                "Messages from the client must be masked");
+    }
+
+    // Read the length
+    uint64_t payloadLength = headerBuffer[1] & 0x7F;
+    if (payloadLength == 126) {
+      read = transport_->read(headerBuffer, 2);
+      if (read < 2) {
+        return false;
+      }
+      payloadLength = be16toh(*reinterpret_cast<uint16_t*>(headerBuffer));
+    } else if (payloadLength == 127) {
+      read = transport_->read(headerBuffer, 8);
+      if (read < 8) {
+        return false;
+      }
+      payloadLength = be64toh(*reinterpret_cast<uint64_t*>(headerBuffer));
+      if ((payloadLength & 0x8000000000000000) != 0) {
+        failConnection(CloseCode::ProtocolError);
+        throw TTransportException(
+            TTransportException::CORRUPTED_DATA,
+            "The most significant bit of the payload length must be zero");
+      }
+    }
+
+    // size_t is smaller than a ulong on a 32-bit system
+    if (payloadLength > UINT32_MAX) {
+      failConnection(CloseCode::MessageTooBig);
+      return false;
+    }
+
+    auto length = static_cast<uint32_t>(payloadLength);
+
+    if (length > 0) {
+      // Read the masking key
+      read = transport_->read(headerBuffer, 4);
+      if (read < 4) {
+        return false;
+      }
+
+      readBuffer_.resetBuffer(length);
+      uint8_t* buffer = readBuffer_.getWritePtr(length);
+      read = transport_->read(buffer, length);
+      readBuffer_.wroteBytes(read);
+      if (read < length) {
+        return false;
+      }
+      
+      // Unmask the data
+      for (size_t i = 0; i < length; i++) {
+        buffer[i] ^= headerBuffer[i % 4];
+      }
+
+      T_DEBUG("FIN=%d, Opcode=%X, length=%d, payload=%s", fin, opcode, length,
+              binary ? readBuffer_.toHexString() : cast(string) readBuffer_);
+    }
+
+    switch (opcode) {
+    case Opcode::Close:
+      if (length >= 2) {
+        uint8_t buffer[2];
+        readBuffer_.read(buffer, 2);
+        CloseCode closeCode = static_cast<CloseCode>(be16toh(*reinterpret_cast<uint16_t*>(buffer)));
+        THRIFT_UNUSED_VARIABLE(closeCode);
+        string closeReason = readBuffer_.readAsString(length - 2);
+        T_DEBUG("Connection closed: %d %s", closeCode, closeReason);
+      }
+      transport_->close();
+      return false;
+    case Opcode::Ping:
+      pong();
+      return readFrame();
+    default:
+      return true;
+    }
+  }
+
+  void resetHandshake() {
+    connection_ = false;
+    secWebSocketKey_ = false;
+    secWebSocketVersion_ = false;
+    upgrade_ = false;
+  }
+
+  void sendBadRequest() {
+    std::ostringstream h;
+    h << "HTTP/1.1 400 Bad Request" << CRLF << "Server: Thrift/" << PACKAGE_VERSION << CRLF << CRLF;
+    std::string header = h.str();
+    transport_->write(reinterpret_cast<const uint8_t*>(header.data()), static_cast<uint32_t>(header.length()));
+    transport_->flush();
+    transport_->close();
+  }
+
+  void writeFrameHeader(Opcode opcode = Opcode::Continuation) {
+    uint32_t headerSize = 1;
+    uint32_t length = writeBuffer_.available_read();
+    if (length < 126) {
+      ++headerSize;
+    } else if (length < 65536) {
+      headerSize += 3;
+    } else {
+      headerSize += 9;
+    }
+    // The server does not mask the response
+
+    uint8_t* header = static_cast<uint8_t*>(alloca(headerSize));
+    if (opcode == Opcode::Continuation) {
+      opcode = binary ? Opcode::Binary : Opcode::Text;
+    }
+    header[0] = static_cast<uint8_t>(opcode) | 0x80;
+    if (length < 126) {
+      header[1] = static_cast<uint8_t>(length);
+    } else if (length < 65536) {
+      header[1] = 126;
+      *reinterpret_cast<uint16_t*>(header + 2) = htobe16(length);
+    } else {
+      header[1] = 127;
+      *reinterpret_cast<uint64_t*>(header + 2) = htobe64(length);
+    }
+
+    transport_->write(header, headerSize);
+  }
+
+  // Add constant here to avoid a linker error on Windows
+  constexpr static const char* CRLF = "\r\n";
+  std::string acceptKey_;
+  bool connection_;
+  bool secWebSocketKey_;
+  bool secWebSocketVersion_;
+  bool upgrade_;
+};
+
+/**
+ * Wraps a transport into binary WebSocket protocol
+ */
+class TBinaryWebSocketServerTransportFactory : public TTransportFactory {
+public:
+  TBinaryWebSocketServerTransportFactory() = default;
+
+  ~TBinaryWebSocketServerTransportFactory() override = default;
+
+  /**
+   * Wraps the transport into a buffered one.
+   */
+  std::shared_ptr<TTransport> getTransport(std::shared_ptr<TTransport> trans) override {
+    return std::shared_ptr<TTransport>(new TWebSocketServer<true>(trans));
+  }
+};
+
+/**
+ * Wraps a transport into text WebSocket protocol
+ */
+class TTextWebSocketServerTransportFactory : public TTransportFactory {
+public:
+  TTextWebSocketServerTransportFactory() = default;
+
+  ~TTextWebSocketServerTransportFactory() override = default;
+
+  /**
+   * Wraps the transport into a buffered one.
+   */
+  std::shared_ptr<TTransport> getTransport(std::shared_ptr<TTransport> trans) override {
+    return std::shared_ptr<TTransport>(new TWebSocketServer<false>(trans));
+  }
+};
+} // namespace transport
+} // namespace thrift
+} // namespace apache
+#endif
