What are the most widespread low bandwidth alternatives to HTTPS? - ruby

I'm porting a web app to a mobile device and working with the major carriers to minimize our bandwidth use, but need to maintain security.
The SSL handshaking overhead associated with HTTPS is more than 50% of the bandwidth currently. Can someone recommend a lightweight, low bandwidth alternative to HTTPS?
The payload is HTTP/XML, but can be modified to any format. I'm using Ruby on Rails so something with a Ruby library is ideal.

It sounds like your connection is short lived, and your payload small. Would it be possible to hold the connection open, and send multiple "messages" through it, that way, as more responses get send, your SSL overhead becomes a smaller portion of the cumulative data transfer. This would avoid the need to repeat the handshake. HTTP has some keep-alive capabilities with it, hopefully those can be applied in Ruby to a SSL connection.

Related

ListenAndServe vs ListenAndServeTLS Speed

I'm building an API that will be hit with many requests/second from a few sources (call it 1000/sec) and will be responding to each quickly with very little information (think < 1k).
When I use HTTP (http.ListenAndServe()), performance is between 1000-2000 req/sec using Siege on my t3.micro and CPU usage rarely exceeds 30-40%
With HTTPS (http.ListenAndServeTLS()), I cap at around 450 req/sec with CPU usage at 100%. It seems pretty obvious it's doing a lot of SSL handshake type work, but my question is why would this be the case? Even with few concurrent connections from Siege it is much slower (I also tried connection=keep-alive in siege config)
I get that the first connection should be slower, but after that, is this behavior still expected or is there some issue I am not aware of? One thing I noticed is Siege is using HTTP/1.1, I would think it should be using 2.0 when going over HTTPS?
Thanks.
When using SSL/TLS your program needs to encode, decode each message sent or received, and this consumes CPU power. You may try to add http/https proxy which will terminate the SSL/TLS traffic. This can be apache http, nginx, haproxy. This can improve the situation.

High Performance Options for Remote services access

I have a service, foo, running on machine A. I need to access that service from machine B. One way is to launch a web server on A and do it via HTTP; code running under web server on A accesses foo and returns the results. Another is to write socket server on A; socket server access service foo and returns the result.
HTTP connection initiation and handshake is expensive; sockets can be written, but I want to avoid that. What other options are available for high performance remote calls?
HTTP is just the protocol over the socket. If you are using TCP/IP networks, you are going to be using a socket. The HTTP connection initiation and handshake are not the expensive bits, it's TCP initiation that's really the expensive bit.
If you use HTTP 1.1, you can use persistent connections (Keep-Alive), which drastically reduces this cost, closer to that of keeping a persistent socket open.
It all depends on whether you want/need the higher-level protocol. Using HTTP means you will be able to do things like consume this service from a lot more clients, while writing much less documentation (if you write your own protocol, you will have to document it). HTTP servers also supports things like authentication, cookies, logging, out of the box. If you don't need these sorts of capabilities, then HTTP might be a waste. But I've seen few projects that don't need at least some of these things.
Adding to the answer of #Rob, as the question is not precisely pointing to an application or performance boundaries, it would be good to look into the options available in a broader context, which is Inter process communication.
The wikipedia page cleanly lists down the options available and would be a good place to start with.
What technology are you going to use? Let me answer for Java world.
If your request rate is below 100/sec, you should not care about optimizations and use most versatile solution - HTTP.
Well-written asynchronous server like Netty-HTTP can easily handle 1000 requests per second on medium-level hardware.
If you need more or have constrained resources, you can go to binary format. Most popular one out there is Google Protobuf(multilanguage) + Netty (Java).
What you should know about HTTP performance:
Http can use Keep-Alive which removes reconnection cost for every request
Http adds traffic overhead for every request and response - around 50-100 bytes.
Http client and server consumes additional CPU for parsing HTTP headers - that is noticeable after abovementioned 100 req/sec
Be careful when selecting technology. Even in 21 century it is hard to find well-written HTTP server and client.

Cost of secure websocket vs. unsecure websocket

I am currently developing a browser-based multiplayer game which is using WebSockets. My highest priorities are low latency and compatibility with a wide range of plattforms and network setups.
But I am doing password authentication. I also have a chat function and I consider the privacy of my players to be important. So I thought that I could maybe improve security and privacy by switching to websockets over TLS. My questions are:
how will TLS encryption of the web socket connection affect performance? Note that I am frequently sending very small but very important messages.
will wss:// work in any environment where ws:// works or will I need a fallback mechanism?
Or would it maybe be wiser for my use-case to implement encryption on the application level?
WSS will work in significantly broader network environments than WS due to proxies and other intermediaries not understanding or actively blocking WebSocket.
Regarding additional latency introduced by TLS, I'd expect it to be insignificant compared to the latency you get from WAN connections anyway (which is roughly 10-250ms RTT).
Regarding bandwidth, since TLS uses symmetric ciphers for the payload encryption I'd expect no overhead.
TLS obviously consumes CPU cycles, but given todays CPU power, it's often not an issue.
Implementing own encryption does not make sense .. unless you care about end-to-end privacy .. but then you won't be able to do anything on the server-side (besides dispatching to other clients) anyway.
In short: go with WSS.
I have written a blog post about WebSocket overhead (incl. comparison with TLS vs non-TLS): http://tavendo.com/blog/post/dissecting-websocket-overhead/
I did a performance study a few years ago that showed SSL over the Internet was only 3 times slower than plaintext. I would expect the gap to have narrowed since then due to hardware speed improvements.
I would certainly not recommend you implement your own encryption when SSL already exists. You have no reason to believe it will be any faster than SSL and you will almost certainly introduce security flaws that are not present in SSL.

Understanding HTTPS connection setup overhead

I'm building a web-based chat app which will need to make an AJAX request for every message sent or received. I'd like the data to be encrypted and am leaning towards running AJAX (with long-polling) over HTTPS.
However, since the frequency of requests here is a lot higher than with basic web browsing, I'd like to get a better understanding of the overhead (network usage, time, server CPU, client CPU) in setting up the encrypted connection for each HTTPS request.
Aside from any general info/advice, I'm curious about:
As a very rough approximation, how much extra time does an HTTPS request take compared to HTTP? Assume content length of 1 byte and an average PC.
Will every AJAX request after the first have anything significant cached, allowing it to establish the connection quicker? If so, how much quicker?
Thank you in advance :-)
Everything in HTTPS is slower. Personal information shouldn't be cached, you have encryption on both ends, and an SSL handshake is relatively slow.
Long-polling will help. Long keep-alives are good. Enabling SSL sessions on your server will avoid a lot of the overhead as well.
The real trick is going to be doing load-balancing or any sort of legitimate caching. Not sure how much that will come into play in your system, being a chat server, but it's something to consider.
You'll get more information from this article.
Most of the overhead is in the handshake (exchanging certificates, checking for their revocation, ...). Session resumption and the recent false start extension helps in that respect.
In my experience, the worse case scenario happens when using client-certificate authentication and advertising too many CAs (the CertificateRequest message sent by the server can even become too big); this is quite rare since in practice, when you use client-certificate authentication, you would only accept client-certificates from a limited number of CAs.
If you configure your server properly (for resources for which it's appropriate), you can also enable browser caching for resources served over HTTPS, using Cache-Control: public.

Any HTTP proxies with explicit, configurable support for request/response buffering and delayed connections?

When dealing with mobile clients it is very common to have multisecond delays during the transmission of HTTP requests. If you are serving pages or services out of a prefork Apache the child processes will be tied up for seconds serving a single mobile client, even if your app server logic is done in 5ms. I am looking for a HTTP server, balancer or proxy server that supports the following:
A request arrives to the proxy. The proxy starts buffering in RAM or in disk the request, including headers and POST/PUT bodies. The proxy DOES NOT open a connection to the backend server. This is probably the most important part.
The proxy server stops buffering the request when:
A size limit has been reached (say, 4KB), or
The request has been received completely, headers and body
Only now, with (part of) the request in memory, a connection is opened to the backend and the request is relayed.
The backend sends back the response. Again the proxy server starts buffering it immediately (up to a more generous size, say 64KB.)
Since the proxy has a big enough buffer the backend response is stored completely in the proxy server in a matter of miliseconds, and the backend process/thread is free to process more requests. The backend connection is immediately closed.
The proxy sends back the response to the mobile client, as fast or as slow as it is capable of, without having a connection to the backend tying up resources.
I am fairly sure you can do 4-6 with Squid, and nginx appears to support 1-3 (and looks like fairly unique in this respect). My question is: is there any proxy server that empathizes these buffering and not-opening-connections-until-ready capabilities? Maybe there is just a bit of Apache config-fu that makes this buffering behaviour trivial? Any of them that it is not a dinosaur like Squid and that supports a lean single-process, asynchronous, event-based execution model?
(Siderant: I would be using nginx but it doesn't support chunked POST bodies, making it useless for serving stuff to mobile clients. Yes cheap 50$ handsets love chunked POSTs... sigh)
What about using both nginx and Squid (client — Squid — nginx — backend)? When returning data from a backend, Squid does convert it from C-T-E: chunked to a regular stream with Content-Length set, so maybe it can normalize POST also.
Nginx can do everything you want. The configuration parameters you are looking for are
http://wiki.codemongers.com/NginxHttpCoreModule#client_body_buffer_size
and
http://wiki.codemongers.com/NginxHttpProxyModule#proxy_buffer_size
Fiddler, a free tool from Telerik, does at least some of the things you're looking for.
Specifically, go to Rules | Custom Rules... and you can add arbitrary Javascript code at all points during the connection. You could simulate some of the things you need with sleep() calls.
I'm not sure this method gives you the fine buffering control you want, however. Still, something might be better than nothing?
Squid 2.7 can support 1-3 with a patch:
http://www.squid-cache.org/Versions/v2/HEAD/changesets/12402.patch
I've tested this and found it to work well, with the proviso that it only buffers to memory, not disk (unless it swaps, of course, and you don't want this), so you need to run it on a box that's appropriately provisioned for your workload.
Chunked POSTs are a problem for most servers and intermediaries. Are you sure you need support? Usually clients should retry the request when they get a 411.
Unfortunately, I'm not aware of a ready-made solution for this. In the worst case scenario, consider developing it yourself, say, using Java NIO -- it shouldn't take more than a week.

Resources