0

I have a tiny CGI script written in Perl which prints numbers from 1 to 10 with 1 second interval:

root@debian-s-1vcpu-1gb-fra1-01:~# cat /usr/lib/cgi-bin/test
#!/usr/bin/perl

use strict;
local $|=1;

print "Content-encoding: none\nContent-type: text/plain\n\n";
#print "Content-type: text/plain\n\n";

for ( my $i = 1 ; $i <= 10 ; $i++ ) {
    print "$i\n";
    sleep(1);
}
root@debian-s-1vcpu-1gb-fra1-01:~#

The script works as expected when using curl:

curl 7.64.0 example

However, with web browsers(for example Chromium 88.0.4324.182 or Firefox 78.13.0esr) the page loads for 10 seconds and then the numbers from 1 to 10 are displayed at once. Request and Response Headers of a web browser can be seen below:

Firefox 78.13.0esr example

Even if I execute curl with identical request headers to Firefox example above, then the numbers are printed with 1 second interval as they should:

$ curl -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Accept-Encoding:
gzip, deflate' -H 'Accept-Language: en-US,en;q=0.5' -H 'Connection: keep-alive' -H 'Host: 164.90.236.255' -H 'Upgrade-Insecure-Requests: 1' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0' -v http://164.90.236.255/cgi-bin/test
* Expire in 0 ms for 6 (transfer 0x55b238016fb0)
*   Trying 164.90.236.255...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x55b238016fb0)
* Connected to 164.90.236.255 (164.90.236.255) port 80 (#0)
> GET /cgi-bin/test HTTP/1.1
> Host: 164.90.236.255
> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
> Accept-Encoding: gzip, deflate
> Accept-Language: en-US,en;q=0.5
> Connection: keep-alive
> Upgrade-Insecure-Requests: 1
> User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
>
< HTTP/1.1 200 OK
< Date: Mon, 24 Jan 2022 12:19:56 GMT
< Server: Apache/2.4.25 (Debian)
< Content-encoding: none
< Keep-Alive: timeout=5, max=100
< Connection: Keep-Alive
< Transfer-Encoding: chunked
< Content-Type: text/plain
<
1
2
3
4
5
6
7
8
9
10
* Connection #0 to host 164.90.236.255 left intact
$ 

Server is Apache 2.4.25 with mod_deflate disabled.

What might cause such behavior? How to disable CGI script buffering in web browsers? Perhaps there is a Response Header which allows one to control this behavior.

2
  • 2
    There is no specification when a browser should display the received (partial) data. A browser may use a buffer for reading the data and may display the data when the buffer is full or when the end of the data is detected. You should look how time or status display is dynamically displayed on HTML pages.
    – Bodo
    Jan 24, 2022 at 13:18
  • @Bodo Thanks! You are probably right. As an hacky workaround, adding print " " x 1024; before the for loop in my CGI script seen in the initial post seems to fill the browsers cache and numbers from 1 to 10 are printed with 1s interval exactly like in case of curl.
    – Martin
    Jan 24, 2022 at 14:31

1 Answer 1

0

What you're looking for is done via Ajax normally. Web browsers don't behave the way you want them to because, imagine a very complex HTML/JS/CSS page which you need to render 10 times instead of once. The browser cannot know in advance what data the server is going to send, so they try to minimize the amount of work in order to save CPU cycles.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .