Tuesday, April 27, 2010

HTTP Redirection, Take 2

Further to the comment posted, here is a revised version for redirection driven by configuration file.

#! /usr/local/bin/python


import sys, os
import BaseHTTPServer


if len(sys.argv) != 2:
    sys.stderr.write("Usage: %s &lgt;config-file>\n" % sys.argv[0])
    sys.exit(1)



#
# config file:
# 1 line 2 fields (port, url)
#
config = sys.argv[1]
if not os.path.exists(config):
    sys.stderr.write("Error. Config file '%s' does not exist" % config)
    sys.exit(2)
else:
    fp = open(config, 'r')
    (port, url) = fp.readline().rstrip().split()



class RedirectHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    # just redirect regardless of uri
    def do_GET(s):
        s.send_response(302)
        s.send_header('Location', url)
        s.end_headers()

    # ignore output
    def log_message(s, format, *args):
        pass



if __name__ == '__main__':
    server_class = BaseHTTPServer.HTTPServer
    httpd = server_class( ('', int(port)), RedirectHandler)
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass
    httpd.server_close()

Sample content of a typical file to listen at port 1668 to www.google.com:

1668 http://www.google.com/

Tested on my Cygwin

Labels:

Wednesday, April 21, 2010

HTTP Redirection

If you need a self-contained web server to handle redirection, you can try this simply Python code. It simple extends the base BaseHTTPServer class.

#! /usr/bin/python


import sys
import BaseHTTPServer


nerror=0
if len(sys.argv) >= 4:

    try:
        port = int(sys.argv[1])
    except:
        nerror += 1

    args = sys.argv[2:]
    if len(args) % 2 == 0:
        mapping = dict( zip(args[::2], args[1::2]) )
    else:
        nerror += 1
else:
    nerror += 1


if nerror > 0:
    sys.stderr.write(\
        "Usage: %s <port> <uri> <redirect> [<uri> <redirect>]" \
        % \
        sys.argv[0])
    exit(0)



class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_GET(s):
        if s.path in mapping:
            url = mapping[s.path]
            s.send_response(302)
            s.send_header('Location', url)
            s.end_headers()
        else:
            s.send_response(200)
            s.send_header('Content-type', 'text/html')
            s.end_headers()
            s.wfile.write("<html><head><title>List of Redirection</title>")
            s.wfile.write("</head><body><h1>List of Redirection</h1><hr>")
            s.wfile.write("<ul>")
            uris = mapping.keys()
            uris.sort()
            for uri in uris:
                redirect = mapping[uri]
                s.wfile.write("<li><a href=%s>%s -> %s</a>" % (redirect,
uri, redirect))
            s.wfile.write("</ul></body></html>")


    # ignore output
    def log_message(s, format, *args):
        pass



if __name__ == '__main__':
    server_class = BaseHTTPServer.HTTPServer
    httpd = server_class(('', port), MyHandler)
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass
    httpd.server_close()

Launch it like this:

$ ./redirect.py
Usage: ./redirect.py <port> <uri> <redirect> [<uri> <redirect>]

$ ./redirect.py  8080 \
  / http://chihungchan.blogspot.com/ \
  /g http://www.google.com/ \
  /c http://www.cnn.com/ \
  /s http://www.sg/

If you forget what are the short url redirection, simply key in bogus URI

Labels:

Tuesday, April 20, 2010

Intel Guide for Developing Multithreaded Applications

Intel Guide for Developing Multithreaded Applications:

Labels:

Wednesday, April 14, 2010

How Deep Is The Directory Structure

Recently our Netbackup failed due to some very long full-path name, guess what's the max length of the full-path? The length is 1037 character long. Below one-liner can tell you how deep is your directory and the corresponding directory I am running this in my home directory under Cygwin.
$ find /home/user -type d | awk -F"/" '{if(NF>max){max=NF;maxpath=$0}}END{print max-1, maxpath}'
12 /home/user/src/Django-1.1.1/build/lib/django/contrib/gis/db/backend/mysql

Labels:

File Uploading, 100% Python

I was trying to mix Perl and Python to achieve file uploading anywhere. After digging into the details of the BaseHTTPServer, I managed to craft out a 100% Python implementation. Together with my downloading server, I am now able to transfer files with ease in my current 'restricted' environment.
#! /usr/bin/python


import BaseHTTPServer
import os, cgi, re, random, platform


class GetHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_GET(self):
        message = '<title>Upload</title>\
            <form action=/ method=POST ENCTYPE=multipart/form-data>\
            <input type=file name=upfile> <input type=submit value=Upload>\
            </form></body></html>'
        self.send_response(200)
        self.end_headers()
        self.wfile.write(message)
        return

    def do_POST(self):
        form = cgi.FieldStorage(fp=self.rfile, headers=self.headers, \
            environ={'REQUEST_METHOD':'POST', 'CONTENT_TYPE':self.headers['Content-Type'], })
        upfile = form['upfile']

        # extract basename of input filename, remove non-alphanumeric characters
        if '\\' in upfile.filename:
            filename = upfile.filename.split('\\')[-1]
        else:
            filename = upfile.filename.split('/')[-1]
        filename = re.sub('[ \t]','-', filename)
        filename = re.sub('[^a-zA-Z0-9_.:-]','', filename)

        fp = open(filename, 'wb')
        while True:
            chunk = upfile.file.read(8192)
            if len(chunk) == 0:
                break
            else:
                fp.write(chunk)
        fp.close()
        self.send_response(200)
        self.end_headers()
        self.wfile.write('<html><head><title>Upload</title></head><body>\
            <h1>Successfully uploaded</h1><br>From: %s<br>To: %s</body></html>' % \
            (upfile.filename, os.sep.join([os.getcwd(), filename])) )



if __name__ == '__main__':
    try:
        port = random.randint(50000,60000)
        url = "http://%s:%d/" % (platform.node(), port)
        server = BaseHTTPServer.HTTPServer( ('', port), GetHandler )
        print "Ask user to visit this URL:\n\t%s" % url
        server.serve_forever()
    except KeyboardInterrupt:
        pass

Labels: