There may be occasions when you need to limit the network speed when connecting via HTTP from an application you are developing. For example, when connecting from a very slow network or a foreign country with poor infrastructure, you want to ensure the connection works correctly.
If your web server is operating on Nginx, you have the ability to limit the network bandwidth via the Nginx settings, thus controlling the speed.
Nginx configuration file
For Docker containers running on official Nginx images, edit the /etc/nginx/conf.d/default.conf
file. See the following article for instructions on how to copy files from the container and update the container.
Bandwidth Limit Settings
Use limit_rate
to set the bandwidth limit.
limit_rate
Use the following example, limiting to 50KBPS (50K Bytes Per Second)
.
server {
listen 80;
server_name localhost;
limit_rate 50k
# Omitted below
}
limit_rate_after
You have the option to limit bandwidth by initially transferring at high speed and then reducing the rate for the remainder.
Use the following to limit bandwidth after 500KB
transfer. The limit_rate
can be used to simulate a slow start; the limit_rate_after
can be used to simulate a stall in the middle of the transfer.
server {
listen 80;
server_name localhost;
limit_rate_after 500k;
limit_rate 50k;
# Omitted below
}
Setting timeout in URLSession
I was doing a simulation test of bandwidth limiting. I noticed that I had made a mistake in setting a timeout when communicating from a client macOS app.
Two types of timeout
The timeout setting code was as follows.
let config = URLSessionConfiguration.ephemeral
config.timeoutIntervalForRequest = 120
config.timeoutIntervalForResource = 120
Since I slowed down the bandwidth as much as possible with Nginx, the download is now taking about 3 minutes. URLSession
has two different timeouts set with the properties.
timeoutIntervalForRequest
(Timeout before the response is returned)timeoutIntervalForResource
(Timeout for download completion)
If the property is set as in the code above, the download will be interrupted at 2 minutes, which would take 3 minutes to download. The correct thing to do is either not set timeoutIntervalForResource
and use the default value or set it to a sufficiently long value. How many values are long enough will vary from app to app. In my case, I erased one line and changed timeoutIntervalForResource
to the default value.
At the same time, it was good to see that it worked correctly when the download was aborted due to a timeout.
Also check when the network is disconnected
A misconfigured timeout is a use case where the application aborts the download. Conversely, it should also be confirmed that the network is interrupted in the middle of the download, and the download cannot be performed.
Error handling when disconnected in the middle of a session
Bandwidth limiting is effective for this as well. Limit bandwidth to create a situation where the download takes a sufficient amount of time. Then, when the download has made some progress, execute the following command to bring the server down.
% docker-compose down
Verify that the app correctly executes the error handling and gets out of the download process. In my case, I also combined limit_rate_after
and proceeded through to about halfway, then executed the command when it slowed down.
Once you have confirmed that error handling is working correctly and has been aborted, leave Nginx stopped and reconnect the application. You can also confirm that error handling works correctly when the server is not running.
Error handling when a file does not exist
After confirming this point, we will also try a case where the file does not exist: the file output by Nginx running on Docker is a file in the content_home
folder locally placed. Change the file name of the file in this folder to intentionally cause an HTTP 403 File Not Found
.
It is OK if the application can confirm error handling when the file does not exist correctly.
Conclusion
Combining Docker and Nginx makes it easy to simulate various networking-related problems. For example, it is very convenient to create a bandwidth limitation in a local machine because it is very difficult to prepare in a slow environment.
Create an application that is resistant to network errors.