-1

I am sending some data after html content (it has a little delay) in the same response during keep-alive session and want browser to show html before the whole response is downloaded.

For example, I have text 'hello, ' and a function that computes 'world' with delay (let it be 1 sec). So I want browser to show 'hello, ' immediately and 'world' with its delay. Is it possible within one request (so, without ajax)

Here is example python code of what I do (highlighted: https://pastebin.com/muUJyR36):

import socket
from time import sleep

sock = socket.socket()
sock.bind(('', 9090))
sock.listen(1)
conn, addr = sock.accept()

def give_me_a_world():
    sleep(1)
    return b'world'

while True:
    data = conn.recv(1024)
    response = b'HTTP/1.1 200 OK\r\n'\
               b'Content-Length: 12\r\n'\
               b'Connection: keep-alive\r\n'\
               b'\r\n'\
               b'hello, '

    conn.send(response) # send first part
    conn.send(give_me_a_world()) # make a delay and send other part

conn.close()
Dijkgraaf
  • 11,049
  • 17
  • 42
  • 54
ska
  • 77
  • 1
  • 5

2 Answers2

0

First and foremost, read How the web works: HTTP and CGI explained to understand why and where your current code violates HTTP and thus doesn't and shouldn't work.

Now, as per Is Content-Length or Transfer-Encoding is mandatory in a response when it has body , after fixing the violation, you should

  • omit the Content-Length header and close the socket after sending all the data, OR
  • calculate the length of the entire data to send beforehand and specify it in the Content-Length header
Community
  • 1
  • 1
ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
0

You could use Transfer-Encoding: chunked and omit Content-Length.

It works fine on text browsers like curl and Links WWW Browser. But, modern graphical browsers don't really start rendering until it reaches some sort of buffer boundaries.

import socket
from time import sleep

sock = socket.socket()
sock.bind(('', 9090))
sock.listen(1)
conn, addr = sock.accept()

def give_me_a_world():
    sleep(1)
    return b'5\r\n'\
           b'world\r\n'\
           b'0\r\n'\
           b'\r\n'

while True:
    data = conn.recv(1024)
    response = b'HTTP/1.1 200 OK\r\n'\
               b'Transfer-Encoding: chunked\r\n'\
               b'Connection: keep-alive\r\n'\
               b'\r\n'\
               b'7\r\n'\
               b'hello, \r\n'

    conn.send(response) # send first part
    conn.send(give_me_a_world()) # make a delay and send other part

conn.close()
Diego S.
  • 161
  • 1
  • 9