comparison pycaptcha/http_example.py @ 87:4775b4195b4b

code pour la generation de captchas
author goldfinger
date Thu, 11 Feb 2010 05:09:46 -0500
parents
children
comparison
equal deleted inserted replaced
86:b3d76ebf2fac 87:4775b4195b4b
1 #!/usr/bin/env python
2 #
3 # An example that presents CAPTCHA tests in a web environment
4 # and gives the user a chance to solve them. Run it, optionally
5 # specifying a port number on the command line, then point your web
6 # browser at the given URL.
7 #
8
9 from Captcha.Visual import Tests
10 from Captcha import Factory
11 import BaseHTTPServer, urlparse, sys
12
13
14 class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
15 def do_GET(self):
16 scheme, host, path, parameters, query, fragment = urlparse.urlparse(self.path)
17
18 # Split the path into segments
19 pathSegments = path.split('/')[1:]
20
21 # Split the query into key-value pairs
22 args = {}
23 for pair in query.split("&"):
24 if pair.find("=") >= 0:
25 key, value = pair.split("=", 1)
26 args.setdefault(key, []).append(value)
27 else:
28 args[pair] = []
29
30 # A hack so it works with a proxy configured for VHostMonster :)
31 if pathSegments[0] == "vhost":
32 pathSegments = pathSegments[3:]
33
34 if pathSegments[0] == "":
35 self.handleRootPage(args.get('test', Tests.__all__)[0])
36
37 elif pathSegments[0] == "images":
38 self.handleImagePage(pathSegments[1])
39
40 elif pathSegments[0] == "solutions":
41 self.handleSolutionPage(pathSegments[1], args['word'][0])
42
43 else:
44 self.handle404()
45
46 def handle404(self):
47 self.send_response(404)
48 self.send_header("Content-Type", "text/html")
49 self.end_headers()
50 self.wfile.write("<html><body><h1>No such resource</h1></body></html>")
51
52 def handleRootPage(self, testName):
53 self.send_response(200)
54 self.send_header("Content-Type", "text/html")
55 self.end_headers()
56
57 test = self.captchaFactory.new(getattr(Tests, testName))
58
59 # Make a list of tests other than the one we're using
60 others = []
61 for t in Tests.__all__:
62 if t != testName:
63 others.append('<li><a href="/?test=%s">%s</a></li>' % (t,t))
64 others = "\n".join(others)
65
66 self.wfile.write("""<html>
67 <head>
68 <title>PyCAPTCHA Example</title>
69 </head>
70 <body>
71 <h1>PyCAPTCHA Example</h1>
72 <p>
73 <b>%s</b>:
74 %s
75 </p>
76
77 <p><img src="/images/%s"/></p>
78 <p>
79 <form action="/solutions/%s" method="get">
80 Enter the word shown:
81 <input type="text" name="word"/>
82 </form>
83 </p>
84
85 <p>
86 Or try...
87 <ul>
88 %s
89 </ul>
90 </p>
91
92 </body>
93 </html>
94 """ % (test.__class__.__name__, test.__doc__, test.id, test.id, others))
95
96 def handleImagePage(self, id):
97 test = self.captchaFactory.get(id)
98 if not test:
99 return self.handle404()
100
101 self.send_response(200)
102 self.send_header("Content-Type", "image/jpeg")
103 self.end_headers()
104 test.render().save(self.wfile, "JPEG")
105
106 def handleSolutionPage(self, id, word):
107 test = self.captchaFactory.get(id)
108 if not test:
109 return self.handle404()
110
111 if not test.valid:
112 # Invalid tests will always return False, to prevent
113 # random trial-and-error attacks. This could be confusing to a user...
114 result = "Test invalidated, try another test"
115 elif test.testSolutions([word]):
116 result = "Correct"
117 else:
118 result = "Incorrect"
119
120 self.send_response(200)
121 self.send_header("Content-Type", "text/html")
122 self.end_headers()
123 self.wfile.write("""<html>
124 <head>
125 <title>PyCAPTCHA Example</title>
126 </head>
127 <body>
128 <h1>PyCAPTCHA Example</h1>
129 <h2>%s</h2>
130 <p><img src="/images/%s"/></p>
131 <p><b>%s</b></p>
132 <p>You guessed: %s</p>
133 <p>Possible solutions: %s</p>
134 <p><a href="/">Try again</a></p>
135 </body>
136 </html>
137 """ % (test.__class__.__name__, test.id, result, word, ", ".join(test.solutions)))
138
139
140 def main(port):
141 print "Starting server at http://localhost:%d/" % port
142 handler = RequestHandler
143 handler.captchaFactory = Factory()
144 BaseHTTPServer.HTTPServer(('', port), RequestHandler).serve_forever()
145
146 if __name__ == "__main__":
147 # The port number can be specified on the command line, default is 8080
148 if len(sys.argv) >= 2:
149 port = int(sys.argv[1])
150 else:
151 port = 8080
152 main(port)
153
154 ### The End ###