1[/ 2 Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) 3 4 Distributed under the Boost Software License, Version 1.0. (See accompanying 5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 7 Official repository: https://github.com/boostorg/beast 8] 9 10[section FAQ] 11 12To set realistic expectations and prevent a litany of duplicate review 13statements, these notes address the most common questions and comments 14about Beast and other HTTP libraries that have gone through formal review. 15 16[variablelist 17[[ 18 "Beast requires too much user code to do anything!" 19][ 20 It is not the intention of the library to provide turn-key 21 solutions for specific HTTP or WebSocket use-cases. 22 Instead, it is a sensible protocol layering on top of 23 Boost.Asio which retains the Boost.Asio memory 24 management style and asynchronous model. 25]] 26[[ 27 "Beast does not offer an HTTP server?" 28][ 29 Beast has a functional HTTP server in the example directory. The 30 server supports both HTTP and WebSocket using synchronous and 31 asynchronous shared or dedicated ports. In addition, the server 32 supports encrypted TLS connections if OpenSSL is available, on 33 dedicated ports. And the server comes with a "multi-port", a 34 flexible single port which supports both encrypted and unencrypted 35 connections, both HTTP and WebSocket, all on the same port. The 36 server is not part of Beast's public interfaces, as that 37 functionality is outside the scope of the library. The author 38 feels that attempting to broaden the scope of the library will 39 reduce its appeal for standardization. 40]] 41[[ 42 "Beast does not offer an HTTP client?" 43][ 44 "I just want to download a resource using HTTP" is a common 45 cry from users and reviewers. Such functionality is beyond 46 the scope of Beast. Building a full featured HTTP client is 47 a difficult task and large enough to deserve its own library. 48 There are many things to deal with such as the various message 49 body encodings, complex parsing of headers, difficult header 50 semantics such as Range and Cache-Control, redirection, 51 Expect:100-continue, connection retrying, domain name 52 resolution, TLS, and much, much more. It is the author's 53 position that Boost first needs a common set of nouns and 54 verbs for manipulating HTTP at the protocol level; Beast 55 provides that language. 56]] 57[[ 58 "There's no HTTP/2 support yet!" 59][ 60 Many reviewers feel that HTTP/2 support is an essential feature of 61 a HTTP library. The authors agree that HTTP/2 is important but also 62 feel that the most sensible implementation is one that does not re-use 63 the same network reading and writing interface for 2 as that for 1.0 64 and 1.1. 65 66 The Beast HTTP message model was designed with the new protocol 67 in mind and should be evaluated in that context. There are plans 68 to add HTTP/2 in the future, but there is no rush to do so. 69 Users can work with HTTP/1 now; we should not deny them that 70 functionality today to wait for a newer protocol tomorrow. 71 It is the author's position that there is sufficient value in 72 Beast's HTTP/1-only implementation that the lack of HTTP/2 73 should not be a barrier to acceptance. 74 75 The Beast HTTP message model is suitable for HTTP/2 and can be re-used. 76 The IETF HTTP Working Group adopted message compatibility with HTTP/1.x 77 as an explicit goal. A parser can simply emit full headers after 78 decoding the compressed HTTP/2 headers. The stream ID is not logically 79 part of the message but rather message metadata and should be 80 communicated out-of-band (see below). HTTP/2 sessions begin with a 81 traditional HTTP/1.1 Upgrade similar in fashion to the WebSocket 82 upgrade. An HTTP/2 implementation can use existing Beast.HTTP primitives 83 to perform this handshake. 84]] 85[[ 86 "This should work with standalone-Asio!" 87][ 88 Beast uses more than Boost.Asio, it depends on various other parts 89 of Boost. The standalone Asio is currently farther ahead than the 90 Boost version. Keeping Beast maintained against both versions of 91 Asio is beyond the resources of the author at the present time. 92 Compatibility with non-Boost libraries should not be an acceptance 93 criteria. Beast is currently designed to be a part of Boost: 94 nothing more, nothing less. Looking at the bigger picture, it 95 is the author's goal to propose this library for standardization. 96 A logical track for achieving this is as follows: 97 98 [ordered_list 99 [ 100 Boost library acceptance. 101 ][ 102 Port to the Boost.Asio version of Networking-TS (This has to wait 103 until Boost's version of Asio is updated). 104 ][ 105 Wait for Networking-TS to become an official part of C++. 106 ][ 107 Port to the standard library versions of networking (gcc, clang, msvc). 108 ][ 109 Develop proposed language (This can happen concurrently with steps 3 and 4) 110 ]] 111]] 112[[ 113 "You need benchmarks!" 114][ 115 The energy invested in Beast went into the design of the interfaces, 116 not performance. That said, the most sensitive parts of Beast have 117 been optimized or designed with optimization in mind. The slow parts 118 of WebSocket processing have been optimized, and the HTTP parser design 119 is lifted from another extremely popular project which has performance 120 as a design goal (see [@https://github.com/h2o/picohttpparser]). 121 122 From: [@http://www.boost.org/development/requirements.html] 123 124 "Aim first for clarity and correctness; optimization should 125 be only a secondary concern in most Boost libraries." 126 127 As the library matures it will undergo optimization passes; benchmarks 128 will logically accompany this process. There is a small benchmarking 129 program included in the tests which compares the performance of 130 Beast's parser to the NodeJS reference parser, as well as some 131 benchmarks which compare the performance of various Beast dynamic 132 buffer implementations against Asio's. 133]] 134[[ 135 "Beast is a terrible name!" 136][ 137 The name "Boost.Http" or "Boost.WebSocket" would mislead users into 138 believing they could perform an HTTP request on a URL or put up a 139 WebSocket client or server in a couple of lines of code. Where 140 would the core utilities go? Very likely it would step on the 141 owner of Boost.Asio's toes to put things in the boost/asio 142 directory; at the very least, it would create unrequested, 143 additional work for the foreign repository. 144 145 "Beast" is sufficiently vague as to not suggest any particular 146 functionality, while acting as a memorable umbrella term for a 147 family of low level containers and algorithms. People in the know 148 or with a need for low-level network protocol operations will 149 have no trouble finding it, and the chances of luring a novice 150 into a bad experience are greatly reduced. 151 There is precedent for proper names: "Hana", "Fusion", "Phoenix", 152 and "Spirit" come to mind. Is "Beast" really any worse than say, 153 "mp11" for example? 154 Beast also already has a growing body of users and attention from 155 the open source community, the name Beast comes up in reddit posts 156 and StackOverflow as the answer to questions about which HTTP or 157 WebSocket library to use. 158]] 159 160 161 162[[ 163 "Some more advanced examples, e.g. including TLS with client/server 164 certificates would help." 165][ 166 The server-framework example demonstrates how to implement a server 167 that supports TLS using certificates. There are also websocket and 168 HTTP client examples which use TLS. Furthermore, management of 169 certificates is beyond the scope of the public interfaces of the 170 library. Asio already provides documentation, interfaces, and 171 examples for performing these tasks - Beast does not intend to 172 reinvent them or to redundantly provide this information. 173]] 174 175[[ 176 "A built-in HTTP router?" 177][ 178 We presume this means a facility to match expressions against the URI 179 in HTTP requests, and dispatch them to calling code. The authors feel 180 that this is a responsibility of higher level code. Beast does 181 not try to offer a web server. That said, the server-framework 182 example has a concept of request routing called a Service. Two 183 services are provided, one for serving files and the other for 184 handling WebSocket upgrade requests. 185]] 186 187[[ 188 "HTTP Cookies? Forms/File Uploads?" 189][ 190 Cookies, or managing these types of HTTP headers in general, is the 191 responsibility of higher levels. Beast just tries to get complete 192 messages to and from the calling code. It deals in the HTTP headers just 193 enough to process the message body and leaves the rest to callers. However, 194 for forms and file uploads the symmetric interface of the message class 195 allows HTTP requests to include arbitrary body types including those needed 196 to upload a file or fill out a form. 197]] 198 199[[ 200 "...supporting TLS (is this a feature? If not this would be a show-stopper), 201 etc." 202][ 203 Beast works with the Stream concept, so it automatically works with the 204 `boost::asio::ssl::stream` that you have already set up through Asio. 205]] 206 207[[ 208 "There should also be more examples of how to integrate the http service 209 with getting files from the file system, generating responses CGI-style" 210][ 211 The design goal for the library is to not try to invent a web server. 212 We feel that there is a strong need for a basic implementation that 213 models the HTTP message and provides functions to send and receive them 214 over Asio. Such an implementation should serve as a building block upon 215 which higher abstractions such as the aforementioned HTTP service or 216 cgi-gateway can be built. 217 218 There are several HTTP servers in the example directory which deliver 219 files, as well as some tested and compiled code snippets which can be 220 used as a starting point for interfacing with other processes. 221]] 222 223[[ 224 "You should send a 100-continue to ask for the rest of the body if required." 225][ 226 Deciding on whether to send the "Expect: 100-continue" header or 227 how to handle it on the server side is the caller's responsibility; 228 Beast provides the functionality to send or inspect the header before 229 sending or reading the body. 230]] 231 232 233 234[[ 235 "I would also like to see instances of this library being used 236 in production. That would give some evidence that the design 237 works in practice." 238][ 239 Beast has already been on public servers receiving traffic and handling 240 hundreds of millions of dollars' worth of financial transactions daily. 241 The servers run [*rippled], open source software 242 ([@https://github.com/ripple/rippled repository]) 243 implementing the 244 [@https://ripple.com/files/ripple_consensus_whitepaper.pdf [*Ripple Consensus Protocol]], 245 technology provided by [@http://ripple.com Ripple]. 246 247 Furthermore, the repository has grown significantly in popularity in 248 2017. There are many users, and some of them participate directly in 249 the repository by reporting issues, performing testing, and in some 250 cases submitting pull requests with code contributions. 251]] 252 253 254 255[[ 256 What about WebSocket message compression? 257][ 258 Beast WebSocket supports the permessage-deflate extension described in 259 [@https://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-00 draft-ietf-hybi-permessage-compression-00]. 260 The library comes with a header-only, C++11 port of ZLib's "deflate" codec 261 used in the implementation of the permessage-deflate extension. 262]] 263[[ 264 Where is the WebSocket TLS/SSL interface? 265][ 266 The `websocket::stream` wraps the socket or stream that you provide 267 (for example, a `boost::asio::ip::tcp::socket` or a 268 `boost::asio::ssl::stream`). You establish your TLS connection using the 269 interface on `ssl::stream` like shown in all of the Asio examples, then 270 construct your `websocket::stream` around it. It works perfectly fine; 271 Beast comes with an `ssl_stream` wrapper in the example directory which 272 allows the SSL stream to be moved, overcoming an Asio limitation. 273 274 The WebSocket implementation [*does] provide support for shutting down 275 the TLS connection through the use of the ADL compile-time virtual functions 276 [link beast.ref.boost__beast__websocket__teardown `teardown`] and 277 [link beast.ref.boost__beast__websocket__async_teardown `async_teardown`]. These will 278 properly close the connection as per rfc6455 and overloads are available 279 for TLS streams. Callers may provide their own overloads of these functions 280 for user-defined next layer types. 281]] 282[[ 283 Windows and OpenSSL: How do I install and build with OpenSSL on Microsoft Windows? 284][ 285 An easy method is to use command-line package installers chocolatey or scoop. Examples: 286 "choco install -y openssl --x86 --version 1.1.1.700" or 287 "scoop install openssl@1.1.1g -a 32bit -g" 288 289 If you've installed OpenSSL to a directory with spaces in the name, it's often 290 preferable to create a symbolic link so that you may use a simpler path, such as: 291 292 mklink /D "OpenSSL" "Program Files (x86)\\OpenSSL-Win32" 293 294 Set the environment variable OPENSSL_ROOT to the location of the new install: 295 296 set OPENSSL_ROOT=C:/OpenSSL 297 298 Then, proceed to build. Refer to beast/.dockers/windows-vs-32/Dockerfile for an example of building the test cases with OpenSSL. 299]] 300] 301 302[endsect] 303