upgrade.inc (18445B)
1 HTTP is a request/response protocol: the client asks, the server 2 answers, and the connection is either closed or reused for the next 3 request. Some applications need something else entirely --- a 4 bidirectional byte stream that neither side has to poll for. Rather 5 than opening a second connection on another port, @emph{RFC 9110} lets 6 a client ask the server to switch the already established connection 7 over to a different protocol. The client sends an ordinary request 8 carrying an @code{Upgrade:} header field, and if the server agrees it 9 answers with the status code @code{101 Switching Protocols}. Once 10 that response has gone out, HTTP is over: the two sides simply talk 11 whatever protocol they agreed on over the same TCP connection. 12 13 Since version 0.9.52 @emph{libmicrohttpd} supports this protocol 14 switch. The API is deliberately protocol-agnostic --- @emph{MHD} 15 performs the HTTP part of the handshake and then hands you the socket. 16 What you send over that socket afterwards is entirely your business; 17 @emph{MHD} neither parses nor generates a single byte of it any more. 18 19 The best known user of this mechanism is the Websocket protocol 20 (@emph{RFC 6455}), which uses the upgrade API as a means to an end and 21 then needs a good deal of machinery of its own for framing, masking 22 and the closing handshake. This chapter takes the opposite approach: 23 it shows the upgrade API on its own, with a protocol so simple that no 24 helper library is needed. Our server switches to a line-based echo 25 protocol: every line the client sends is sent straight back, until the 26 client sends the line @code{QUIT}. 27 28 @heading Enabling upgrades 29 30 Upgrading is not allowed by default, because handing raw sockets to 31 application code has consequences the library cannot control. You opt 32 in with the @code{MHD_ALLOW_UPGRADE} flag: 33 34 @verbatim 35 daemon = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | 36 MHD_USE_INTERNAL_POLLING_THREAD | 37 MHD_ALLOW_UPGRADE | 38 MHD_USE_ERROR_LOG, 39 PORT, NULL, NULL, 40 &access_handler, NULL, 41 MHD_OPTION_END); 42 @end verbatim 43 @noindent 44 45 The choice of threading mode matters more here than anywhere else in 46 this tutorial, because it decides whether your code is allowed to 47 block. 48 49 With @code{MHD_USE_THREAD_PER_CONNECTION} every connection already has 50 a thread of its own, and that thread is the one that will run your 51 upgrade callback. Blocking in it stalls exactly one client, so you 52 may write the straightforward loop of @code{recv()} and @code{send()} 53 calls that everybody has in their head. This is what makes the 54 example in this chapter short enough to read in one go. 55 56 Without it --- that is, with a single internal polling thread, a 57 thread pool, epoll, or an external event loop --- your callback runs 58 @emph{inside} @emph{MHD}'s event loop. Blocking there freezes every 59 other connection the same loop is serving. In that case the callback 60 must return immediately, and you have to register the socket in your 61 own event loop (or hand it to a thread you started yourself) and drive 62 the conversation from there. 63 64 @heading Deciding whether to upgrade 65 66 A client that wants to switch protocols says so twice: it names the 67 protocol in the @code{Upgrade:} header field, and it lists the token 68 @code{Upgrade} in the @code{Connection:} header field. Both fields 69 are comma-separated lists, so a browser may well send 70 @code{Connection: keep-alive, Upgrade}. Comparing the whole field 71 value against the string @code{"Upgrade"} would reject such a request; 72 the example therefore contains a small helper @code{has_token()} that 73 walks the list. Note also that a protocol switch is a HTTP/1.1 74 feature; @code{MHD_queue_response()} will refuse an upgrade response 75 on a HTTP/1.0 connection. 76 77 @verbatim 78 if ( (0 != strcmp (method, MHD_HTTP_METHOD_GET)) || 79 (0 != strcmp (version, MHD_HTTP_VERSION_1_1)) || 80 (! has_token (MHD_lookup_connection_value (connection, 81 MHD_HEADER_KIND, 82 MHD_HTTP_HEADER_CONNECTION), 83 "Upgrade")) || 84 (! has_token (MHD_lookup_connection_value (connection, 85 MHD_HEADER_KIND, 86 MHD_HTTP_HEADER_UPGRADE), 87 PROTOCOL)) ) 88 return answer_plain (connection, 89 MHD_HTTP_UPGRADE_REQUIRED, 90 PAGE_UPGRADE_REQUIRED, 91 1); 92 @end verbatim 93 @noindent 94 95 Refusing is not an error condition: the client asked a question and 96 gets an ordinary HTTP answer. Which answer depends on who is at 97 fault. If the request is malformed --- for instance an 98 @code{Upgrade:} field without the matching @code{Connection:} token 99 --- @code{MHD_HTTP_BAD_REQUEST} is appropriate. If the request is 100 perfectly well-formed but simply does not speak the protocol this 101 resource requires, @code{MHD_HTTP_UPGRADE_REQUIRED} (426) is the 102 better answer, and it should carry an @code{Upgrade:} header field 103 naming the protocol the server would have accepted. Our example 104 folds both cases into a 426 for brevity. Either way you queue a 105 perfectly normal response and the connection stays a HTTP connection. 106 107 @heading Creating the upgrade response 108 109 If we do want to switch, we create a special response object with 110 @code{MHD_create_response_for_upgrade()}. It takes the callback that 111 will receive the socket and a closure pointer for it, and returns 112 @code{NULL} on error. The response has no body --- it is a header and 113 nothing else. 114 115 @verbatim 116 response = MHD_create_response_for_upgrade (&upgrade_handler, 117 NULL); 118 if (NULL == response) 119 return MHD_NO; 120 MHD_add_response_header (response, 121 MHD_HTTP_HEADER_UPGRADE, 122 PROTOCOL); 123 ret = MHD_queue_response (connection, 124 MHD_HTTP_SWITCHING_PROTOCOLS, 125 response); 126 MHD_destroy_response (response); 127 return ret; 128 @end verbatim 129 @noindent 130 131 Two details are easy to get wrong here. 132 133 The first is the @code{Connection: Upgrade} response header field, and 134 the surprise is that you must @emph{not} add it. 135 @code{MHD_create_response_for_upgrade()} puts it into the response 136 itself, and @code{MHD_queue_response()} then verifies that it is still 137 there and still contains the @code{upgrade} token before it accepts 138 the response. @emph{MHD} does merge repeated @code{Connection:} 139 header fields into a single field rather than emitting two of them, 140 but it only de-duplicates the @code{close} token, so adding 141 @code{Upgrade} a second time puts @code{Connection: Upgrade, Upgrade} 142 on the wire. Clients tolerate that, but there is no reason to send 143 it. 144 145 What @emph{MHD} does @emph{not} invent for you is the @code{Upgrade:} 146 field naming the new protocol --- that one is yours to add, since only 147 you know what you are switching to. Do not forget it: 148 @code{MHD_queue_response()} does not check for it, so in a normal 149 build the client simply receives a 101 that fails to say what it 150 switched to, while a library built with assertions enabled aborts when 151 it performs the switch. 152 153 The second is the status code. @code{MHD_queue_response()} rejects an 154 upgrade response with any status other than 155 @code{MHD_HTTP_SWITCHING_PROTOCOLS}, and conversely it rejects status 156 101 combined with a response that is not an upgrade response. On any 157 of these mistakes it returns @code{MHD_NO} and, with 158 @code{MHD_USE_ERROR_LOG} enabled, explains itself on @code{stderr}; 159 this is by far the quickest way to debug a handshake that does not 160 happen. 161 162 The response object itself follows the usual rules. 163 @code{MHD_queue_response()} takes its own reference, so calling 164 @code{MHD_destroy_response()} immediately afterwards is correct and is 165 what all the other examples in this tutorial do. The object is only 166 really freed once the last connection using it is done with it, which 167 for an upgrade means after the callback has returned. As with any 168 other response you may build one upgrade response and queue it for 169 many connections; the callback is then simply invoked once per 170 connection. 171 172 @heading The upgrade callback 173 174 After the 101 response has been written to the socket, @emph{MHD} 175 calls the @code{MHD_UpgradeHandler} you registered: 176 177 @verbatim 178 static void 179 upgrade_handler (void *cls, 180 struct MHD_Connection *connection, 181 void *req_cls, 182 const char *extra_in, 183 size_t extra_in_size, 184 MHD_socket sock, 185 struct MHD_UpgradeResponseHandle *urh) 186 @end verbatim 187 @noindent 188 189 @table @code 190 @item cls 191 The closure that was passed to 192 @code{MHD_create_response_for_upgrade()}. Since the same response 193 object may serve many connections, this is per-@emph{response} state, 194 not per-connection state. 195 196 @item connection 197 The original HTTP connection. It is handed over so that you can have 198 a last look at the request --- @code{MHD_lookup_connection_value()} 199 still works here, which is how a real protocol picks up, say, a 200 subprotocol name or an authentication token. Do not queue anything on 201 it any more. 202 203 @item req_cls 204 Whatever your access handler left in @code{*req_cls}. This is the 205 natural place to put per-connection state that the access handler 206 already computed. 207 208 @item extra_in / extra_in_size 209 Bytes of your new protocol that the client sent immediately behind the 210 request header, and that @emph{MHD} therefore already read off the 211 socket while parsing the request. They are @emph{gone} from the 212 socket: if you go straight to @code{recv()} you silently lose them. 213 Process this buffer first, exactly as if you had read it yourself. 214 The buffer belongs to @emph{MHD} and is only valid for the duration of 215 the call, so copy anything you want to keep. A client that waits for 216 the 101 before it starts talking will produce 217 @code{extra_in_size == 0}, which is why this argument is so easy to 218 overlook and so annoying when it finally bites. 219 220 @item sock 221 The socket. For a plain HTTP connection this is the connection to the 222 client; for HTTPS it is one end of a socketpair with @emph{MHD} 223 relaying the TLS traffic, so socket options and @code{getpeername()} 224 will not give you what you expect. Read and write it as you please, 225 and you may call @code{shutdown()} on it, but you must never call 226 @code{close()}. 227 228 @item urh 229 The handle for @code{MHD_upgrade_action()}, described below. 230 @end table 231 232 The loop itself is then unremarkable, apart from consuming 233 @code{extra_in} before the first @code{recv()}: 234 235 @verbatim 236 make_blocking (sock); 237 es.line_len = 0; 238 done = echo_feed (sock, &es, extra_in, extra_in_size); 239 while (0 == done) 240 { 241 got = recv (sock, buf, sizeof (buf), 0); 242 if (0 > got) 243 { 244 if (EINTR == errno) 245 continue; 246 break; /* read error */ 247 } 248 if (0 == got) 249 break; /* client closed the connection */ 250 done = echo_feed (sock, &es, buf, (size_t) got); 251 } 252 MHD_upgrade_action (urh, 253 MHD_UPGRADE_ACTION_CLOSE); 254 @end verbatim 255 @noindent 256 257 @heading Blocking or not blocking 258 259 The call to @code{make_blocking()} deserves a warning, because the 260 current behaviour is the opposite of what the threading modes suggest. 261 @emph{MHD} puts every accepted client socket into non-blocking mode, 262 and it does so regardless of the threading mode --- in fact the 263 library refuses to perform the switch at all, logging @code{Cannot 264 execute "upgrade" as the socket is in the blocking mode}, if it finds 265 the socket blocking. So even under 266 @code{MHD_USE_THREAD_PER_CONNECTION}, where you are perfectly entitled 267 to block, the socket you are handed is non-blocking and a 268 @code{recv()} on an idle connection returns @code{-1} with 269 @code{EAGAIN} instead of waiting. 270 271 If you want the simple blocking loop shown above, you therefore have 272 to ask for it. The example does so with a small 273 @code{make_blocking()} helper --- @code{fcntl()} clearing 274 @code{O_NONBLOCK} on POSIX systems, @code{ioctlsocket()} on W32 --- 275 which is the only operating-system-dependent code in the whole 276 program. 277 278 Under any other threading mode you leave the socket alone, keep it 279 non-blocking, and add it to your own event loop instead. 280 281 @heading Closing the connection 282 283 The last obligation of the callback is to hand the socket back: 284 285 @verbatim 286 MHD_upgrade_action (urh, 287 MHD_UPGRADE_ACTION_CLOSE); 288 @end verbatim 289 @noindent 290 291 This is not a formality. An upgraded connection is put into an 292 internal ``suspended'' state, and it stays there --- socket open, 293 connection structure allocated, slot counted against the connection 294 limit --- until the application says it is done. Only 295 @code{MHD_UPGRADE_ACTION_CLOSE} says that. Calling @code{close()} on 296 the socket yourself does not, and additionally leaves @emph{MHD} 297 holding a file descriptor number that the operating system may already 298 have handed to somebody else. Call the action exactly once, on every 299 path out of the callback, including the error paths. 300 301 @code{MHD_upgrade_action()} takes two further actions in the current 302 release, @code{MHD_UPGRADE_ACTION_CORK_ON} and 303 @code{MHD_UPGRADE_ACTION_CORK_OFF}. They switch @code{TCP_CORK} (or 304 @code{TCP_NOPUSH}) on the underlying socket so that several small 305 writes can be coalesced into a single segment. They are a hint, not a 306 guarantee: the call returns @code{MHD_NO} if the platform has no such 307 option or if the socket is not a TCP socket, which is the normal case 308 for HTTPS connections. The header file marks this part of the API as 309 not yet finalised, so do not build anything load-bearing on it. 310 311 @heading Remarks 312 313 @code{MHD_stop_daemon()} does @emph{not} interrupt an upgraded 314 connection. It marks the connection as closed internally and logs 315 @code{Initiated daemon shutdown while "upgraded" connection was not 316 closed}, but it neither shuts down nor closes the socket --- and then 317 it waits for the connection's thread, which means it blocks until your 318 callback has returned. A callback parked in a blocking @code{recv()} 319 therefore hangs the shutdown for as long as the client keeps the 320 connection open. Any server that wants to terminate on demand needs 321 its own way out of that loop: a global shutdown flag combined with a 322 @code{shutdown()} on the sockets you are holding, a self-pipe added to 323 a @code{select()} in the loop, or a receive timeout on the socket. 324 Our example sidesteps the problem by only stopping the daemon when the 325 user presses return at a moment when nothing is connected. 326 327 Error handling in the callback is entirely yours. @emph{MHD} will not 328 tell you that a client vanished and will not time an upgraded 329 connection out --- @code{MHD_OPTION_CONNECTION_TIMEOUT} stops applying 330 the moment the connection is upgraded. Treat @code{0} from 331 @code{recv()} as a clean disconnect and a negative return as a broken 332 one, and remember that a peer which disappears without a FIN produces 333 neither until the TCP stack gives up, which can take a very long time. 334 Whatever happens, end by calling @code{MHD_upgrade_action()} with 335 @code{MHD_UPGRADE_ACTION_CLOSE}. 336 337 Finally, keep in mind that an upgraded connection is a connection that 338 @emph{MHD} can no longer recycle, and that intermediaries are entitled 339 to be unhelpful: @code{Upgrade:} is listed in @code{Connection:} and 340 is therefore a hop-by-hop header field. A proxy that does not 341 understand your protocol is allowed to drop it, in which case your 342 server never sees an upgrade request at all and the client gets an 343 ordinary HTTP response where it expected a 101. This is the main 344 reason why deployed protocols on top of this mechanism --- Websockets 345 above all --- make the handshake verifiable by both ends instead of 346 trusting that the request arrived intact. 347 348 The complete program is available as @code{upgrade.c} in the 349 @code{examples} section. Start it and talk to it with any tool that 350 lets you type raw bytes at a socket --- @code{telnet localhost 8888} 351 will do --- by sending 352 353 @verbatim 354 GET / HTTP/1.1 355 Host: localhost 356 Connection: Upgrade 357 Upgrade: echo 358 359 @end verbatim 360 @noindent 361 362 followed by an empty line. The server answers with 363 364 @verbatim 365 HTTP/1.1 101 Switching Protocols 366 Date: ... 367 Connection: Upgrade 368 Upgrade: echo 369 370 @end verbatim 371 @noindent 372 373 and from then on echoes every line back until you type @code{QUIT}. 374 Note the absence of a @code{Content-Length:} field: a 101 response has 375 no body, and everything after the empty line already belongs to the 376 new protocol. 377 378 For a real-world protocol built on exactly this API, read 379 @emph{RFC 6455} and note how much of it exists only to make the 380 handshake and the framing verifiable --- none of which the upgrade API 381 itself has an opinion about. 382 383 @heading Exercises 384 385 @itemize @bullet 386 387 @item 388 Point a browser at the server. The browser sends a plain @code{GET /} 389 and receives the @code{426} page. Now add a second resource that 390 serves a small HTML page and switch the upgrade to a different URL, so 391 that the same server can be both browsed and upgraded. 392 393 @item 394 Make the echo server useful: keep a list of the sockets of all 395 upgraded connections and forward every line one client sends to all 396 the others, turning the example into a minimal chat server. You will 397 need a mutex around the list, and you will discover why the closing 398 rules matter --- a socket must leave the list before its callback 399 returns. 400 401 @item 402 Fix the shutdown behaviour discussed in the remarks. Add a global 403 ``quitting'' flag and a list of active sockets, have @code{main()} set 404 the flag and call @code{shutdown (sock, SHUT_RDWR)} on every entry 405 before it calls @code{MHD_stop_daemon()}, and verify that the daemon 406 now stops even while a client is connected and silent. 407 408 @item 409 Change the daemon flags to plain 410 @code{MHD_USE_INTERNAL_POLLING_THREAD} without 411 @code{MHD_USE_THREAD_PER_CONNECTION} and observe that the server now 412 serves exactly one upgraded client and stops answering everybody else. 413 Then repair it: leave the socket non-blocking, start a thread from 414 within the callback, and return immediately. 415 416 @item 417 Have the client send a line longer than @code{LINE_SIZE}. The example 418 silently drops the excess. What should a real protocol do instead, 419 and which status code would you have used if the problem had been 420 detectable during the handshake? 421 422 @end itemize