Sometimes you want to limit the network speed when connecting with HTTP from an application you are making. For example, when connecting from a very slow network or from a foreign country with poor infrastructure, you want to make sure that the connection works correctly.
If your web server is running Nginx, you can limit the network bandwidth in the Nginx settings to reduce 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 can limit bandwidth by transferring quickly at first and slowing down the rest.
Use the following to limit bandwidth after 500KB
transfer: limit_rate
can be used to simulate a slow start; 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 and 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 I could with Nginx, the download is now taking about 3 minutes. URLSession
has two different timeouts, which are set in the properties.
timeoutIntervalForRequest
(Timeout before 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 when it 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. 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 all the way 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 from 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 a variety of networking-related problems. It is very convenient to be able to create a bandwidth limitation in a local machine, because it is very difficult to prepare a slow environment.
Create an application that is resistant to network errors.