Tornado-04, Tornado output and response headers

Time:2022-11-25

Tornado output and response headers


1. Output

in the previous article03. Input and output of TornadoHave a preliminary understanding of write
In this article, let’s take a deeper look at write
First, we create a new lesson3 folder under the last tornado folder
In fact, write does not directly return the data to the front end, but writes it to the buffer first, and returns to the front end after the function ends.
We verify as follows:
Create a new start1.py file and add the following code after adding the basic code

class FlushHandler(tornado.web.RequestHandler):
    def get(self):
        self.write('11111111111' + '<br>')
        self.write('22222222222' + '<br>')
        self.write('There comes a flush' + '<br>')
        self.flush()
        import time
        time.sleep(5)
        self.write('33333333333' + '<br>')
        self.write('There no flush' + '<br>')
        self.write('The function is almost over!')


Tornado-04, Tornado output and response headers

Tornado-04, Tornado output and response headers

Here we can clearly see that the result is different with or without self.flush(). If there is, you can see the previous output first. If not, you can print it out together after the function is executed. self.flush() is to flush the current output buffer to the web page.

In addition to the self.flush() above, there is also self.finish() that needs our attention. It is similar to the return in the function. Once executed, self.write cannot be executed later. The function prototype:

RequestHandler.finish(chunk = None)

After the finish function is called, calling the write function will report an error

self.finish()
self.write('en~~~~')

Error content: RuntimeError: Cannot write() after finish()

Send the given HTTP error to the browser

Function prototype:

RequestHandler.send_error(status_code = 500,**kwargs)

If flush() has already been called, it is not possible to send an error, so the method will simply terminate the response. If output has been written but not yet flushed, it is discarded and replaced with an error page.

Override write_error() to customize the error page returned. Pass additional keyword arguments
Add the following Handler

class ErrorHandler(tornado.web.RequestHandler):
    def get(self):
        self.send_error(404)
        # self.flush()
        self.send_error(404) #If self.flush() has been executed, no error will be displayed

Tornado-04, Tornado output and response headers


Override to implement custom error pages

Function prototype:

RequestHandler.write_error(status_code** kwargs )

write_error can call write, render, set_header, etc. to produce output.
Add the following code in ErrorHandler

def write_error(self, status_code, **kwargs): # override write_error method
    self.write("---%d----\n"%status_code)

Tornado-04, Tornado output and response headers

Custom output errors can be implemented by overriding the write_error method.

Set the status code of the response

RequestHandler.set_status(status_code,reason = None)

parameter:

  • status_code (int) – Response status code.
  • reason (string) – A human readable reason phrase describing the status code.

    self.set_status(404,’error’)

2. Setting the response header

Take Google Chrome as an example: press F12 to open the console that comes with the browser, we choose Network, here we can see information that the browser does not see on the page. Refresh after opening, and you can see after selecting: General, Respnse Headers and Request Headers

General: It is the basic information in the request, Respnse Headers is the corresponding information, Request Headers is the request information, and the corresponding information can be set to the browser on the server side.
Add the following code

(r'/header',HeadersHandler),

class HeadersHandler(tornado.web.RequestHandler):
    def get(self):
        self.write('headers')
        self.set_header('hujing',18)
        self.set_header('changsha','hunan')

Tornado-04, Tornado output and response headers

Function prototype:

RequestHandler.set_header(name, value)

If the value is not a string, we convert it to a string. Then encode all header values ​​as UTF-8

self.set_header can set the response header you need

Add the given response header and value

Function prototype:

RequestHandler.add_header(*name*, *value*)

Unlike set_header, add_header may be called multiple times to return multiple values ​​for the same key. The same key set_header can only return one value

self.set_header('hujing','20') #Only display hujing:20 here, covering the previous hujing:18
self.add_header('hujing','19')  
self.add_header('changsha','0731')  
self.add_header('changsha','0321')

undo previous set_header call

If there is an addition, there will be a deletion, the function prototype:

RequestHandler.clear_header(name)


self.clear_header('changsha')

3. Execution order of corresponding headers

class IndexHandler(tornado.web.RequestHandler):
    def set_default_headers(self):
        print(' ---set_default_headers---: set header'+'<br> ')

    def initialize(self):
        print(' ---initialize---: initialize '+'<br> ')

    def prepare(self):
        print(' ---prepare---: preparation '+'<br> ')

    def get(self):
        self.write(' ---get---: processing get request'+'<br> ')

    def post(self):
        self.write(' ---post---: processing post request'+'<br> ')

    def write_error(self, status_code, **kwargs):
        print(' ---write_error---: handle error '+'<br> ')

    def on_finish(self):
        print(' ---on_finish---: end, release resources'+'<br> ')

The above is the execution sequence of a response in the background. You can implement what you need according to your needs.

The sum of the source code of this article

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define, options

define('port', default=9000, help='run port', type=int)


class FlushHandler(tornado.web.RequestHandler):
    def get(self):
        self.write('11111111111' + '<br>')
        self.write('22222222222' + '<br>')
        self.write('There comes a flush' + '<br>')
        self.flush()
        import time
        time.sleep(5)
        self.write('33333333333' + '<br>')
        self.write('There no flush' + '<br>')
        self.write('The function is almost over!')


class ErrorHandler(tornado.web.RequestHandler):
    def get(self):
        self.send_error(404)
        # self.set_status(404, 'error')

    def write_error(self, status_code, **kwargs): # override write_error method
        self.write("--%d--\n" % status_code)


class HeadersHandler(tornado.web.RequestHandler):
    def get(self):
        self.write('headers')
        self.set_header('hujing', 18)
        self.set_header('changsha', 'hunan')
        self.set_header('hujing', '20')  # 1
        self.add_header('hujing', '19')  # 2
        self.add_header('changsha', '0731')  # 3
        self.add_header('changsha', '0321')  # 4


if __name__ == '__main__':
    tornado.options.parse_command_line()
    print(options.port) # print port to terminal
    app = tornado.web.Application(
        handlers=[
            (r'/flush', FlushHandler),
            (r'/error', ErrorHandler),
            (r'/header', HeadersHandler),
        ],
        template_path='templates',

    )
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

Recommended Today

Client cannot authenticate XXX:[TOKEN, KERBEROS]

Caused by: org.apache.hadoop.security.AccessControlException: Client cannot authenticate xxx:[TOKEN, KERBEROS] The security authentication failed, and the cause analysis is as follows:1. Check whether the Kerberos address can be connected normally // kdc’s ip System.setProperty(“java.security.krb5.kdc”, “192.168.1.1”); // realm System.setProperty(“java.security.krb5.realm”, “XXX”); 2. The configuration file failed to be read successfully UserGroupInformation.loginUserFromKeytab(user name, path to keytab file); It is recommended […]