1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061
|
<pre>Internet Engineering Task Force (IETF) S. Loreto
Request for Comments: 6202 Ericsson
Category: Informational P. Saint-Andre
ISSN: 2070-1721 Cisco
S. Salsano
University of Rome "Tor Vergata"
G. Wilkins
Webtide
April 2011
<span class="h1">Known Issues and Best Practices</span>
<span class="h1">for the Use of Long Polling and Streaming in Bidirectional HTTP</span>
Abstract
On today's Internet, the Hypertext Transfer Protocol (HTTP) is often
used (some would say abused) to enable asynchronous, "server-
initiated" communication from a server to a client as well as
communication from a client to a server. This document describes
known issues and best practices related to such "bidirectional HTTP"
applications, focusing on the two most common mechanisms: HTTP long
polling and HTTP streaming.
Status of This Memo
This document is not an Internet Standards Track specification; it is
published for informational purposes.
This document is a product of the Internet Engineering Task Force
(IETF). It represents the consensus of the IETF community. It has
received public review and has been approved for publication by the
Internet Engineering Steering Group (IESG). Not all documents
approved by the IESG are a candidate for any level of Internet
Standard; see <a href="./rfc5741#section-2">Section 2 of RFC 5741</a>.
Information about the current status of this document, any errata,
and how to provide feedback on it may be obtained at
<a href="http://www.rfc-editor.org/info/rfc6202">http://www.rfc-editor.org/info/rfc6202</a>.
<span class="grey">Loreto, et al. Informational [Page 1]</span></pre>
<hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-2" ></span>
<span class="grey"><a href="./rfc6202">RFC 6202</a> Bidirectional HTTP April 2011</span>
Copyright Notice
Copyright (c) 2011 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to <a href="https://www.rfc-editor.org/bcp/bcp78">BCP 78</a> and the IETF Trust's Legal
Provisions Relating to IETF Documents
(<a href="http://trustee.ietf.org/license-info">http://trustee.ietf.org/license-info</a>) in effect on the date of
publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect
to this document. Code Components extracted from this document must
include Simplified BSD License text as described in Section 4.e of
the Trust Legal Provisions and are provided without warranty as
described in the Simplified BSD License.
Table of Contents
<a href="#section-1">1</a>. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-3">3</a>
<a href="#section-2">2</a>. HTTP Long Polling . . . . . . . . . . . . . . . . . . . . . . <a href="#page-4">4</a>
<a href="#section-2.1">2.1</a>. Definition . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-4">4</a>
<a href="#section-2.2">2.2</a>. HTTP Long Polling Issues . . . . . . . . . . . . . . . . . <a href="#page-5">5</a>
<a href="#section-3">3</a>. HTTP Streaming . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-7">7</a>
<a href="#section-3.1">3.1</a>. Definition . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-7">7</a>
<a href="#section-3.2">3.2</a>. HTTP Streaming Issues . . . . . . . . . . . . . . . . . . <a href="#page-8">8</a>
<a href="#section-4">4</a>. Overview of Technologies . . . . . . . . . . . . . . . . . . . <a href="#page-10">10</a>
<a href="#section-4.1">4.1</a>. Bayeux . . . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-10">10</a>
<a href="#section-4.2">4.2</a>. BOSH . . . . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-11">11</a>
<a href="#section-4.3">4.3</a>. Server-Sent Events . . . . . . . . . . . . . . . . . . . . <a href="#page-13">13</a>
<a href="#section-5">5</a>. HTTP Best Practices . . . . . . . . . . . . . . . . . . . . . <a href="#page-13">13</a>
<a href="#section-5.1">5.1</a>. Limits to the Maximum Number of Connections . . . . . . . <a href="#page-13">13</a>
<a href="#section-5.2">5.2</a>. Pipelined Connections . . . . . . . . . . . . . . . . . . <a href="#page-14">14</a>
<a href="#section-5.3">5.3</a>. Proxies . . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-14">14</a>
<a href="#section-5.4">5.4</a>. HTTP Responses . . . . . . . . . . . . . . . . . . . . . . <a href="#page-15">15</a>
<a href="#section-5.5">5.5</a>. Timeouts . . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-15">15</a>
<a href="#section-5.6">5.6</a>. Impact on Intermediary Entities . . . . . . . . . . . . . <a href="#page-16">16</a>
<a href="#section-6">6</a>. Security Considerations . . . . . . . . . . . . . . . . . . . <a href="#page-16">16</a>
<a href="#section-7">7</a>. References . . . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-17">17</a>
<a href="#section-7.1">7.1</a>. Normative References . . . . . . . . . . . . . . . . . . . <a href="#page-17">17</a>
<a href="#section-7.2">7.2</a>. Informative References . . . . . . . . . . . . . . . . . . <a href="#page-17">17</a>
<a href="#section-8">8</a>. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-18">18</a>
<span class="grey">Loreto, et al. Informational [Page 2]</span></pre>
<hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-3" ></span>
<span class="grey"><a href="./rfc6202">RFC 6202</a> Bidirectional HTTP April 2011</span>
<span class="h2"><a class="selflink" id="section-1" href="#section-1">1</a>. Introduction</span>
The Hypertext Transfer Protocol [<a href="./rfc2616" title=""Hypertext Transfer Protocol -- HTTP/1.1"">RFC2616</a>] is a request/response
protocol. HTTP defines the following entities: clients, proxies, and
servers. A client establishes connections to a server for the
purpose of sending HTTP requests. A server accepts connections from
clients in order to service HTTP requests by sending back responses.
Proxies are intermediate entities that can be involved in the
delivery of requests and responses from the client to the server and
vice versa.
In the standard HTTP model, a server cannot initiate a connection
with a client nor send an unrequested HTTP response to a client;
thus, the server cannot push asynchronous events to clients.
Therefore, in order to receive asynchronous events as soon as
possible, the client needs to poll the server periodically for new
content. However, continual polling can consume significant
bandwidth by forcing a request/response round trip when no data is
available. It can also be inefficient because it reduces the
responsiveness of the application since data is queued until the
server receives the next poll request from the client.
In order to improve this situation, several server-push programming
mechanisms have been implemented in recent years. These mechanisms,
which are often grouped under the common label "Comet" [<a href="#ref-COMET" title=""Comet: Low Latency Data for the Browser"">COMET</a>],
enable a web server to send updates to clients without waiting for a
poll request from the client. Such mechanisms can deliver updates to
clients in a more timely manner while avoiding the latency
experienced by client applications due to the frequent opening and
closing of connections necessary to periodically poll for data.
The two most common server-push mechanisms are HTTP long polling and
HTTP streaming:
HTTP Long Polling: The server attempts to "hold open" (not
immediately reply to) each HTTP request, responding only when
there are events to deliver. In this way, there is always a
pending request to which the server can reply for the purpose of
delivering events as they occur, thereby minimizing the latency in
message delivery.
HTTP Streaming: The server keeps a request open indefinitely; that
is, it never terminates the request or closes the connection, even
after it pushes data to the client.
It is possible to define other technologies for bidirectional HTTP;
however, such technologies typically require changes to HTTP itself
(e.g., by defining new HTTP methods). This document focuses only on
<span class="grey">Loreto, et al. Informational [Page 3]</span></pre>
<hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-4" ></span>
<span class="grey"><a href="./rfc6202">RFC 6202</a> Bidirectional HTTP April 2011</span>
bidirectional HTTP technologies that work within the current scope of
HTTP as defined in [<a href="./rfc2616" title=""Hypertext Transfer Protocol -- HTTP/1.1"">RFC2616</a>] (HTTP 1.1) and [<a href="./rfc1945" title=""Hypertext Transfer Protocol -- HTTP/1.0"">RFC1945</a>] (HTTP 1.0).
The authors acknowledge that both the HTTP long polling and HTTP
streaming mechanisms stretch the original semantic of HTTP and that
the HTTP protocol was not designed for bidirectional communication.
This document neither encourages nor discourages the use of these
mechanisms, and takes no position on whether they provide appropriate
solutions to the problem of providing bidirectional communication
between clients and servers. Instead, this document merely
identifies technical issues with these mechanisms and suggests best
practices for their deployment.
The remainder of this document is organized as follows. <a href="#section-2">Section 2</a>
analyzes the HTTP long polling technique. <a href="#section-3">Section 3</a> analyzes the
HTTP streaming technique. <a href="#section-4">Section 4</a> provides an overview of the
specific technologies that use the server-push technique. <a href="#section-5">Section 5</a>
lists best practices for bidirectional HTTP using existing
technologies.
<span class="h2"><a class="selflink" id="section-2" href="#section-2">2</a>. HTTP Long Polling</span>
<span class="h3"><a class="selflink" id="section-2.1" href="#section-2.1">2.1</a>. Definition</span>
With the traditional or "short polling" technique, a client sends
regular requests to the server and each request attempts to "pull"
any available events or data. If there are no events or data
available, the server returns an empty response and the client waits
for some time before sending another poll request. The polling
frequency depends on the latency that the client can tolerate in
retrieving updated information from the server. This mechanism has
the drawback that the consumed resources (server processing and
network) strongly depend on the acceptable latency in the delivery of
updates from server to client. If the acceptable latency is low
(e.g., on the order of seconds), then the polling frequency can cause
an unacceptable burden on the server, the network, or both.
In contrast with such "short polling", "long polling" attempts to
minimize both the latency in server-client message delivery and the
use of processing/network resources. The server achieves these
efficiencies by responding to a request only when a particular event,
status, or timeout has occurred. Once the server sends a long poll
response, typically the client immediately sends a new long poll
request. Effectively, this means that at any given time the server
will be holding open a long poll request, to which it replies when
new information is available for the client. As a result, the server
is able to asynchronously "initiate" communication.
<span class="grey">Loreto, et al. Informational [Page 4]</span></pre>
<hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-5" ></span>
<span class="grey"><a href="./rfc6202">RFC 6202</a> Bidirectional HTTP April 2011</span>
The basic life cycle of an application using HTTP long polling is as
follows:
1. The client makes an initial request and then waits for a
response.
2. The server defers its response until an update is available or
until a particular status or timeout has occurred.
3. When an update is available, the server sends a complete response
to the client.
4. The client typically sends a new long poll request, either
immediately upon receiving a response or after a pause to allow
an acceptable latency period.
The HTTP long polling mechanism can be applied to either persistent
or non-persistent HTTP connections. The use of persistent HTTP
connections will avoid the additional overhead of establishing a new
TCP/IP connection [<a href="#ref-TCP" title=""Transmission Control Protocol"">TCP</a>] for every long poll request.
<span class="h3"><a class="selflink" id="section-2.2" href="#section-2.2">2.2</a>. HTTP Long Polling Issues</span>
The HTTP long polling mechanism introduces the following issues.
Header Overhead: With the HTTP long polling technique, every long
poll request and long poll response is a complete HTTP message and
thus contains a full set of HTTP headers in the message framing.
For small, infrequent messages, the headers can represent a large
percentage of the data transmitted. If the network MTU (Maximum
Transmission Unit) allows all the information (including the HTTP
header) to fit within a single IP packet, this typically does not
represent a significant increase in the burden for networking
entities. On the other hand, the amount of transferred data can
be significantly larger than the real payload carried by HTTP, and
this can have a significant impact (e.g., when volume-based
charging is in place).
Maximal Latency: After a long poll response is sent to a client, the
server needs to wait for the next long poll request before another
message can be sent to the client. This means that while the
average latency of long polling is close to one network transit,
the maximal latency is over three network transits (long poll
response, next long poll request, long poll response). However,
because HTTP is carried over TCP/IP, packet loss and
retransmission can occur; therefore, maximal latency for any
TCP/IP protocol will be more than three network transits (lost
<span class="grey">Loreto, et al. Informational [Page 5]</span></pre>
<hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-6" ></span>
<span class="grey"><a href="./rfc6202">RFC 6202</a> Bidirectional HTTP April 2011</span>
packet, next packet, negative ack, retransmit). When HTTP
pipelining (see <a href="#section-5.2">Section 5.2</a>) is available, the latency due to the
server waiting for a new request can be avoided.
Connection Establishment: A common criticism of both short polling
and long polling is that these mechanisms frequently open TCP/IP
connections and then close them. However, both polling mechanisms
work well with persistent HTTP connections that can be reused for
many poll requests. Specifically, the short duration of the pause
between a long poll response and the next long poll request avoids
the closing of idle connections.
Allocated Resources: Operating systems will allocate resources to
TCP/IP connections and to HTTP requests outstanding on those
connections. The HTTP long polling mechanism requires that for
each client both a TCP/IP connection and an HTTP request are held
open. Thus, it is important to consider the resources related to
both of these when sizing an HTTP long polling application.
Typically, the resources used per TCP/IP connection are minimal
and can scale reasonably. Frequently, the resources allocated to
HTTP requests can be significant, and scaling the total number of
requests outstanding can be limited on some gateways, proxies, and
servers.
Graceful Degradation: A long polling client or server that is under
load has a natural tendency to gracefully degrade in performance
at a cost of message latency. If load causes either a client or
server to run slowly, then events to be pushed to the client will
queue (waiting either for the client to send a long poll request
or for the server to free up CPU cycles that can be used to
process a long poll request that is being held at the server). If
multiple messages are queued for a client, they might be delivered
in a batch within a single long poll response. This can
significantly reduce the per-message overhead and thus ease the
workload of the client or server for the given message load.
Timeouts: Long poll requests need to remain pending or "hanging"
until the server has something to send to the client. The timeout
issues related to these pending requests are discussed in
<a href="#section-5.5">Section 5.5</a>.
Caching: Caching mechanisms implemented by intermediate entities can
interfere with long poll requests. This issue is discussed in
<a href="#section-5.6">Section 5.6</a>.
<span class="grey">Loreto, et al. Informational [Page 6]</span></pre>
<hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-7" ></span>
<span class="grey"><a href="./rfc6202">RFC 6202</a> Bidirectional HTTP April 2011</span>
<span class="h2"><a class="selflink" id="section-3" href="#section-3">3</a>. HTTP Streaming</span>
<span class="h3"><a class="selflink" id="section-3.1" href="#section-3.1">3.1</a>. Definition</span>
The HTTP streaming mechanism keeps a request open indefinitely. It
never terminates the request or closes the connection, even after the
server pushes data to the client. This mechanism significantly
reduces the network latency because the client and the server do not
need to open and close the connection.
The basic life cycle of an application using HTTP streaming is as
follows:
1. The client makes an initial request and then waits for a
response.
2. The server defers the response to a poll request until an update
is available, or until a particular status or timeout has
occurred.
3. Whenever an update is available, the server sends it back to the
client as a part of the response.
4. The data sent by the server does not terminate the request or the
connection. The server returns to step 3.
The HTTP streaming mechanism is based on the capability of the server
to send several pieces of information in the same response, without
terminating the request or the connection. This result can be
achieved by both HTTP/1.1 and HTTP/1.0 servers.
An HTTP response content length can be defined using three options:
Content-Length header: This indicates the size of the entity body in
the message, in bytes.
Transfer-Encoding header: The 'chunked' valued in this header
indicates the message will break into chunks of known size if
needed.
End of File (EOF): This is actually the default approach for
HTTP/1.0 where the connections are not persistent. Clients do not
need to know the size of the body they are reading; instead they
expect to read the body until the server closes the connection.
Although with HTTP/1.1 the default is for persistent connections,
it is still possible to use EOF by setting the 'Connection:close'
header in either the request or the response, thereby indicating
that the connection is not to be considered 'persistent' after the
<span class="grey">Loreto, et al. Informational [Page 7]</span></pre>
<hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-8" ></span>
<span class="grey"><a href="./rfc6202">RFC 6202</a> Bidirectional HTTP April 2011</span>
current request/response is complete. The client's inclusion of
the 'Connection: close' header field in the request will also
prevent pipelining.
The main issue with EOF is that it is difficult to tell the
difference between a connection terminated by a fault and one that
is correctly terminated.
An HTTP/1.0 server can use only EOF as a streaming mechanism. In
contrast, both EOF and "chunked transfer" are available to an
HTTP/1.1 server.
The "chunked transfer" mechanism is the one typically used by
HTTP/1.1 servers for streaming. This is accomplished by including
the header "Transfer-Encoding: chunked" at the beginning of the
response, which enables the server to send the following parts of the
response in different "chunks" over the same connection. Each chunk
starts with the hexadecimal expression of the length of its data,
followed by CR/LF (the end of the response is indicated with a chunk
of size 0).
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
25
This is the data in the first chunk
1C
and this is the second one
0
Figure 1: Transfer-Encoding response
To achieve the same result, an HTTP/1.0 server will omit the Content-
Length header in the response. Thus, it will be able to send the
subsequent parts of the response on the same connection (in this
case, the different parts of the response are not explicitly
separated by HTTP protocol, and the end of the response is achieved
by closing the connection).
<span class="h3"><a class="selflink" id="section-3.2" href="#section-3.2">3.2</a>. HTTP Streaming Issues</span>
The HTTP streaming mechanism introduces the following issues.
<span class="grey">Loreto, et al. Informational [Page 8]</span></pre>
<hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-9" ></span>
<span class="grey"><a href="./rfc6202">RFC 6202</a> Bidirectional HTTP April 2011</span>
Network Intermediaries: The HTTP protocol allows for intermediaries
(proxies, transparent proxies, gateways, etc.) to be involved in
the transmission of a response from the server to the client.
There is no requirement for an intermediary to immediately forward
a partial response, and it is legal for the intermediary to buffer
the entire response before sending any data to the client (e.g.,
caching transparent proxies). HTTP streaming will not work with
such intermediaries.
Maximal Latency: Theoretically, on a perfect network, an HTTP
streaming protocol's average and maximal latency is one network
transit. However, in practice, the maximal latency is higher due
to network and browser limitations. The browser techniques used
to terminate HTTP streaming connections are often associated with
JavaScript and/or DOM (Document Object Model) elements that will
grow in size for every message received. Thus, in order to avoid
unlimited growth of memory usage in the client, an HTTP streaming
implementation occasionally needs to terminate the streaming
response and send a request to initiate a new streaming response
(which is essentially equivalent to a long poll). Thus, the
maximal latency is at least three network transits. Also, because
HTTP is carried over TCP/IP, packet loss and retransmission can
occur; therefore maximal latency for any TCP/IP protocol will be
more than three network transits (lost packet, next packet,
negative ack, retransmit).
Client Buffering: There is no requirement in existing HTTP
specifications for a client library to make the data from a
partial HTTP response available to the client application. For
example, if each response chunk contains a statement of
JavaScript, there is no requirement in the browser to execute that
JavaScript before the entire response is received. However, in
practice, most browsers do execute JavaScript received in partial
responses -- although some require a buffer overflow to trigger
execution. In most implementations, blocks of white space can be
sent to achieve buffer overflow.
Framing Techniques: Using HTTP streaming, several application
messages can be sent within a single HTTP response. The
separation of the response stream into application messages needs
to be performed at the application level and not at the HTTP
level. In particular, it is not possible to use the HTTP chunks
as application message delimiters, since intermediate proxies
might "re-chunk" the message stream (for example, by combining
different chunks into a longer one). This issue does not affect
the HTTP long polling technique, which provides a canonical
framing technique: each application message can be sent in a
different HTTP response.
<span class="grey">Loreto, et al. Informational [Page 9]</span></pre>
<hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-10" ></span>
<span class="grey"><a href="./rfc6202">RFC 6202</a> Bidirectional HTTP April 2011</span>
<span class="h2"><a class="selflink" id="section-4" href="#section-4">4</a>. Overview of Technologies</span>
This section provides an overview of existing technologies that
implement HTTP-based server-push mechanisms to asynchronously deliver
messages from the server to the client.
<span class="h3"><a class="selflink" id="section-4.1" href="#section-4.1">4.1</a>. Bayeux</span>
The Bayeux protocol [<a href="#ref-BAYEUX" title=""Bayeux Protocol -- Bayeux 1.0.0"">BAYEUX</a>] was developed in 2006-2007 by the Dojo
Foundation. Bayeux can use both the HTTP long polling and HTTP
streaming mechanisms.
In order to achieve bidirectional communications, a Bayeux client
will use two HTTP connections to a Bayeux server so that both server-
to-client and client-to-server messaging can occur asynchronously.
The Bayeux specification requires that implementations control
pipelining of HTTP requests, so that requests are not pipelined
inappropriately (e.g., a client-to-server message pipelined behind a
long poll request).
In practice, for JavaScript clients, such control over pipelining is
not possible in current browsers. Therefore, JavaScript
implementations of Bayeux attempt to meet this requirement by
limiting themselves to a maximum of two outstanding HTTP requests at
any one time, so that browser connection limits will not be applied
and the requests will not be queued or pipelined. While broadly
effective, this mechanism can be disrupted if non-Bayeux JavaScript
clients simultaneously issue requests to the same host.
Bayeux connections are negotiated between client and server with
handshake messages that allow the connection type, authentication
method, and other parameters to be agreed upon between the client and
the server. Furthermore, during the handshake phase, the client and
the server reveal to each other their acceptable bidirectional
techniques, and the client selects one from the intersection of those
sets.
For non-browser or same-domain Bayeux, clients use HTTP POST requests
to the server for both the long poll request and the request to send
messages to the server. The Bayeux protocol packets are sent as the
body of the HTTP messages using the "application/json" Internet media
type [<a href="./rfc4627" title=""The application/json Media Type for JavaScript Object Notation (JSON)"">RFC4627</a>].
For browsers that are operating in cross-domain mode, Bayeux attempts
to use Cross-Origin Resource Sharing [<a href="#ref-CORS" title=""Cross-Origin Resource Sharing"">CORS</a>] checking if the browser
and server support it, so that normal HTTP POST requests can be used.
If this mechanism fails, Bayeux clients use the "JSONP" mechanism as
<span class="grey">Loreto, et al. Informational [Page 10]</span></pre>
<hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-11" ></span>
<span class="grey"><a href="./rfc6202">RFC 6202</a> Bidirectional HTTP April 2011</span>
described in [<a href="#ref-JSONP" title=""JSON with padding"">JSONP</a>]. In this last case, client-to-server messages
are sent as encoded JSON on the URL query parameters, and server-to-
client messages are sent as a JavaScript program that wraps the
message JSON with a JavaScript function call to the already loaded
Bayeux implementation.
<span class="h3"><a class="selflink" id="section-4.2" href="#section-4.2">4.2</a>. BOSH</span>
BOSH, which stands for Bidirectional-streams Over Synchronous HTTP
[<a href="#ref-BOSH" title=""Bidirectional-streams Over Synchronous HTTP (BOSH)"">BOSH</a>], was developed by the XMPP Standards Foundation in 2003-2004.
The purpose of BOSH is to emulate normal TCP connections over HTTP
(TCP is the standard connection mechanism used in the Extensible
Messaging and Presence Protocol as described in [<a href="./rfc6120" title=""Extensible Messaging and Presence Protocol (XMPP): Core"">RFC6120</a>]). BOSH
employs the HTTP long polling mechanism by allowing the server
(called a "BOSH connection manager") to defer its response to a
request until it actually has data to send to the client from the
application server itself (typically an XMPP server). As soon as the
client receives a response from the connection manager, it sends
another request to the connection manager, thereby ensuring that the
connection manager is (almost) always holding a request that it can
use to "push" data to the client.
In some situations, the client needs to send data to the server while
it is waiting for data to be pushed from the connection manager. To
prevent data from being pipelined behind the long poll request that
is on hold, the client can send its outbound data in a second HTTP
request over a second TCP connection. BOSH forces the server to
respond to the request it has been holding on the first connection as
soon as it receives a new request from the client, even if it has no
data to send to the client. It does so to make sure that the client
can send more data immediately, if necessary -- even in the case
where the client is not able to pipeline the requests -- while
simultaneously respecting the two-connection limit discussed in
<a href="#section-5.1">Section 5.1</a>.
The number of long poll request-response pairs is negotiated during
the first request sent from the client to the connection manager.
Typically, BOSH clients and connection managers will negotiate the
use of two pairs, although it is possible to use only one pair or
more than two pairs.
The roles of the two request-response pairs typically switch whenever
the client sends data to the connection manager. This means that
when the client issues a new request, the connection manager
immediately answers the blocked request on the other TCP connection,
thus freeing it; in this way, in a scenario where only the client
sends data, the even requests are sent over one connection, and the
odd ones are sent over the other connection.
<span class="grey">Loreto, et al. Informational [Page 11]</span></pre>
<hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-12" ></span>
<span class="grey"><a href="./rfc6202">RFC 6202</a> Bidirectional HTTP April 2011</span>
BOSH is able to work reliably both when network conditions force
every HTTP request to be made over a different TCP connection and
when it is possible to use HTTP/1.1 and then rely on two persistent
TCP connections.
If the connection manager has no data to send to the client for an
agreed amount of time (also negotiated during the first request),
then the connection manager will respond to the request it has been
holding with no data, and that response immediately triggers a fresh
client request. The connection manager does so to ensure that if a
network connection is broken then both parties will realize that fact
within a reasonable amount of time.
Moreover, BOSH defines the negotiation of an "inactivity period"
value that specifies the longest allowable inactivity period (in
seconds). This enables the client to ensure that the periods with no
requests pending are never too long.
BOSH allows data to be pushed immediately when HTTP pipelining is
available. However, if HTTP pipelining is not available and one of
the endpoints has just pushed some data, BOSH will usually need to
wait for a network round-trip time until the server is able to again
push data to the client.
BOSH uses standard HTTP POST request and response bodies to encode
all information.
BOSH normally uses HTTP pipelining over a persistent HTTP/1.1
connection. However, a client can deliver its POST requests in any
way permitted by HTTP 1.0 or HTTP 1.1. (Although the use of HTTP
POST with pipelining is discouraged in <a href="./rfc2616">RFC 2616</a>, BOSH employs various
methods, such as request identifiers, to ensure that this usage does
not lead to indeterminate results if the transport connection is
terminated prematurely.)
BOSH clients and connection managers are not allowed to use Chunked
Transfer Coding, since intermediaries might buffer each partial HTTP
request or response and only forward the full request or response
once it is available.
BOSH allows the usage of the Accept-Encoding and Content-Encoding
headers in the request and in the response, respectively, and then
compresses the response body accordingly.
Each BOSH session can share the HTTP connection(s) it uses with other
HTTP traffic, including other BOSH sessions and HTTP requests and
responses completely unrelated to the BOSH protocol (e.g., Web page
downloads).
<span class="grey">Loreto, et al. Informational [Page 12]</span></pre>
<hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-13" ></span>
<span class="grey"><a href="./rfc6202">RFC 6202</a> Bidirectional HTTP April 2011</span>
<span class="h3"><a class="selflink" id="section-4.3" href="#section-4.3">4.3</a>. Server-Sent Events</span>
W3C Server-Sent Events specification [<a href="#ref-WD-eventsource" title=""Server-Sent Events"">WD-eventsource</a>] defines an API
that enables servers to push data to Web pages over HTTP in the form
of DOM events.
The data is encoded as "text/event-stream" content and pushed using
an HTTP streaming mechanism, but the specification suggests disabling
HTTP chunking for serving event streams unless the rate of messages
is high enough to avoid the possible negative effects of this
technique as described in <a href="#section-3.2">Section 3.2</a>.
However, it is not clear if there are significant benefits to using
EOF rather than chunking with regards to intermediaries, unless they
support only HTTP/1.0.
<span class="h2"><a class="selflink" id="section-5" href="#section-5">5</a>. HTTP Best Practices</span>
<span class="h3"><a class="selflink" id="section-5.1" href="#section-5.1">5.1</a>. Limits to the Maximum Number of Connections</span>
HTTP <a href="./rfc2616#section-8.1.4">[RFC2616], Section 8.1.4</a>, recommends that a single user client
not maintain more than two connections to any server or proxy, in
order to prevent the server from being overloaded and to avoid
unexpected side effects in congested networks. Until recently, this
limit was implemented by most commonly deployed browsers, thus making
connections a scarce resource that needed to be shared within the
browser. Note that the available JavaScript APIs in the browsers
hide the connections, and the security model inhibits the sharing of
any resource between frames. The new HTTP specification [<a href="#ref-HTTPBIS" title=""HTTP/1.1, part 1: URIs, Connections, and Message Parsing"">HTTPBIS</a>]
removes the two-connection limitation, only encouraging clients to be
conservative when opening multiple connections. In fact, recent
browsers have increased this limit to 6 or 8 connections; however, it
is still not possible to discover the local limit, and usage of
multiple frames and tabs still places 8 connections within easy
reach.
Web applications need to limit the number of long poll requests
initiated, ideally to a single long poll that is shared between
frames, tabs, or windows of the same browser. However, the security
constraints of the browsers make such sharing difficult.
A best practice for a server is to use cookies [<a href="#ref-COOKIE" title=""HTTP State Management Mechanism"">COOKIE</a>] to detect
multiple long poll requests from the same browser and to avoid
deferring both requests since this might cause connection starvation
and/or pipeline issues.
<span class="grey">Loreto, et al. Informational [Page 13]</span></pre>
<hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-14" ></span>
<span class="grey"><a href="./rfc6202">RFC 6202</a> Bidirectional HTTP April 2011</span>
<span class="h3"><a class="selflink" id="section-5.2" href="#section-5.2">5.2</a>. Pipelined Connections</span>
HTTP [<a href="./rfc2616" title=""Hypertext Transfer Protocol -- HTTP/1.1"">RFC2616</a>] permits optional request pipelining over persistent
connections. Multiple requests can be enqueued before the responses
arrive.
In the case of HTTP long polling, the use of HTTP pipelining can
reduce latency when multiple messages need to be sent by a server to
a client in a short period of time. With HTTP pipelining, the server
can receive and enqueue a set of HTTP requests. Therefore, the
server does not need to receive a new HTTP request from the client
after it has sent a message to the client within an HTTP response.
In principle, the HTTP pipelining can be applied to HTTP GET and HTTP
POST requests, but using HTTP POST requests is more critical. In
fact, the use of HTTP POST with pipelining is discouraged in <a href="./rfc2616">RFC 2616</a>
and needs to be handled with special care.
There is an issue regarding the inability to control pipelining.
Normal requests can be pipelined behind a long poll, and are thus
delayed until the long poll completes.
Mechanisms for bidirectional HTTP that want to exploit HTTP
pipelining need to verify that HTTP pipelining is available (e.g.,
supported by the client, the intermediaries, and the server); if it's
not available, they need to fall back to solutions without HTTP
pipelining.
<span class="h3"><a class="selflink" id="section-5.3" href="#section-5.3">5.3</a>. Proxies</span>
Most proxies work well with HTTP long polling because a complete HTTP
response will be sent either on an event or a timeout. Proxies are
advised to return that response immediately to the user agent, which
immediately acts on it.
The HTTP streaming mechanism uses partial responses and sends some
JavaScript in an HTTP/1.1 chunk as described in <a href="#section-3">Section 3</a>. This
mechanism can face problems caused by two factors: (1) it relies on
proxies to forward each chunk (even though there is no requirement
for them to do so, and some caching proxies do not), and (2) it
relies on user agents to execute the chunk of JavaScript as it
arrives (even though there is also no requirement for them to do so).
A "reverse proxy" basically is a proxy that pretends to be the actual
server (as far as any client or client proxy is concerned), but it
passes on the request to the actual server that is usually sitting
behind another layer of firewalls. Any HTTP short polling or HTTP
<span class="grey">Loreto, et al. Informational [Page 14]</span></pre>
<hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-15" ></span>
<span class="grey"><a href="./rfc6202">RFC 6202</a> Bidirectional HTTP April 2011</span>
long polling solution will work fine with this, as will most HTTP
streaming solutions. The main downside is performance, since most
proxies are not designed to hold many open connections.
Reverse proxies can come to grief when they try to share connections
to the servers between multiple clients. As an example, Apache with
mod_jk shares a small set of connections (often 8 or 16) between all
clients. If long polls are sent on those shared connections, then
the proxy can be starved of connections, which means that other
requests (either long poll or normal) can be held up. Thus, Comet
mechanisms currently need to avoid any connection sharing -- either
in the browser or in any intermediary -- because the HTTP assumption
is that each request will complete as fast as possible.
One of the main reasons why both HTTP long polling and HTTP streaming
are perceived as having a negative impact on servers and proxies is
that they use a synchronous programming model for handling requests,
since the resources allocated to each request are held for the
duration of the request. Asynchronous proxies and servers can handle
long polls using slightly more resources than normal HTTP traffic.
Unfortunately some synchronous proxies do exist (e.g., Apache mod_jk)
and many HTTP application servers also have a blocking model for
their request handling (e.g., the Java servlet 2.5 specification).
<span class="h3"><a class="selflink" id="section-5.4" href="#section-5.4">5.4</a>. HTTP Responses</span>
In accordance with [<a href="./rfc2616" title=""Hypertext Transfer Protocol -- HTTP/1.1"">RFC2616</a>], the server responds to a request it has
successfully received by sending a 200 OK answer, but only when a
particular event, status, or timeout has occurred. The 200 OK body
section contains the actual event, status, or timeout that occurred.
This "best practice" is simply standard HTTP.
<span class="h3"><a class="selflink" id="section-5.5" href="#section-5.5">5.5</a>. Timeouts</span>
The HTTP long polling mechanism allows the server to respond to a
request only when a particular event, status, or timeout has
occurred. In order to minimize (as much as possible) both latency in
server-client message delivery and the processing/network resources
needed, the long poll request timeout ought to be set to a high
value.
However, the timeout value has to be chosen carefully; indeed,
problems can occur if this value is set too high (e.g., the client
might receive a 408 Request Timeout answer from the server or a 504
Gateway Timeout answer from a proxy). The default timeout value in a
browser is 300 seconds, but most network infrastructures include
proxies and servers whose timeouts are not that long.
<span class="grey">Loreto, et al. Informational [Page 15]</span></pre>
<hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-16" ></span>
<span class="grey"><a href="./rfc6202">RFC 6202</a> Bidirectional HTTP April 2011</span>
Several experiments have shown success with timeouts as high as 120
seconds, but generally 30 seconds is a safer value. Therefore,
vendors of network equipment wishing to be compatible with the HTTP
long polling mechanism are advised to implement a timeout
substantially greater than 30 seconds (where "substantially" means
several times more than the medium network transit time).
<span class="h3"><a class="selflink" id="section-5.6" href="#section-5.6">5.6</a>. Impact on Intermediary Entities</span>
There is no way for an end client or host to signal to HTTP
intermediaries that long polling is in use; therefore, long poll
requests are completely transparent for intermediary entities and are
handled as normal requests. This can have an impact on intermediary
entities that perform operations that are not useful in case of long
polling. However, any capabilities that might interfere with
bidirectional flow (e.g., caching) can be controlled with standard
headers or cookies.
As a best practice, caching is always intentionally suppressed in a
long poll request or response, i.e., the "Cache-Control" header is
set to "no-cache".
<span class="h2"><a class="selflink" id="section-6" href="#section-6">6</a>. Security Considerations</span>
This document is meant to describe current usage of HTTP to enable
asynchronous or server-initiated communication. It does not propose
any change to the HTTP protocol or to the expected behavior of HTTP
entities. Therefore this document does not introduce new security
concerns into existing HTTP infrastructure. The considerations
reported hereafter refer to the solutions that are already
implemented and deployed.
One security concern with cross-domain HTTP long polling is related
to the fact that often the mechanism is implemented by executing the
JavaScript returned from the long poll request. If the server is
prone to injection attacks, then it could be far easier to trick a
browser into executing the code [<a href="#ref-CORS" title=""Cross-Origin Resource Sharing"">CORS</a>].
Another security concern is that the number of open connections that
needs to be maintained by a server in HTTP long polling and HTTP
streaming could more easily lead to denial-of-service (DoS) attacks
[<a href="./rfc4732" title=""Internet Denial-of-Service Considerations"">RFC4732</a>].
<span class="grey">Loreto, et al. Informational [Page 16]</span></pre>
<hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-17" ></span>
<span class="grey"><a href="./rfc6202">RFC 6202</a> Bidirectional HTTP April 2011</span>
<span class="h2"><a class="selflink" id="section-7" href="#section-7">7</a>. References</span>
<span class="h3"><a class="selflink" id="section-7.1" href="#section-7.1">7.1</a>. Normative References</span>
[<a id="ref-RFC1945">RFC1945</a>] Berners-Lee, T., Fielding, R., and H. Nielsen,
"Hypertext Transfer Protocol -- HTTP/1.0",
<a href="./rfc1945">RFC 1945</a>, May 1996.
[<a id="ref-RFC2616">RFC2616</a>] Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
Masinter, L., Leach, P., and T. Berners-Lee,
"Hypertext Transfer Protocol -- HTTP/1.1",
<a href="./rfc2616">RFC 2616</a>, June 1999.
[<a id="ref-RFC4732">RFC4732</a>] Handley, M., Rescorla, E., and IAB, "Internet
Denial-of-Service Considerations", <a href="./rfc4732">RFC 4732</a>,
December 2006.
<span class="h3"><a class="selflink" id="section-7.2" href="#section-7.2">7.2</a>. Informative References</span>
[<a id="ref-BAYEUX">BAYEUX</a>] Russell, A., Wilkins, G., Davis, D., and M.
Nesbitt, "Bayeux Protocol -- Bayeux 1.0.0", 2007,
<<a href="http://svn.cometd.com/trunk/bayeux/bayeux.html">http://svn.cometd.com/trunk/bayeux/bayeux.html</a>>.
[<a id="ref-BOSH">BOSH</a>] Paterson, I., Smith, D., and P. Saint-Andre,
"Bidirectional-streams Over Synchronous HTTP
(BOSH)", XSF XEP 0124, February 2007.
[<a id="ref-COMET">COMET</a>] Russell, A., "Comet: Low Latency Data for the
Browser", March 2006, <<a href="http://infrequently.org/">http://infrequently.org/</a>
2006/03/comet-low-latency-data-for-the-browser/ >.
[<a id="ref-COOKIE">COOKIE</a>] Barth, A., <a style="text-decoration: none" href='https://www.google.com/search?sitesearch=datatracker.ietf.org%2Fdoc%2Fhtml%2F&q=inurl:draft-+%22HTTP+State+Management+Mechanism%22'>"HTTP State Management Mechanism"</a>, Work
in Progress, March 2011.
[<a id="ref-CORS">CORS</a>] van Kesteren, A., "Cross-Origin Resource Sharing",
W3C Working Draft WD-cors-20100727, latest version
available at <<a href="http://www.w3.org/TR/cors/">http://www.w3.org/TR/cors/</a>>,
July 2010,
<<a href="http://www.w3.org/TR/2010/WD-cors-20100727/">http://www.w3.org/TR/2010/WD-cors-20100727/</a>>.
[<a id="ref-HTTPBIS">HTTPBIS</a>] Fielding, R., Ed., Gettys, J., Mogul, J., Nielsen,
H., Masinter, L., Leach, P., Berners-Lee, T.,
Lafon, Y., Ed., and J. Reschke, Ed., "HTTP/1.1,
part 1: URIs, Connections, and Message Parsing",
Work in Progress, March 2011.
[<a id="ref-JSONP">JSONP</a>] Wikipedia, "JSON with padding",
<<a href="http://en.wikipedia.org/wiki/JSONP#JSONP">http://en.wikipedia.org/wiki/JSONP#JSONP</a>>.
<span class="grey">Loreto, et al. Informational [Page 17]</span></pre>
<hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-18" ></span>
<span class="grey"><a href="./rfc6202">RFC 6202</a> Bidirectional HTTP April 2011</span>
[<a id="ref-RFC4627">RFC4627</a>] Crockford, D., "The application/json Media Type for
JavaScript Object Notation (JSON)", <a href="./rfc4627">RFC 4627</a>,
July 2006.
[<a id="ref-RFC6120">RFC6120</a>] Saint-Andre, P., "Extensible Messaging and Presence
Protocol (XMPP): Core", <a href="./rfc6120">RFC 6120</a>, March 2011.
[<a id="ref-TCP">TCP</a>] Postel, J., "Transmission Control Protocol", STD 7,
<a href="./rfc793">RFC 793</a>, September 1981.
[<a id="ref-WD-eventsource">WD-eventsource</a>] Hickson, I., "Server-Sent Events", W3C Working
Draft WD-eventsource-20091222, latest version
available at <<a href="http://www.w3.org/TR/eventsource/">http://www.w3.org/TR/eventsource/</a>>,
December 2009, <<a href="http://www.w3.org/TR/2009/WD-eventsource-20091222/">http://www.w3.org/TR/2009/</a>
<a href="http://www.w3.org/TR/2009/WD-eventsource-20091222/">WD-eventsource-20091222/</a>>.
<span class="h2"><a class="selflink" id="section-8" href="#section-8">8</a>. Acknowledgments</span>
Thanks to Joe Hildebrand, Julien Laganier, Jack Moffitt, Subramanian
Moonesamy, Mark Nottingham, Julian Reschke, Martin Thomson, and
Martin Tyler for their feedback.
<span class="grey">Loreto, et al. Informational [Page 18]</span></pre>
<hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-19" ></span>
<span class="grey"><a href="./rfc6202">RFC 6202</a> Bidirectional HTTP April 2011</span>
Authors' Addresses
Salvatore Loreto
Ericsson
Hirsalantie 11
Jorvas 02420
Finland
EMail: salvatore.loreto@ericsson.com
Peter Saint-Andre
Cisco
1899 Wyknoop Street, Suite 600
Denver, CO 80202
USA
Phone: +1-303-308-3282
EMail: psaintan@cisco.com
Stefano Salsano
University of Rome "Tor Vergata"
Via del Politecnico, 1
Rome 00133
Italy
EMail: stefano.salsano@uniroma2.it
Greg Wilkins
Webtide
EMail: gregw@webtide.com
Loreto, et al. Informational [Page 19]
</pre>
|