简体   繁体   中英

Cookies and HTTP with Python

I wish to "retrieve" the cookies sent by the client in my subclass of BaseHTTPRequestHandler .

Firstly I'm unsure of the exact sequence of sending of headers, in a typical HTTP request and response this is my understanding of the sequence of events:

  1. Client sends request (method, path, HTTP version, host, and ALL headers).
  2. The server responds with a response code, followed by a bunch of headers of its own.
  3. The server then sends the body of the response.

When exactly is the client's POST data sent? Does any overlapping occur in this sequence as described above?

Second, when is it safe to assume that the "Cookie" header has been received by the server. Should all of the client headers have been received by the time self.send_response is called by the server? When in the HTTP communication is the appropriate time to peek at cookie headers in self.headers ?

Thirdly, what is the canonical way to parse cookies in Python. I currently believe a Cookie.SimpleCookie should be instantiated, and then data from the cookie headers some how fed into it. Further clouding this problem, is the Cookie classes clunkiness when dealing with the HTTPRequestHandler interfaces. Why does the output from Cookie.output() not end with a line terminator to fit into self.wfile.write(cookie.output()) , or instead drop the implicitly provided header name to fit nicely into self.send_header("Set-Cookie", cookie.output())

Finally, the cookie classes in the Cookie module, give the illusion that they're dictionaries of dictionaries. Assigning to different keys in the cookie, does not pack more data into the cookie, but rather generates more cookies... all apparently in the one class, and each generating its own Set-Cookie header. What is the best practise for packing containers of values into cookie(s)?

HTTP is a request/response protocol, without overlap; the body of a POST comes as part of the request (when the verb is POST, of course).

All headers also come as part of the request, including Cookie: if any (there might be no such header of course, eg when the browser is running with cookies disabled or whatever). So peek at the headers whenever you've received the request and are serving it.

I'm not sure what your "thirdly" problem is. No newline gets inserted if none is part of the cookie -- why ever should it be? Edit : see later.

On the fourth point, I think you may be confusing cookies with "morsels". There is no limit to the number of Set-Cookie headers in the HTTP response, so why's that a problem?

Edit : you can optionally pass to output up to three arguments: the set of morsel attributes you want in the output for each morsel (default None meaning all attributes), the header string you want to use in front of each morsel (default Set-Cookie: ), the separator string you want between morsels (default \\r\\n ). So it seems that your intended use of a cookie is single-morsel (otherwise you couldn't stick the string representation into a single header, which you appear most keen to do): in that case

thecookie.output(None, '')

will give you exactly the string you want. Just make multiple SimpleCookie instances with one morsel each (since one morsel is what fits into a single header!-).

Here's a quick way to get the cookies with no 3rd-party-libraries. While it only answers a section of the question, it may be answering the one which most "visitors" will be after.

import Cookie

def do_GET(self):
    cookies = {}
    cookies_string = self.headers.get('Cookie')
    if cookies_string:
      cookies = Cookie.SimpleCookie()
      cookies.load(cookies_string)
    if 'my-cookie' in cookies:
      print(cookies['my-cookie'].value)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM