28

I wrote a simple HTTP client and server in Python for experimenting. The first code snippet below shows how I send an HTTP GET request with a parameter named imsi. In the second code snippet I show my do_Get function implementation in the server side. My question is how I can extract the imsi parameter in the server code and send a response back to the client in order to signal the client that imsi is valid.
Thanks.

P.S.: I verified that the client sends the request successfully.

CLIENT code snippet

    params = urllib.urlencode({'imsi': str(imsi)})
    conn = httplib.HTTPConnection(host + ':' + str(port))
    #conn.set_debuglevel(1)
    conn.request("GET", "/index.htm", 'imsi=' + str(imsi))
    r = conn.getresponse()

SERVER code snippet

import sys, string, cStringIO, cgi, time, datetime
from os import curdir, sep
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer

class MyHandler(BaseHTTPRequestHandler):

# I want to extract the imsi parameter here and send a success response to 
# back to the client.
def do_GET(self):
    try:
        if self.path.endswith(".html"):
            #self.path has /index.htm
            f = open(curdir + sep + self.path)
            self.send_response(200)
            self.send_header('Content-type','text/html')
            self.end_headers()
            self.wfile.write("<h1>Device Static Content</h1>")
            self.wfile.write(f.read())
            f.close()
            return
        if self.path.endswith(".esp"):   #our dynamic content
            self.send_response(200)
            self.send_header('Content-type','text/html')
            self.end_headers()
            self.wfile.write("<h1>Dynamic Dynamic Content</h1>")
            self.wfile.write("Today is the " + str(time.localtime()[7]))
            self.wfile.write(" day in the year " + str(time.localtime()[0]))
            return

        # The root
        self.send_response(200)
        self.send_header('Content-type','text/html')
        self.end_headers()

        lst = list(sys.argv[1])
        n = lst[len(lst) - 1]
        now = datetime.datetime.now()

        output = cStringIO.StringIO()
        output.write("<html><head>")
        output.write("<style type=\"text/css\">")
        output.write("h1 {color:blue;}")
        output.write("h2 {color:red;}")
        output.write("</style>")
        output.write("<h1>Device #" + n + " Root Content</h1>")
        output.write("<h2>Device Addr: " + sys.argv[1] + ":" + sys.argv[2] + "</h1>")
        output.write("<h2>Device Time: " + now.strftime("%Y-%m-%d %H:%M:%S") + "</h2>")
        output.write("</body>")
        output.write("</html>")

        self.wfile.write(output.getvalue())

        return

    except IOError:
        self.send_error(404,'File Not Found: %s' % self.path)
2

4 Answers 4

62

You can parse the query of a GET request using urlparse, then split the query string.

from urlparse import urlparse
query = urlparse(self.path).query
query_components = dict(qc.split("=") for qc in query.split("&"))
imsi = query_components["imsi"]
# query_components = { "imsi" : "Hello" }

# Or use the parse_qs method
from urlparse import urlparse, parse_qs
query_components = parse_qs(urlparse(self.path).query)
imsi = query_components["imsi"] 
# query_components = { "imsi" : ["Hello"] }

You can confirm this by using

 curl http://your.host/?imsi=Hello
Sign up to request clarification or add additional context in comments.

2 Comments

& is a shell special character ... Needs to be escaped so your curl command passes both params
With Python 3, use from urllib.parse import urlparse source: stackoverflow.com/a/5239594/4669135
22

BaseHTTPServer is a pretty low-level server. Generally you want to use a real web framework that does this kind of grunt work for you, but since you asked...

First import a url parsing library. In Python 2,x it's urlparse. (In Python3, you'd use urllib.parse)

import urlparse

Then, in your do_get method, parse the query string.

imsi = urlparse.parse_qs(urlparse.urlparse(self.path).query).get('imsi', None)
print imsi  # Prints None or the string value of imsi

Also, you could be using urllib in your client code and it would probably be a lot easier.

Comments

2

If you dont want to import additional libraries in most cases you can use:

i = self.path.index ( "?" ) + 1
params = dict ( [ tuple ( p.split("=") ) for p in self.path[i:].split ( "&" ) ] )

Comments

0

cgi module contains FieldStorage class which is supposed to be used in CGI context, but seems to be easily used in your context as well.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.