Why is pipelining disabled in modern browsers? - google-chrome

Many, if not all modern browsers are not using pipelined HTTP requests. In theory pipelining should speed up requests by reducing the number of round trip times required to fetch a website.
According to the HTTP standard, all servers must handle pipelined requests, so the problem should not be in lack of support on the servers.
I have seen some security concerns, such as a layer 7 DoS attack if a client pushes as many pipelined requests as possible to a URL that's performance-intensive for the server, ignoring any answers that might be received.
That would be a reason to turn pipelining support off on the server (violating the standard), but I cannot find any reason to turn it off on the clients.
It is however turned on by default on Android browsers and Chrome mobile.
Why are Chrome, Firefox, IE, Opera and Safari not using pipelined HTTP requests in their desktop (and sometimes mobile) version? What is their reasoning behind turning it off?

Pipelining is disabled for the following reasons:
Firefox:
The bigger issue has frankly been head of line blocking and its impact on performance and robustness. Naïve pipelines simply make performance worse.
Chrome:
The option to enable pipelining has been removed from Chrome, as there are known crashing bugs and known front-of-queue blocking issues. There are also a large number of servers and middleboxes that behave badly and inconsistently when pipelining is enabled. Until these are resolved, it's recommended nobody uses pipelining. Doing so currently requires a custom build of Chromium.
In general:
Buggy proxies are still common and these lead to strange and erratic behaviors that Web developers cannot foresee and diagnose easily.
Pipelining is complex to implement correctly: the size of the resource being transferred, the effective RTT that will be used, as well as the effective bandwidth, have a direct incidence on the improvement provided by the pipeline. Without knowing these, important messages may be delayed behind unimportant ones. The notion of important even evolves during page layout! HTTP pipelining therefore brings a marginal improvement in most cases only.
Pipelining is subject to the HOL problem.
HTTP/2 offers an alternative:
With HTTP/1.x, the browser has limited ability to leverage above priority data: the protocol does not support multiplexing, and there is no way to communicate request priority to the server. Instead, it must rely on the use of parallel connections, which enables limited parallelism of up to six requests per origin. As a result, requests are queued on the client until a connection is available, which adds unnecessary network latency. In theory, HTTP Pipelining tried to partially address this problem, but in practice it has failed to gain adoption.
HTTP/2 resolves these inefficiencies: request queuing and head-of-line blocking is eliminated because the browser can dispatch all requests the moment they are discovered, and the browser can communicate its stream prioritization preference via stream dependencies and weights, allowing the server to further optimize response delivery.
A proxy can be used as well:
You can try something I did to speed up Konqueror in KDE3. I was dissatisfied that Konqueror did not have HTTP pipelining, so after some searching, I installed Polipo as a local HTTP/HTTPS/FTP proxy and set Konqueror to use it (localhost on port 8123 if I remember correctly). In addition to HTTP pipelining, Polipo also provided improved caching, and since it was a proxy, I could set every browser to use it and the caching would be shared between the browsers. (This also means that it is a good idea to disable each browser's independent caching.)
Salesforce uses the following process:
Salesforce has a powerful and field-tested approach for mitigating HOLB at the TCP layer: we decouple the relation between an HTTP request and a TCP connection. Think about your transport as composed of multiple TCP connections (as many as the network context would need). Any part of the HTTP request can go over any TCP connection. So if you hit the HOLB in one connection, it not only helps in mitigating affected requests, it also minimizes impact to other application requests using healthy connections. The result is an ability to enjoy the benefits of multiplexing and pipelining at the HTTP layer while minimizing risks of HOLB.
References
Mozilla Bug 264354 – Enable HTTP pipelining by default
HTTP Pipelining - The Chromium Projects
Chromium Issue 364557: Remove pipelining code from Chrome
Understanding Connection Limits and New Proxy Connection Limits in WinInet and Internet Explorer – Http Client Protocol Issues (and other fun stuff I support)
HTTPS and Keep-Alive Connections – IEInternals
Changes in WinHttp on Windows 7 and onwards wrt HTTP/1.0 – HTTPContext
Content-Length and Transfer-Encoding Validation in the IE10 Download Manager – IEInternals
Use Sensible Long-Lived Cache headers – IEInternals
Web Performance : 2015 : March | Akamai Community
WebSockets, caution required!
HTTP: HTTP/2 - High Performance Browser Networking (O'Reilly)
HTTP Pipelining - Not So Fast...(Nor Slow!) – Guy's Pod
Persistent Connection Behavior of Popular Browsers
Connection management in HTTP/1.x - HTTP | MDN
Download Resumption in Internet Explorer – IEInternals
Networking Improvements in IE10 and Windows 8 – IEInternals
Konqueror very slowly (KDE4) • KDE Community Forums
HTTP Optimization: Multiple TCP Connections and Pipelining
SpeedGuide :: Internet Explorer, Chrome, Firefox Web Browser Tweaks
The Full Picture on HTTP/2 and HOL Blocking – Salesforce Engineering

The accepted answer may be somewhat out of date. Today I've seen chrome desktop pipeline 10 requests in a single HTTPS connection against our server, which provided me with the pipeline counts.

Related

Why did Google.com switch to SPDY (HTTP/2+QUIC/35) instead of HTTP/2

Several days ago I saw Google.com was using HTTP/2, but yesterday I became aware that Google.com had switched to SPDY (HTTP/2+QUIC/35).
Two questions:
As you know, HTTP/2 extends SPDY, why did Google.com rollback to SPDY?
What's the difference between SPDY and SPDY (HTTP/2+QUIC/35)?
http/2+quic/35 is not Speedy, it is a new communication protocol, based on UDP instead of TCP, named QUIC.
Let's quote https://www.chromium.org/quic :
Key advantages of QUIC over TCP+TLS+HTTP2 include:
Connection establishment latency
Improved congestion control
Multiplexing without head-of-line blocking
Forward error correction
Connection migration
A good presentation is available in this blog article.
In fact, the whole QUIC project was used to by-pass the TCP standards, in a more reactive way. Google did experiment on QUIC since years, transparently in Chrome browsers of billions of users, and switched now to it by default, if it works (with a fallback to "classical" HTTP/2 over TCP).
From the developer point of view, QUIC has a HTTP/2 interface, with all its features.
To my knownledge, only the LiteSpeed supports QUIC outside of Google - not the OpenLiteSpeed version yet (sadly) - and the go-based Caddy server.
Are you sure they did? Or is the tool you are using to display this info (this extension perhaps?) choosing to display it as such? Show the Network tab in developer tools in Chrome to see what Chrome really thinks it's talking.
HTTP/2 is the standard version of SPDY so saying something is "SPDY-enabled (HTTP/2)" doesn't make sense. Unless it means it can talk SPDY ("SPDY-enabled") but has chosen in this case to talk HTTP/2 as that's better?
Finally QUIC is a new protocol Google is experimenting with, which replaces the TCP network layer that SPDY and HTTP/2 are built on top of. So both can use QUIC instead of TCP and it's usually faster than TCP (hence the name which sounds like "quick" and is an acronym of "Quick UDP Internet Connections")

Why do browser implementations of HTTP/2 require TLS?

Why does most modern browsers require TLS for HTTP2?
Is there a technical reason behind this? Or simply just to make the web more secure?
http://caniuse.com/#feat=http2
It is partly about making more things use HTTPS and encourage users and servers to go HTTPS. Both Firefox and Chrome developers have stated this to be generally good. For the sake of users and users' security and privacy.
It is also about broken "middle boxes" deployed on the Internet that assume TCP traffic over port 80 (that might look like HTTP/1.1) means HTTP/1.1 and then they will interfere in order to "improve" or filter the traffic in some way. Doing HTTP/2 clear text over such networks end up with a much worse success rate. Insisting on encryption makes those middle boxes never get the chance to mess up the traffic.
Further, there are a certain percentage of deployed HTTP/1.1 servers that will return an error response to an Upgrade: with an unknown protocol (such as "h2c", which is HTTP/2 in clear text) which also would complicate an implementation in a widely used browser. Doing the negotiation over HTTPS is much less error prone as "not supporting it" simply means switching down to the safe old HTTP/1.1 approach.

Can't get SignalR, CORS and Server-Sent Events to work together

I have a SignalR 2.0 server hosted in IIS7 with a javascript client, targeting mainly Chrome browsers at the moment.
Without cross-domain, the SignalR transport is Server Sent Events, which works very nicely and is efficient.
I added CORS support to the server in the suggested fashion, using Microsoft.Owin.Cors -- that makes the server work with the client cross domain-- however, the SignalR transport is now long-polling; this is going to cause a much higher load on my servers, as the SignalR messages from the server to the client are quite frequent.
I'd really like to get Server-Sent Events and CORS support working together, and from my understanding of the protocols I don't see a reason why it can't be done. Any suggestions? Anyone have any luck in the same scenario with other browsers?
SignalR currently doesn't try to establish cross-domain SSE connections by default.
This decision was made before browsers had CORS compatible EventSource implementations, so it was seen as wasteful to even attempt establishing cross-domain SSE connections.
Starting with SignalR 2.0.3, cross-domain SSE connections will be attempted by default.
In the meantime you can manually specify which transports to try and what order to try them in:
$.connection.hub.start({transport: ["webSockets", "serverSentEvents", "foreverFrame", "longPolling"]});
http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-javascript-client#transport

Do HTML WebSockets maintain an open connection for each client? Does this scale?

I am curious if anyone has any information about the scalability of HTML WebSockets. For everything I've read it appears that every client will maintain an open line of communication with the server. I'm just wondering how that scales and how many open WebSocket connections a server can handle. Maybe leaving those connections open isn't a problem in reality, but it feels like it is.
In most ways WebSockets will probably scale better than AJAX/HTML requests. However, that doesn't mean WebSockets is a replacement for all uses of AJAX/HTML.
Each TCP connection in itself consumes very little in terms server resources. Often setting up the connection can be expensive but maintaining an idle connection it is almost free. The first limitation that is usually encountered is the maximum number of file descriptors (sockets consume file descriptors) that can be open simultaneously. This often defaults to 1024 but can easily be configured higher.
Ever tried configuring a web server to support tens of thousands of simultaneous AJAX clients? Change those clients into WebSockets clients and it just might be feasible.
HTTP connections, while they don't create open files or consume port numbers for a long period, are more expensive in just about every other way:
Each HTTP connection carries a lot of baggage that isn't used most of the time: cookies, content type, conetent length, user-agent, server id, date, last-modified, etc. Once a WebSockets connection is established, only the data required by the application needs to be sent back and forth.
Typically, HTTP servers are configured to log the start and completion of every HTTP request taking up disk and CPU time. It will become standard to log the start and completion of WebSockets data, but while the WebSockets connection doing duplex transfer there won't be any additional logging overhead (except by the application/service if it is designed to do so).
Typically, interactive applications that use AJAX either continuously poll or use some sort of long-poll mechanism. WebSockets is a much cleaner (and lower resource) way of doing a more event'd model where the server and client notify each other when they have something to report over the existing connection.
Most of the popular web servers in production have a pool of processes (or threads) for handling HTTP requests. As pressure increases the size of the pool will be increased because each process/thread handles one HTTP request at a time. Each additional process/thread uses more memory and creating new processes/threads is quite a bit more expensive than creating new socket connections (which those process/threads still have to do). Most of the popular WebSockets server frameworks are going the event'd route which tends to scale and perform better.
The primary benefit of WebSockets will be lower latency connections for interactive web applications. It will scale better and consume less server resources than HTTP AJAX/long-poll (assuming the application/server is designed properly), but IMO lower latency is the primary benefit of WebSockets because it will enable new classes of web applications that are not possible with the current overhead and latency of AJAX/long-poll.
Once the WebSockets standard becomes more finalized and has broader support, it will make sense to use it for most new interactive web applications that need to communicate frequently with the server. For existing interactive web applications it will really depend on how well the current AJAX/long-poll model is working. The effort to convert will be non-trivial so in many cases the cost just won't be worth the benefit.
Update:
Useful link: 600k concurrent websocket connections on AWS using Node.js
Just a clarification: the number of client connections that a server can support has nothing to do with ports in this scenario, since the server is [typically] only listening for WS/WSS connections on one single port. I think what the other commenters meant to refer to were file descriptors. You can set the maximum number of file descriptors quite high, but then you have to watch out for socket buffer sizes adding up for each open TCP/IP socket. Here's some additional info: https://serverfault.com/questions/48717/practical-maximum-open-file-descriptors-ulimit-n-for-a-high-volume-system
As for decreased latency via WS vs. HTTP, it's true since there's no more parsing of HTTP headers beyond the initial WS handshake. Plus, as more and more packets are successfully sent, the TCP congestion window widens, effectively reducing the RTT.
Any modern single server is able to server thousands of clients at once. Its HTTP server software has just to be is Event-Driven (IOCP) oriented (we are not in the old Apache one connection = one thread/process equation any more). Even the HTTP server built in Windows (http.sys) is IOCP oriented and very efficient (running in kernel mode). From this point of view, there won't be a lot of difference at scaling between WebSockets and regular HTTP connection. One TCP/IP connection uses a little resource (much less than a thread), and modern OS are optimized for handling a lot of concurrent connections: WebSockets and HTTP are just OSI 7 application layer protocols, inheriting from this TCP/IP specifications.
But, from experiment, I've seen two main problems with WebSockets:
They do not support CDN;
They have potential security issues.
So I would recommend the following, for any project:
Use WebSockets for client notifications only (with a fallback mechanism to long-polling - there are plenty of libraries around);
Use RESTful / JSON for all other data, using a CDN or proxies for cache.
In practice, full WebSockets applications do not scale well. Just use WebSockets for what they were designed to: push notifications from the server to the client.
About the potential problems of using WebSockets:
1. Consider using a CDN
Today (almost 4 years later), web scaling involves using Content Delivery Network (CDN) front ends, not only for static content (html,css,js) but also your (JSON) application data.
Of course, you won't put all your data on your CDN cache, but in practice, a lot of common content won't change often. I suspect that 80% of your REST resources may be cached... Even a one minute (or 30 seconds) CDN expiration timeout may be enough to give your central server a new live, and enhance the application responsiveness a lot, since CDN can be geographically tuned...
To my knowledge, there is no WebSockets support in CDN yet, and I suspect it would never be. WebSockets are statefull, whereas HTTP is stateless, so is much easily cached. In fact, to make WebSockets CDN-friendly, you may need to switch to a stateless RESTful approach... which would not be WebSockets any more.
2. Security issues
WebSockets have potential security issues, especially about DOS attacks. For illustration about new security vulnerabilities , see this set of slides and this webkit ticket.
WebSockets avoid any chance of packet inspection at OSI 7 application layer level, which comes to be pretty standard nowadays, in any business security. In fact, WebSockets makes the transmission obfuscated, so may be a major breach of security leak.
Think of it this way: what is cheaper, keeping an open connection, or opening a new connection for every request (with the negotiation overhead of doing so, remember it's TCP.)
Of course it depends on the application, but for long-term realtime connections (e.g. an AJAX chat) it's far better to keep the connection open.
The max number of connections will be capped by the max number of free ports for the sockets.
No it does not scale, gives tremendous work to intermediate routes switches. Then on the server side the page faults (you have to keep all those descriptors) are reaching high values, and the time to bring a resource into the work area increases. These are mostly JAVA written servers and it might be faster to hold on those gazilions of sockets then to destroy/create one.
When you run such a server on a machine any other process can't move anymore.

HTML 5 Websockets will replace Comet?

It looks like Websockets in HTML 5 will become a new standard for server push.
Does that mean the server push hack called Comet will be obsolete?
Is there a reason why I should learn how to implement comet when Websockets soon (1-2 years) will be available in all major browsers?
Then I could just use Beaconpush or Pusher instead till then right?
There are 2 pieces to this puzzle:
Q: Will the client-side portion of "comet" be necessary?
A: Yes. Even in the next 2 years, you're not going to see full support for WebSockets in the "major" browsers. IE8 for example doesn't have support for it, nor does the current version of FireFox. Given that IE6 was released in 2001, and it's still around today, I don't see WebSockets as replacing comet completely anytime soon.
Q: Will the server-side portion of "comet" be necessary?
A: Yes. Comet servers are designed to handle long-lived HTTP connections, where "typical" web servers do not. Even if the client side supports WebSockets, the server side will still need to be designed to handle the load.
In addition, as "gustavogb" mentioned, at least right now WebSockets aren't properly supported in a lot of HTTP Proxies, so until those all get updated as well, we'll still need some sort of fallback mechanism.
In short: comet, as it exists today, is not going away any time soon.
As an added note: the versions of WebSockets that currently ARE implemented in Chrome and Safari are two different drafts, and work on the "current" draft is still under very heavy development, so I don't even believe it is realistic to say that WebSockets support is functional at the moment. As a curiosity or for learning, sure, but not as a real spec, at least not yet.
[Update, 2/23/11]
The currently shipping version of Safari has a broken implementation (it doesn't send the right header), Firefox 4 has just deprecated WebSockets, so it won't ship enabled, and IE9 isn't looking good either. Looks like Chrome is the only one with a working, enabled version of a draft spec, so WebSockets has a long way to go yet.
Does that mean the server push hack called Comet will be obsolete?
WebSockets are capable of replacing Comet, AJAX, Long Polling, and all the hacks to workaround the problem when web browsers could not open a simple socket for bi-directional communications with the server.
Is there a reason why I should learn how to implement comet when WebSockets soon will be available in all major browsers?
It depends what "soon" means to you. No version of Internet Explorer (pre IE 9) supports the WebSockets API yet, for example.
UPDATE:
This was not intended to be an exhaustive answer. Check out the other answers, and #jvenema's in particular, for further insight into this topic.
Consider using a web socket library/framework that falls back to comet in the absence of browser support.
Checkout out Orbited and Hookbox.
In the medium term websockets won't replace comet solutions not only because of lack of browsers support but also because of HTTP Proxies. Until most of HTTP Proxies will be updated to support websockets connections, web developers will have to implement alternative solutions based on comet techniques to work in networks "protected" with this kind of proxies.
In the short/medium websockets will be just an optimization to be used when available, but you will still need to implement long-polling (comet) to rely on when websockets are not available if you need to make your website accessible for a lot of customers with networks/browsers not under your control.
Hopefully this will be abstracted by javascript frameworks and will be transparent for web developers.
Yes, because "soon" is a very slippery term. Many web shops still have to support IE6.
No, because a rash of comet frameworks and servers has emerged in recent times that will soon make it largely unnecessary for you to get your hands dirty in the basement.
Yes, because "soon" is a very slippery term...
Charter for the [working group] working group tasked with websockets, BiDirectional or Server-Initiated HTTP (hybi):
Description of Working Group
HTTP has most often been used as a request/response protocol, leading
to clients polling for new data, or users hitting the refresh button in
their browsers. Recent web applications are finding ways to communicate
with web servers in realtime, pushing data from the server-side to the
client as soon as it is available. However, these applications at
present can only use a variety of HTTP mechanisms (e.g. long polling
requests) to communicate with web servers bidirectionally.
The Hypertext-Bidirectional (HyBi) working group will seek
standardization of one approach to maintain bidirectional
communications between the HTTP client, server and intermediate
entities, which will provide more efficiency compared to the current
use of hanging requests.
HTTP still has a role to play; it's a flexible message oriented system. websockets was developed to provide bidirectionality and avoid the long polling issue altogether. [it does this well]. but it's simpler than http. and there's a lot of things that are useful about http. there will certainly be continued progress enriching http's bidirectional communication, be it comet or other push technologies. my own humble attempt is [http://github.com/rektide/pipe-layer].