s-hunter
s-hunter

Reputation: 25826

Getting GET and POST Request data in Python BaseHTTPServer

I am getting this error when trying to get the GET and POST data.

Exception happened during processing of request from ('127.0.0.1', 62635)
Traceback (most recent call last):
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 321, in process_request
    self.finish_request(request, client_address)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 655, in __init__
    self.handle()
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/BaseHTTPServer.py", line 340, in handle
    self.handle_one_request()
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/BaseHTTPServer.py", line 328, in handle_one_request
    method()
  File "server1.py", line 30, in do_GET
    print form.getvalue["foo"]
TypeError: 'instancemethod' object has no attribute '__getitem__'

The code

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import SocketServer
import cgitb; cgitb.enable()
import cgi


class GP(BaseHTTPRequestHandler):
    def _set_headers(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
    def do_HEAD(self):
        self._set_headers()
    def do_GET(self):
        self._set_headers()
        form = cgi.FieldStorage()
        print form.getvalue["foo"]
        self.wfile.write("<html><body><h1>Get Request Received!</h1></body></html>")
    def do_POST(self):
        self._set_headers()
        form = cgi.FieldStorage()
        print form.getvalue["foo"]
        self.wfile.write("<html><body><h1>POST Request Received!</h1></body></html>")

def run(server_class=HTTPServer, handler_class=GP, port=8088):
    server_address = ('', port)
    httpd = server_class(server_address, handler_class)
    print 'Server running at localhost:8088...'
    httpd.serve_forever()

run()

Running the code and I got the above errors. What's wrong in this code?

python server1.py
curl http://localhost:8088?foo=bar
curl -d "foo=bar" http://localhost:8088

Upvotes: 1

Views: 7562

Answers (2)

s-hunter
s-hunter

Reputation: 25826

The working version based on the answer from Binary Birch Tree

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from urlparse import parse_qs
import cgi

class GP(BaseHTTPRequestHandler):
    def _set_headers(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
    def do_HEAD(self):
        self._set_headers()
    def do_GET(self):
        self._set_headers()
        print parse_qs(self.path[2:])
        self.wfile.write("<html><body><h1>Get Request Received!</h1></body></html>")
    def do_POST(self):
        self._set_headers()
        form = cgi.FieldStorage(
            fp=self.rfile,
            headers=self.headers,
            environ={'REQUEST_METHOD': 'POST'}
        )
        print form.getvalue("foo")
        self.wfile.write("<html><body><h1>POST Request Received!</h1></body></html>")

def run(server_class=HTTPServer, handler_class=GP, port=8088):
    server_address = ('', port)
    httpd = server_class(server_address, handler_class)
    print 'Server running at localhost:8088...'
    httpd.serve_forever()

run()

Upvotes: 2

Binary Birch Tree
Binary Birch Tree

Reputation: 15748

To solve the immediate error, you can use:

form.getvalue("foo")

instead of:

form.getvalue["foo"]

which was causing:

TypeError: 'instancemethod' object has no attribute '__getitem__'

In addition (as suggested in https://stackoverflow.com/a/25091973), you may want to use:

form = cgi.FieldStorage(
    fp=self.rfile,
    headers=self.headers,
    environ={'REQUEST_METHOD': 'POST'}
)

instead of:

form = cgi.FieldStorage()

in the POST request handler.

In the GET request handler, you may want to use urlparse.parse_qs (for Python 2) or urllib.parse.parse_qs (for Python 3) instead of cgi.FieldStorage.

Upvotes: 6

Related Questions