summaryrefslogtreecommitdiff
blob: dc88978519b03c2c78b0c7985cb82e7b32d71000 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import sys, os, cgi, string, random, Cookie
from StringIO import StringIO
from os.path import dirname, realpath, join as pjoin
from SimpleHTTPServer import SimpleHTTPRequestHandler

chars = string.ascii_letters + string.digits
sessionDict = {} # dictionary mapping session id's to session objects

class SessionElement(object):
    """Arbitrary objects, referenced by the session id"""
    d = {}

def generateRandom(length):
    """Return a random string of specified length (used for session id's)"""
    return ''.join([random.choice(chars) for _ in range(length)])

class HTTP_REDIRECTION(Exception):
    pass


class MyRequestHandler(SimpleHTTPRequestHandler):

    pages = pjoin(dirname(realpath(__file__)), 'pages/')

    def getFile(self, localpath):
        try:
            fs = file(localpath, 'rb')
            ctype = self.guess_type(localpath)
        except:
            self.send_error(404, "File " + localpath + " not found")
            return

        self.send_response(200)
        self.send_header("Content-type", ctype)
        fss = os.fstat(fs.fileno())
        self.send_header("Content-Length", str(fss[6]))
        self.send_header("Last-Modified", self.date_time_string(fss.st_mtime))
        self.end_headers()
        self.copyfile(fs, self.wfile)
        fs.close()
    
    
    def writeContent(self, text, ctype='text/plain'):
        self.send_response(200)
        self.send_header("Content-type", ctype)
        self.send_header("Content-Length", len(text))
        self.end_headers()
        self.wfile.write(text)

    def checkLogin(self):
        self.cookie = Cookie.SimpleCookie()
        if self.headers.has_key('cookie'):
            self.cookie = Cookie.SimpleCookie(self.headers.getheader("cookie"))
            
        sd = self.Session().d
        print 'Session dictionary:', sd
        if 'login' not in sd and not self.path.startswith('/login'):
            sd['requested'] = self.path
            
            self.send_response(301)
            for m in self.cookie.values():
                self.send_header('Set-Cookie', m.output(header='').lstrip())
            self.send_header('Location', '/login.html')
            self.end_headers()
            return False
        
        return True


    def do_GET(self):
        print "Requested path", self.path
        
        if not self.checkLogin():
            return
        
        print "Ok, we are in", self.path
        
        path = self.path

        if path == '/':
            return self.getFile(pjoin(self.pages, 'index.html'))

        if path.startswith('/info/'):
            return self.getInfo(path[6:])

        if path.startswith('/results'):
            return self.getFile(path[8:])

        # Remove leading slashes
        while path[0] == '/':
            path = path[1:]
        return self.getFile(pjoin(self.pages, path))

        print "Translated", self.path
        self.send_response(400)
        self.end_headers()

    def do_POST(self):
        print "Requested path", self.path
        
        if not self.checkLogin():
            return
        
        # Create FieldStorage from POST request
        form = cgi.FieldStorage(
            fp=self.rfile,
            headers=self.headers,
            environ={'REQUEST_METHOD':'POST',
                     'CONTENT_TYPE':self.headers['Content-Type'],
                     })
        
        # Get requested action
        action = form.getvalue('action', self.path[1:])
        if not action.endswith('.py'):
            action = action + '.py'
        print "Requested", action
        
        # Call the action in a special environment
        output = StringIO()
        tmpout = sys.stdout
        sys.stdout = output
        
        execfile(pjoin(dirname(realpath(__file__)), 'actions', action),
                 dict(form=form, Session=self.Session))
        
        sys.stdout = tmpout
        text = output.getvalue()
        
        self.writeContent(text, 'text/html')


    def Session(self):
        """Session management
        If the client has sent a cookie named sessionId, take its value and 
        return the corresponding SessionElement objet, stored in 
        sessionDict
        Otherwise create a new SessionElement objet and generate a random
        8-letters value sent back to the client as the value for a cookie
        called sessionId"""
        if self.cookie.has_key("sessionId"):
            sessionId = self.cookie["sessionId"].value
        else:
            sessionId = generateRandom(8)
            self.cookie["sessionId"] = sessionId
        try:
            sessionObject = sessionDict[sessionId]
        except KeyError:
            sessionObject = SessionElement()
            sessionDict[sessionId] = sessionObject
        return sessionObject