6

I've seen this question, but I want to be able to access the data that's POST'd, external from the handler.

Is there a way to do this?

Following is the code:

import BaseHTTPServer

HOST_NAME = ''
PORT_NUMBER=8088

postVars = ''

class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):

    def do_POST(s):
        s.send_response(200)
        s.end_headers()
        varLen = int(s.headers['Content-Length'])
        postVars = s.rfile.read(varLen)
        print postVars

server_class = BaseHTTPServer.HTTPServer
httpd = server_class((HOST_NAME, PORT_NUMBER), MyHandler)

try:
    httpd.handle_request()
except KeyboardInterrupt:
    pass

print postVars
httpd.server_close()

postVars is valued during the Handler, but not after MyHandler

Community
  • 1
  • 1
KevinDTimm
  • 14,226
  • 3
  • 42
  • 60

2 Answers2

10

This because the postVars is locally affected in the MyHandler instance created by the HTTPServer. If you want to access it, declare postVars as a global variable at the start of do_POST method.

def do_POST(s):
  global postVars
  s.send_response(200)
  s.end_headers()
  varLen = int(s.headers['Content-Length'])
  postVars = s.rfile.read(varLen)

Anyway, I'm not sure what you want to achieve by using variables outside the server and requestHandler context.

Kaltezar
  • 711
  • 4
  • 9
  • So simple, upvoted and accepted (I need the var globally because after I grab the data I have a boat load of other processing to do and embedding it into the handler will not work) – KevinDTimm Jun 01 '11 at 16:32
  • 5
    Don't know your real context, but the best way to handle a lot of post-processing is to put the POST data in some kind of `queue` and have a backend server process which consume the queue. – Kaltezar Jun 01 '11 at 16:50
  • 3
    Why is the only solution using global-variable? – NoBugs Jan 06 '16 at 16:20
  • works fantastically, I've been looking for this all day.... thanks! :) – Adjam Jan 18 '23 at 23:55
8

The BaseHTTPServer is available as an attribute on the BaseHTTPRequestHandler. That means that you can make the postVars available on the server.

If you subclass the BaseHTTPServer like:

class MyServer(BaseHTTPServer.HTTPServer):
    def __init__(self, *args, **kwargs):
         # Because HTTPServer is an old-style class, super() can't be used.
         BaseHTTPServer.HTTPServer.__init__(self, *args, **kwargs)
         self.postVars = None

You can use this server to save the postVars on the server like:

class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):

    def do_POST(s):
        s.send_response(200)
        s.end_headers()
        varLen = int(s.headers['Content-Length'])
        s.server.postVars = s.rfile.read(varLen)
        print postVars

And then off course use MyServer instead of BaseHTTPServer:

server_class = MyServer
httpd = server_class((HOST_NAME, PORT_NUMBER), MyHandler)

print httpd.postVars

In general that solution would be preferable to having a global variable.

Tarik
  • 10,810
  • 2
  • 26
  • 40
BakaKuna
  • 585
  • 4
  • 13
  • 1
    this should be the accepted answer. Global variables usually cause a major headache later on. Thank you very much – Benjamin Maier Mar 24 '19 at 11:08
  • This is the best answer. During my hours of search, i knew that i needed to store it in the server, because a new request handler instance is generated after every GET operation. I needed to find a way to access the server and I was going to read all the source code if this wasn't here. In my class, it's `self.server` for those who want to copy lol – Orhan G. Hafif Oct 10 '19 at 18:46