]> code.delx.au - gnu-emacs/blob - test/cedet/tests/test.py
Merge from `emacs-23'.
[gnu-emacs] / test / cedet / tests / test.py
1 # Test file for Python language.
2 #
3
4 # Simle class compount statement with blank lines sprinkled.
5 class Foo(Bar):
6
7 x = 1
8
9 y = 2
10
11 # Simple def statement with no argument
12 def sss():
13 i = 1
14
15 # Simple def statement with arguments
16 def ttt(x,y,z):
17 i = 1
18
19 import foo
20
21 for x in y:
22 print x
23
24 while y > 0:
25 y = y - 1
26
27 a=b=c=d=e=f=i=j=k=l=m=n=o=p=q=r=s=t=x=y=1
28
29 if x:
30 x = 2
31 y = 3
32
33 x = 2
34 y = 3
35 s and t
36 q | r
37 o ^ p
38 m & n
39 k << l
40 z = 4
41 i >> j
42 e / f
43 c * d
44 a + b
45 2 ** 5
46 x
47 s = "a" "b" "c"
48 1
49
50 # implicit continuation lines, see
51 # http://docs.python.org/ref/implicit-joining.html
52
53 a_list = [ 1, 2, 3,
54 4, 5,
55 6 ]
56
57 a_tuple = (1, 2, 3,
58
59 4, 5, 6)
60
61 a_hash = { 'a':1, "b":2,
62 'c' : 3,
63 "d" : 4 }
64
65
66 def longarglist(a,
67 b,
68 c,
69 d):
70 a=1;
71 b=1;
72 c=1;
73 d=1;
74
75 class longclasslist(xx.yyy,
76 zz.aa):
77 foo=1
78
79
80 # wisent-python.wy chokes on this! -ryk 6/17/02
81
82 class HTTPServer(xxx.yyy):
83 allow_reuse_address = 1 # Seems to make sense in testing environment
84 def server_bind(self):
85 SocketServer.TCPServer.server_bind(self)
86 host, port = self.socket.getsockname()
87 self.server_name = socket.getfqdn(host)
88 self.server_port = port
89
90
91 #########################################################################
92 ### /usr/lib/python2.2/BaseHTTPServer.py
93 #########################################################################
94
95 """HTTP server base class.
96
97 Note: the class in this module doesn't implement any HTTP request; see
98 SimpleHTTPServer for simple implementations of GET, HEAD and POST
99 (including CGI scripts).
100
101 Contents:
102
103 - BaseHTTPRequestHandler: HTTP request handler base class
104 - test: test function
105
106 XXX To do:
107
108 - send server version
109 - log requests even later (to capture byte count)
110 - log user-agent header and other interesting goodies
111 - send error log to separate file
112 - are request names really case sensitive?
113
114 """
115
116
117 # See also:
118 #
119 # HTTP Working Group T. Berners-Lee
120 # INTERNET-DRAFT R. T. Fielding
121 # <draft-ietf-http-v10-spec-00.txt> H. Frystyk Nielsen
122 # Expires September 8, 1995 March 8, 1995
123 #
124 # URL: http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-v10-spec-00.txt
125
126
127 # Log files
128 # ---------
129 #
130 # Here's a quote from the NCSA httpd docs about log file format.
131 #
132 # | The logfile format is as follows. Each line consists of:
133 # |
134 # | host rfc931 authuser [DD/Mon/YYYY:hh:mm:ss] "request" ddd bbbb
135 # |
136 # | host: Either the DNS name or the IP number of the remote client
137 # | rfc931: Any information returned by identd for this person,
138 # | - otherwise.
139 # | authuser: If user sent a userid for authentication, the user name,
140 # | - otherwise.
141 # | DD: Day
142 # | Mon: Month (calendar name)
143 # | YYYY: Year
144 # | hh: hour (24-hour format, the machine's timezone)
145 # | mm: minutes
146 # | ss: seconds
147 # | request: The first line of the HTTP request as sent by the client.
148 # | ddd: the status code returned by the server, - if not available.
149 # | bbbb: the total number of bytes sent,
150 # | *not including the HTTP/1.0 header*, - if not available
151 # |
152 # | You can determine the name of the file accessed through request.
153 #
154 # (Actually, the latter is only true if you know the server configuration
155 # at the time the request was made!)
156
157
158 __version__ = "0.2"
159
160 __all__ = ["HTTPServer", "BaseHTTPRequestHandler"]
161
162 import sys
163 import time
164 import socket # For gethostbyaddr()
165 import mimetools
166 import SocketServer
167
168 # Default error message
169 DEFAULT_ERROR_MESSAGE = """\
170 <head>
171 <title>Error response</title>
172 </head>
173 <body>
174 <h1>Error response</h1>
175 <p>Error code %(code)d.
176 <p>Message: %(message)s.
177 <p>Error code explanation: %(code)s = %(explain)s.
178 </body>
179 """
180
181
182 class HTTPServer(SocketServer.TCPServer):
183
184 allow_reuse_address = 1 # Seems to make sense in testing environment
185
186 def server_bind(self):
187 """Override server_bind to store the server name."""
188 SocketServer.TCPServer.server_bind(self)
189 host, port = self.socket.getsockname()
190 self.server_name = socket.getfqdn(host)
191 self.server_port = port
192
193
194 class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
195
196 """HTTP request handler base class.
197
198 The following explanation of HTTP serves to guide you through the
199 code as well as to expose any misunderstandings I may have about
200 HTTP (so you don't need to read the code to figure out I'm wrong
201 :-).
202
203 HTTP (HyperText Transfer Protocol) is an extensible protocol on
204 top of a reliable stream transport (e.g. TCP/IP). The protocol
205 recognizes three parts to a request:
206
207 1. One line identifying the request type and path
208 2. An optional set of RFC-822-style headers
209 3. An optional data part
210
211 The headers and data are separated by a blank line.
212
213 The first line of the request has the form
214
215 <command> <path> <version>
216
217 where <command> is a (case-sensitive) keyword such as GET or POST,
218 <path> is a string containing path information for the request,
219 and <version> should be the string "HTTP/1.0". <path> is encoded
220 using the URL encoding scheme (using %xx to signify the ASCII
221 character with hex code xx).
222
223 The protocol is vague about whether lines are separated by LF
224 characters or by CRLF pairs -- for compatibility with the widest
225 range of clients, both should be accepted. Similarly, whitespace
226 in the request line should be treated sensibly (allowing multiple
227 spaces between components and allowing trailing whitespace).
228
229 Similarly, for output, lines ought to be separated by CRLF pairs
230 but most clients grok LF characters just fine.
231
232 If the first line of the request has the form
233
234 <command> <path>
235
236 (i.e. <version> is left out) then this is assumed to be an HTTP
237 0.9 request; this form has no optional headers and data part and
238 the reply consists of just the data.
239
240 The reply form of the HTTP 1.0 protocol again has three parts:
241
242 1. One line giving the response code
243 2. An optional set of RFC-822-style headers
244 3. The data
245
246 Again, the headers and data are separated by a blank line.
247
248 The response code line has the form
249
250 <version> <responsecode> <responsestring>
251
252 where <version> is the protocol version (always "HTTP/1.0"),
253 <responsecode> is a 3-digit response code indicating success or
254 failure of the request, and <responsestring> is an optional
255 human-readable string explaining what the response code means.
256
257 This server parses the request and the headers, and then calls a
258 function specific to the request type (<command>). Specifically,
259 a request SPAM will be handled by a method do_SPAM(). If no
260 such method exists the server sends an error response to the
261 client. If it exists, it is called with no arguments:
262
263 do_SPAM()
264
265 Note that the request name is case sensitive (i.e. SPAM and spam
266 are different requests).
267
268 The various request details are stored in instance variables:
269
270 - client_address is the client IP address in the form (host,
271 port);
272
273 - command, path and version are the broken-down request line;
274
275 - headers is an instance of mimetools.Message (or a derived
276 class) containing the header information;
277
278 - rfile is a file object open for reading positioned at the
279 start of the optional input data part;
280
281 - wfile is a file object open for writing.
282
283 IT IS IMPORTANT TO ADHERE TO THE PROTOCOL FOR WRITING!
284
285 The first thing to be written must be the response line. Then
286 follow 0 or more header lines, then a blank line, and then the
287 actual data (if any). The meaning of the header lines depends on
288 the command executed by the server; in most cases, when data is
289 returned, there should be at least one header line of the form
290
291 Content-type: <type>/<subtype>
292
293 where <type> and <subtype> should be registered MIME types,
294 e.g. "text/html" or "text/plain".
295
296 """
297
298 # The Python system version, truncated to its first component.
299 sys_version = "Python/" + sys.version.split()[0]
300
301 # The server software version. You may want to override this.
302 # The format is multiple whitespace-separated strings,
303 # where each string is of the form name[/version].
304 server_version = "BaseHTTP/" + __version__
305
306 def parse_request(self):
307 """Parse a request (internal).
308
309 The request should be stored in self.raw_request; the results
310 are in self.command, self.path, self.request_version and
311 self.headers.
312
313 Return value is 1 for success, 0 for failure; on failure, an
314 error is sent back.
315
316 """
317 self.request_version = version = "HTTP/0.9" # Default
318 requestline = self.raw_requestline
319 if requestline[-2:] == '\r\n':
320 requestline = requestline[:-2]
321 elif requestline[-1:] == '\n':
322 requestline = requestline[:-1]
323 self.requestline = requestline
324 words = requestline.split()
325 if len(words) == 3:
326 [command, path, version] = words
327 if version[:5] != 'HTTP/':
328 self.send_error(400, "Bad request version (%s)" % `version`)
329 return 0
330 elif len(words) == 2:
331 [command, path] = words
332 if command != 'GET':
333 self.send_error(400,
334 "Bad HTTP/0.9 request type (%s)" % `command`)
335 return 0
336 else:
337 self.send_error(400, "Bad request syntax (%s)" % `requestline`)
338 return 0
339 self.command, self.path, self.request_version = command, path, version
340 self.headers = self.MessageClass(self.rfile, 0)
341 return 1
342
343 def handle(self):
344 """Handle a single HTTP request.
345
346 You normally don't need to override this method; see the class
347 __doc__ string for information on how to handle specific HTTP
348 commands such as GET and POST.
349
350 """
351
352 self.raw_requestline = self.rfile.readline()
353 if not self.parse_request(): # An error code has been sent, just exit
354 return
355 mname = 'do_' + self.command
356 if not hasattr(self, mname):
357 self.send_error(501, "Unsupported method (%s)" % `self.command`)
358 return
359 method = getattr(self, mname)
360 method()
361
362 def send_error(self, code, message=None):
363 """Send and log an error reply.
364
365 Arguments are the error code, and a detailed message.
366 The detailed message defaults to the short entry matching the
367 response code.
368
369 This sends an error response (so it must be called before any
370 output has been generated), logs the error, and finally sends
371 a piece of HTML explaining the error to the user.
372
373 """
374
375 try:
376 short, long = self.responses[code]
377 except KeyError:
378 short, long = '???', '???'
379 if not message:
380 message = short
381 explain = long
382 self.log_error("code %d, message %s", code, message)
383 self.send_response(code, message)
384 self.send_header("Content-Type", "text/html")
385 self.end_headers()
386 self.wfile.write(self.error_message_format %
387 {'code': code,
388 'message': message,
389 'explain': explain})
390
391 error_message_format = DEFAULT_ERROR_MESSAGE
392
393 def send_response(self, code, message=None):
394 """Send the response header and log the response code.
395
396 Also send two standard headers with the server software
397 version and the current date.
398
399 """
400 self.log_request(code)
401 if message is None:
402 if self.responses.has_key(code):
403 message = self.responses[code][0]
404 else:
405 message = ''
406 if self.request_version != 'HTTP/0.9':
407 self.wfile.write("%s %s %s\r\n" %
408 (self.protocol_version, str(code), message))
409 self.send_header('Server', self.version_string())
410 self.send_header('Date', self.date_time_string())
411
412 def send_header(self, keyword, value):
413 """Send a MIME header."""
414 if self.request_version != 'HTTP/0.9':
415 self.wfile.write("%s: %s\r\n" % (keyword, value))
416
417 def end_headers(self):
418 """Send the blank line ending the MIME headers."""
419 if self.request_version != 'HTTP/0.9':
420 self.wfile.write("\r\n")
421
422 def log_request(self, code='-', size='-'):
423 """Log an accepted request.
424
425 This is called by send_reponse().
426
427 """
428
429 self.log_message('"%s" %s %s',
430 self.requestline, str(code), str(size))
431
432 def log_error(self, *args):
433 """Log an error.
434
435 This is called when a request cannot be fulfilled. By
436 default it passes the message on to log_message().
437
438 Arguments are the same as for log_message().
439
440 XXX This should go to the separate error log.
441
442 """
443
444 apply(self.log_message, args)
445
446 def log_message(self, format, *args):
447 """Log an arbitrary message.
448
449 This is used by all other logging functions. Override
450 it if you have specific logging wishes.
451
452 The first argument, FORMAT, is a format string for the
453 message to be logged. If the format string contains
454 any % escapes requiring parameters, they should be
455 specified as subsequent arguments (it's just like
456 printf!).
457
458 The client host and current date/time are prefixed to
459 every message.
460
461 """
462
463 sys.stderr.write("%s - - [%s] %s\n" %
464 (self.address_string(),
465 self.log_date_time_string(),
466 format%args))
467
468 def version_string(self):
469 """Return the server software version string."""
470 return self.server_version + ' ' + self.sys_version
471
472 def date_time_string(self):
473 """Return the current date and time formatted for a message header."""
474 now = time.time()
475 year, month, day, hh, mm, ss, wd, y, z = time.gmtime(now)
476 s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
477 self.weekdayname[wd],
478 day, self.monthname[month], year,
479 hh, mm, ss)
480 return s
481
482 def log_date_time_string(self):
483 """Return the current time formatted for logging."""
484 now = time.time()
485 year, month, day, hh, mm, ss, x, y, z = time.localtime(now)
486 s = "%02d/%3s/%04d %02d:%02d:%02d" % (
487 day, self.monthname[month], year, hh, mm, ss)
488 return s
489
490 weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
491
492 monthname = [None,
493 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
494 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
495
496 def address_string(self):
497 """Return the client address formatted for logging.
498
499 This version looks up the full hostname using gethostbyaddr(),
500 and tries to find a name that contains at least one dot.
501
502 """
503
504 host, port = self.client_address
505 return socket.getfqdn(host)
506
507 # Essentially static class variables
508
509 # The version of the HTTP protocol we support.
510 # Don't override unless you know what you're doing (hint: incoming
511 # requests are required to have exactly this version string).
512 protocol_version = "HTTP/1.0"
513
514 # The Message-like class used to parse headers
515 MessageClass = mimetools.Message
516
517 # Table mapping response codes to messages; entries have the
518 # form {code: (shortmessage, longmessage)}.
519 # See http://www.w3.org/hypertext/WWW/Protocols/HTTP/HTRESP.html
520 responses = {
521 200: ('OK', 'Request fulfilled, document follows'),
522 201: ('Created', 'Document created, URL follows'),
523 202: ('Accepted',
524 'Request accepted, processing continues off-line'),
525 203: ('Partial information', 'Request fulfilled from cache'),
526 204: ('No response', 'Request fulfilled, nothing follows'),
527
528 301: ('Moved', 'Object moved permanently -- see URI list'),
529 302: ('Found', 'Object moved temporarily -- see URI list'),
530 303: ('Method', 'Object moved -- see Method and URL list'),
531 304: ('Not modified',
532 'Document has not changed singe given time'),
533
534 400: ('Bad request',
535 'Bad request syntax or unsupported method'),
536 401: ('Unauthorized',
537 'No permission -- see authorization schemes'),
538 402: ('Payment required',
539 'No payment -- see charging schemes'),
540 403: ('Forbidden',
541 'Request forbidden -- authorization will not help'),
542 404: ('Not found', 'Nothing matches the given URI'),
543
544 500: ('Internal error', 'Server got itself in trouble'),
545 501: ('Not implemented',
546 'Server does not support this operation'),
547 502: ('Service temporarily overloaded',
548 'The server cannot process the request due to a high load'),
549 503: ('Gateway timeout',
550 'The gateway server did not receive a timely response'),
551
552 }
553
554
555 def test(HandlerClass = BaseHTTPRequestHandler,
556 ServerClass = HTTPServer):
557 """Test the HTTP request handler class.
558
559 This runs an HTTP server on port 8000 (or the first command line
560 argument).
561
562 """
563
564 if sys.argv[1:]:
565 port = int(sys.argv[1])
566 else:
567 port = 8000
568 server_address = ('', port)
569
570 httpd = ServerClass(server_address, HandlerClass)
571
572 sa = httpd.socket.getsockname()
573 print "Serving HTTP on", sa[0], "port", sa[1], "..."
574 httpd.serve_forever()
575
576
577 if __name__ == '__main__':
578 test()
579
580 # arch-tag: 567449b3-cc90-45b6-bbe3-1e113995bdae