OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """This is a simple HTTP/FTP/SYNC/TCP/UDP/ server used for testing Chrome. | 6 """This is a simple HTTP/FTP/SYNC/TCP/UDP/ server used for testing Chrome. |
7 | 7 |
8 It supports several test URLs, as specified by the handlers in TestPageHandler. | 8 It supports several test URLs, as specified by the handlers in TestPageHandler. |
9 By default, it listens on an ephemeral port and sends the port number back to | 9 By default, it listens on an ephemeral port and sends the port number back to |
10 the originating process over a pipe. The originating process can specify an | 10 the originating process over a pipe. The originating process can specify an |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 self.stop = False | 259 self.stop = False |
260 self.nonce_time = None | 260 self.nonce_time = None |
261 while not self.stop: | 261 while not self.stop: |
262 self.handle_request() | 262 self.handle_request() |
263 self.socket.close() | 263 self.socket.close() |
264 | 264 |
265 | 265 |
266 class BasePageHandler(BaseHTTPServer.BaseHTTPRequestHandler): | 266 class BasePageHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
267 | 267 |
268 def __init__(self, request, client_address, socket_server, | 268 def __init__(self, request, client_address, socket_server, |
269 connect_handlers, get_handlers, post_handlers, put_handlers): | 269 connect_handlers, get_handlers, head_handlers, post_handlers, |
| 270 put_handlers): |
270 self._connect_handlers = connect_handlers | 271 self._connect_handlers = connect_handlers |
271 self._get_handlers = get_handlers | 272 self._get_handlers = get_handlers |
| 273 self._head_handlers = head_handlers |
272 self._post_handlers = post_handlers | 274 self._post_handlers = post_handlers |
273 self._put_handlers = put_handlers | 275 self._put_handlers = put_handlers |
274 BaseHTTPServer.BaseHTTPRequestHandler.__init__( | 276 BaseHTTPServer.BaseHTTPRequestHandler.__init__( |
275 self, request, client_address, socket_server) | 277 self, request, client_address, socket_server) |
276 | 278 |
277 def log_request(self, *args, **kwargs): | 279 def log_request(self, *args, **kwargs): |
278 # Disable request logging to declutter test log output. | 280 # Disable request logging to declutter test log output. |
279 pass | 281 pass |
280 | 282 |
281 def _ShouldHandleRequest(self, handler_name): | 283 def _ShouldHandleRequest(self, handler_name): |
282 """Determines if the path can be handled by the handler. | 284 """Determines if the path can be handled by the handler. |
283 | 285 |
284 We consider a handler valid if the path begins with the | 286 We consider a handler valid if the path begins with the |
285 handler name. It can optionally be followed by "?*", "/*". | 287 handler name. It can optionally be followed by "?*", "/*". |
286 """ | 288 """ |
287 | 289 |
288 pattern = re.compile('%s($|\?|/).*' % handler_name) | 290 pattern = re.compile('%s($|\?|/).*' % handler_name) |
289 return pattern.match(self.path) | 291 return pattern.match(self.path) |
290 | 292 |
291 def do_CONNECT(self): | 293 def do_CONNECT(self): |
292 for handler in self._connect_handlers: | 294 for handler in self._connect_handlers: |
293 if handler(): | 295 if handler(): |
294 return | 296 return |
295 | 297 |
296 def do_GET(self): | 298 def do_GET(self): |
297 for handler in self._get_handlers: | 299 for handler in self._get_handlers: |
298 if handler(): | 300 if handler(): |
299 return | 301 return |
300 | 302 |
| 303 def do_HEAD(self): |
| 304 for handler in self._head_handlers: |
| 305 if handler(): |
| 306 return |
| 307 |
301 def do_POST(self): | 308 def do_POST(self): |
302 for handler in self._post_handlers: | 309 for handler in self._post_handlers: |
303 if handler(): | 310 if handler(): |
304 return | 311 return |
305 | 312 |
306 def do_PUT(self): | 313 def do_PUT(self): |
307 for handler in self._put_handlers: | 314 for handler in self._put_handlers: |
308 if handler(): | 315 if handler(): |
309 return | 316 return |
310 | 317 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 self.ChunkedServerHandler, | 351 self.ChunkedServerHandler, |
345 self.ContentTypeHandler, | 352 self.ContentTypeHandler, |
346 self.NoContentHandler, | 353 self.NoContentHandler, |
347 self.ServerRedirectHandler, | 354 self.ServerRedirectHandler, |
348 self.ClientRedirectHandler, | 355 self.ClientRedirectHandler, |
349 self.MultipartHandler, | 356 self.MultipartHandler, |
350 self.MultipartSlowHandler, | 357 self.MultipartSlowHandler, |
351 self.DefaultResponseHandler] | 358 self.DefaultResponseHandler] |
352 post_handlers = [ | 359 post_handlers = [ |
353 self.EchoTitleHandler, | 360 self.EchoTitleHandler, |
354 self.EchoAllHandler, | |
355 self.EchoHandler, | 361 self.EchoHandler, |
356 self.DeviceManagementHandler] + get_handlers | 362 self.DeviceManagementHandler] + get_handlers |
357 put_handlers = [ | 363 put_handlers = [ |
358 self.EchoTitleHandler, | 364 self.EchoTitleHandler, |
359 self.EchoAllHandler, | |
360 self.EchoHandler] + get_handlers | 365 self.EchoHandler] + get_handlers |
| 366 head_handlers = [ |
| 367 self.FileHandler, |
| 368 self.DefaultResponseHandler] |
361 | 369 |
362 self._mime_types = { | 370 self._mime_types = { |
363 'crx' : 'application/x-chrome-extension', | 371 'crx' : 'application/x-chrome-extension', |
364 'exe' : 'application/octet-stream', | 372 'exe' : 'application/octet-stream', |
365 'gif': 'image/gif', | 373 'gif': 'image/gif', |
366 'jpeg' : 'image/jpeg', | 374 'jpeg' : 'image/jpeg', |
367 'jpg' : 'image/jpeg', | 375 'jpg' : 'image/jpeg', |
368 'pdf' : 'application/pdf', | 376 'pdf' : 'application/pdf', |
369 'xml' : 'text/xml' | 377 'xml' : 'text/xml' |
370 } | 378 } |
371 self._default_mime_type = 'text/html' | 379 self._default_mime_type = 'text/html' |
372 | 380 |
373 BasePageHandler.__init__(self, request, client_address, socket_server, | 381 BasePageHandler.__init__(self, request, client_address, socket_server, |
374 connect_handlers, get_handlers, post_handlers, | 382 connect_handlers, get_handlers, head_handlers, |
375 put_handlers) | 383 post_handlers, put_handlers) |
376 | 384 |
377 def GetMIMETypeFromName(self, file_name): | 385 def GetMIMETypeFromName(self, file_name): |
378 """Returns the mime type for the specified file_name. So far it only looks | 386 """Returns the mime type for the specified file_name. So far it only looks |
379 at the file extension.""" | 387 at the file extension.""" |
380 | 388 |
381 (shortname, extension) = os.path.splitext(file_name.split("?")[0]) | 389 (shortname, extension) = os.path.splitext(file_name.split("?")[0]) |
382 if len(extension) == 0: | 390 if len(extension) == 0: |
383 # no extension. | 391 # no extension. |
384 return self._default_mime_type | 392 return self._default_mime_type |
385 | 393 |
386 # extension starts with a dot, so we need to remove it | 394 # extension starts with a dot, so we need to remove it |
387 return self._mime_types.get(extension[1:], self._default_mime_type) | 395 return self._mime_types.get(extension[1:], self._default_mime_type) |
388 | 396 |
389 def NoCacheMaxAgeTimeHandler(self): | 397 def NoCacheMaxAgeTimeHandler(self): |
390 """This request handler yields a page with the title set to the current | 398 """This request handler yields a page with the title set to the current |
391 system time, and no caching requested.""" | 399 system time, and no caching requested.""" |
392 | 400 |
393 if not self._ShouldHandleRequest("/nocachetime/maxage"): | 401 if not self._ShouldHandleRequest("/nocachetime/maxage"): |
394 return False | 402 return False |
395 | 403 |
396 self.send_response(200) | 404 self.send_response(200) |
397 self.send_header('Cache-Control', 'max-age=0') | 405 self.send_header('Cache-Control', 'max-age=0') |
398 self.send_header('Content-type', 'text/html') | 406 self.send_header('Content-Type', 'text/html') |
399 self.end_headers() | 407 self.end_headers() |
400 | 408 |
401 self.wfile.write('<html><head><title>%s</title></head></html>' % | 409 self.wfile.write('<html><head><title>%s</title></head></html>' % |
402 time.time()) | 410 time.time()) |
403 | 411 |
404 return True | 412 return True |
405 | 413 |
406 def NoCacheTimeHandler(self): | 414 def NoCacheTimeHandler(self): |
407 """This request handler yields a page with the title set to the current | 415 """This request handler yields a page with the title set to the current |
408 system time, and no caching requested.""" | 416 system time, and no caching requested.""" |
409 | 417 |
410 if not self._ShouldHandleRequest("/nocachetime"): | 418 if not self._ShouldHandleRequest("/nocachetime"): |
411 return False | 419 return False |
412 | 420 |
413 self.send_response(200) | 421 self.send_response(200) |
414 self.send_header('Cache-Control', 'no-cache') | 422 self.send_header('Cache-Control', 'no-cache') |
415 self.send_header('Content-type', 'text/html') | 423 self.send_header('Content-Type', 'text/html') |
416 self.end_headers() | 424 self.end_headers() |
417 | 425 |
418 self.wfile.write('<html><head><title>%s</title></head></html>' % | 426 self.wfile.write('<html><head><title>%s</title></head></html>' % |
419 time.time()) | 427 time.time()) |
420 | 428 |
421 return True | 429 return True |
422 | 430 |
423 def CacheTimeHandler(self): | 431 def CacheTimeHandler(self): |
424 """This request handler yields a page with the title set to the current | 432 """This request handler yields a page with the title set to the current |
425 system time, and allows caching for one minute.""" | 433 system time, and allows caching for one minute.""" |
426 | 434 |
427 if not self._ShouldHandleRequest("/cachetime"): | 435 if not self._ShouldHandleRequest("/cachetime"): |
428 return False | 436 return False |
429 | 437 |
430 self.send_response(200) | 438 self.send_response(200) |
431 self.send_header('Cache-Control', 'max-age=60') | 439 self.send_header('Cache-Control', 'max-age=60') |
432 self.send_header('Content-type', 'text/html') | 440 self.send_header('Content-Type', 'text/html') |
433 self.end_headers() | 441 self.end_headers() |
434 | 442 |
435 self.wfile.write('<html><head><title>%s</title></head></html>' % | 443 self.wfile.write('<html><head><title>%s</title></head></html>' % |
436 time.time()) | 444 time.time()) |
437 | 445 |
438 return True | 446 return True |
439 | 447 |
440 def CacheExpiresHandler(self): | 448 def CacheExpiresHandler(self): |
441 """This request handler yields a page with the title set to the current | 449 """This request handler yields a page with the title set to the current |
442 system time, and set the page to expire on 1 Jan 2099.""" | 450 system time, and set the page to expire on 1 Jan 2099.""" |
443 | 451 |
444 if not self._ShouldHandleRequest("/cache/expires"): | 452 if not self._ShouldHandleRequest("/cache/expires"): |
445 return False | 453 return False |
446 | 454 |
447 self.send_response(200) | 455 self.send_response(200) |
448 self.send_header('Expires', 'Thu, 1 Jan 2099 00:00:00 GMT') | 456 self.send_header('Expires', 'Thu, 1 Jan 2099 00:00:00 GMT') |
449 self.send_header('Content-type', 'text/html') | 457 self.send_header('Content-Type', 'text/html') |
450 self.end_headers() | 458 self.end_headers() |
451 | 459 |
452 self.wfile.write('<html><head><title>%s</title></head></html>' % | 460 self.wfile.write('<html><head><title>%s</title></head></html>' % |
453 time.time()) | 461 time.time()) |
454 | 462 |
455 return True | 463 return True |
456 | 464 |
457 def CacheProxyRevalidateHandler(self): | 465 def CacheProxyRevalidateHandler(self): |
458 """This request handler yields a page with the title set to the current | 466 """This request handler yields a page with the title set to the current |
459 system time, and allows caching for 60 seconds""" | 467 system time, and allows caching for 60 seconds""" |
460 | 468 |
461 if not self._ShouldHandleRequest("/cache/proxy-revalidate"): | 469 if not self._ShouldHandleRequest("/cache/proxy-revalidate"): |
462 return False | 470 return False |
463 | 471 |
464 self.send_response(200) | 472 self.send_response(200) |
465 self.send_header('Content-type', 'text/html') | 473 self.send_header('Content-Type', 'text/html') |
466 self.send_header('Cache-Control', 'max-age=60, proxy-revalidate') | 474 self.send_header('Cache-Control', 'max-age=60, proxy-revalidate') |
467 self.end_headers() | 475 self.end_headers() |
468 | 476 |
469 self.wfile.write('<html><head><title>%s</title></head></html>' % | 477 self.wfile.write('<html><head><title>%s</title></head></html>' % |
470 time.time()) | 478 time.time()) |
471 | 479 |
472 return True | 480 return True |
473 | 481 |
474 def CachePrivateHandler(self): | 482 def CachePrivateHandler(self): |
475 """This request handler yields a page with the title set to the current | 483 """This request handler yields a page with the title set to the current |
476 system time, and allows caching for 5 seconds.""" | 484 system time, and allows caching for 5 seconds.""" |
477 | 485 |
478 if not self._ShouldHandleRequest("/cache/private"): | 486 if not self._ShouldHandleRequest("/cache/private"): |
479 return False | 487 return False |
480 | 488 |
481 self.send_response(200) | 489 self.send_response(200) |
482 self.send_header('Content-type', 'text/html') | 490 self.send_header('Content-Type', 'text/html') |
483 self.send_header('Cache-Control', 'max-age=3, private') | 491 self.send_header('Cache-Control', 'max-age=3, private') |
484 self.end_headers() | 492 self.end_headers() |
485 | 493 |
486 self.wfile.write('<html><head><title>%s</title></head></html>' % | 494 self.wfile.write('<html><head><title>%s</title></head></html>' % |
487 time.time()) | 495 time.time()) |
488 | 496 |
489 return True | 497 return True |
490 | 498 |
491 def CachePublicHandler(self): | 499 def CachePublicHandler(self): |
492 """This request handler yields a page with the title set to the current | 500 """This request handler yields a page with the title set to the current |
493 system time, and allows caching for 5 seconds.""" | 501 system time, and allows caching for 5 seconds.""" |
494 | 502 |
495 if not self._ShouldHandleRequest("/cache/public"): | 503 if not self._ShouldHandleRequest("/cache/public"): |
496 return False | 504 return False |
497 | 505 |
498 self.send_response(200) | 506 self.send_response(200) |
499 self.send_header('Content-type', 'text/html') | 507 self.send_header('Content-Type', 'text/html') |
500 self.send_header('Cache-Control', 'max-age=3, public') | 508 self.send_header('Cache-Control', 'max-age=3, public') |
501 self.end_headers() | 509 self.end_headers() |
502 | 510 |
503 self.wfile.write('<html><head><title>%s</title></head></html>' % | 511 self.wfile.write('<html><head><title>%s</title></head></html>' % |
504 time.time()) | 512 time.time()) |
505 | 513 |
506 return True | 514 return True |
507 | 515 |
508 def CacheSMaxAgeHandler(self): | 516 def CacheSMaxAgeHandler(self): |
509 """This request handler yields a page with the title set to the current | 517 """This request handler yields a page with the title set to the current |
510 system time, and does not allow for caching.""" | 518 system time, and does not allow for caching.""" |
511 | 519 |
512 if not self._ShouldHandleRequest("/cache/s-maxage"): | 520 if not self._ShouldHandleRequest("/cache/s-maxage"): |
513 return False | 521 return False |
514 | 522 |
515 self.send_response(200) | 523 self.send_response(200) |
516 self.send_header('Content-type', 'text/html') | 524 self.send_header('Content-Type', 'text/html') |
517 self.send_header('Cache-Control', 'public, s-maxage = 60, max-age = 0') | 525 self.send_header('Cache-Control', 'public, s-maxage = 60, max-age = 0') |
518 self.end_headers() | 526 self.end_headers() |
519 | 527 |
520 self.wfile.write('<html><head><title>%s</title></head></html>' % | 528 self.wfile.write('<html><head><title>%s</title></head></html>' % |
521 time.time()) | 529 time.time()) |
522 | 530 |
523 return True | 531 return True |
524 | 532 |
525 def CacheMustRevalidateHandler(self): | 533 def CacheMustRevalidateHandler(self): |
526 """This request handler yields a page with the title set to the current | 534 """This request handler yields a page with the title set to the current |
527 system time, and does not allow caching.""" | 535 system time, and does not allow caching.""" |
528 | 536 |
529 if not self._ShouldHandleRequest("/cache/must-revalidate"): | 537 if not self._ShouldHandleRequest("/cache/must-revalidate"): |
530 return False | 538 return False |
531 | 539 |
532 self.send_response(200) | 540 self.send_response(200) |
533 self.send_header('Content-type', 'text/html') | 541 self.send_header('Content-Type', 'text/html') |
534 self.send_header('Cache-Control', 'must-revalidate') | 542 self.send_header('Cache-Control', 'must-revalidate') |
535 self.end_headers() | 543 self.end_headers() |
536 | 544 |
537 self.wfile.write('<html><head><title>%s</title></head></html>' % | 545 self.wfile.write('<html><head><title>%s</title></head></html>' % |
538 time.time()) | 546 time.time()) |
539 | 547 |
540 return True | 548 return True |
541 | 549 |
542 def CacheMustRevalidateMaxAgeHandler(self): | 550 def CacheMustRevalidateMaxAgeHandler(self): |
543 """This request handler yields a page with the title set to the current | 551 """This request handler yields a page with the title set to the current |
544 system time, and does not allow caching event though max-age of 60 | 552 system time, and does not allow caching event though max-age of 60 |
545 seconds is specified.""" | 553 seconds is specified.""" |
546 | 554 |
547 if not self._ShouldHandleRequest("/cache/must-revalidate/max-age"): | 555 if not self._ShouldHandleRequest("/cache/must-revalidate/max-age"): |
548 return False | 556 return False |
549 | 557 |
550 self.send_response(200) | 558 self.send_response(200) |
551 self.send_header('Content-type', 'text/html') | 559 self.send_header('Content-Type', 'text/html') |
552 self.send_header('Cache-Control', 'max-age=60, must-revalidate') | 560 self.send_header('Cache-Control', 'max-age=60, must-revalidate') |
553 self.end_headers() | 561 self.end_headers() |
554 | 562 |
555 self.wfile.write('<html><head><title>%s</title></head></html>' % | 563 self.wfile.write('<html><head><title>%s</title></head></html>' % |
556 time.time()) | 564 time.time()) |
557 | 565 |
558 return True | 566 return True |
559 | 567 |
560 def CacheNoStoreHandler(self): | 568 def CacheNoStoreHandler(self): |
561 """This request handler yields a page with the title set to the current | 569 """This request handler yields a page with the title set to the current |
562 system time, and does not allow the page to be stored.""" | 570 system time, and does not allow the page to be stored.""" |
563 | 571 |
564 if not self._ShouldHandleRequest("/cache/no-store"): | 572 if not self._ShouldHandleRequest("/cache/no-store"): |
565 return False | 573 return False |
566 | 574 |
567 self.send_response(200) | 575 self.send_response(200) |
568 self.send_header('Content-type', 'text/html') | 576 self.send_header('Content-Type', 'text/html') |
569 self.send_header('Cache-Control', 'no-store') | 577 self.send_header('Cache-Control', 'no-store') |
570 self.end_headers() | 578 self.end_headers() |
571 | 579 |
572 self.wfile.write('<html><head><title>%s</title></head></html>' % | 580 self.wfile.write('<html><head><title>%s</title></head></html>' % |
573 time.time()) | 581 time.time()) |
574 | 582 |
575 return True | 583 return True |
576 | 584 |
577 def CacheNoStoreMaxAgeHandler(self): | 585 def CacheNoStoreMaxAgeHandler(self): |
578 """This request handler yields a page with the title set to the current | 586 """This request handler yields a page with the title set to the current |
579 system time, and does not allow the page to be stored even though max-age | 587 system time, and does not allow the page to be stored even though max-age |
580 of 60 seconds is specified.""" | 588 of 60 seconds is specified.""" |
581 | 589 |
582 if not self._ShouldHandleRequest("/cache/no-store/max-age"): | 590 if not self._ShouldHandleRequest("/cache/no-store/max-age"): |
583 return False | 591 return False |
584 | 592 |
585 self.send_response(200) | 593 self.send_response(200) |
586 self.send_header('Content-type', 'text/html') | 594 self.send_header('Content-Type', 'text/html') |
587 self.send_header('Cache-Control', 'max-age=60, no-store') | 595 self.send_header('Cache-Control', 'max-age=60, no-store') |
588 self.end_headers() | 596 self.end_headers() |
589 | 597 |
590 self.wfile.write('<html><head><title>%s</title></head></html>' % | 598 self.wfile.write('<html><head><title>%s</title></head></html>' % |
591 time.time()) | 599 time.time()) |
592 | 600 |
593 return True | 601 return True |
594 | 602 |
595 | 603 |
596 def CacheNoTransformHandler(self): | 604 def CacheNoTransformHandler(self): |
597 """This request handler yields a page with the title set to the current | 605 """This request handler yields a page with the title set to the current |
598 system time, and does not allow the content to transformed during | 606 system time, and does not allow the content to transformed during |
599 user-agent caching""" | 607 user-agent caching""" |
600 | 608 |
601 if not self._ShouldHandleRequest("/cache/no-transform"): | 609 if not self._ShouldHandleRequest("/cache/no-transform"): |
602 return False | 610 return False |
603 | 611 |
604 self.send_response(200) | 612 self.send_response(200) |
605 self.send_header('Content-type', 'text/html') | 613 self.send_header('Content-Type', 'text/html') |
606 self.send_header('Cache-Control', 'no-transform') | 614 self.send_header('Cache-Control', 'no-transform') |
607 self.end_headers() | 615 self.end_headers() |
608 | 616 |
609 self.wfile.write('<html><head><title>%s</title></head></html>' % | 617 self.wfile.write('<html><head><title>%s</title></head></html>' % |
610 time.time()) | 618 time.time()) |
611 | 619 |
612 return True | 620 return True |
613 | 621 |
614 def EchoHeader(self): | 622 def EchoHeader(self): |
615 """This handler echoes back the value of a specific request header.""" | 623 """This handler echoes back the value of a specific request header.""" |
616 return self.EchoHeaderHelper("/echoheader") | 624 return self.EchoHeaderHelper("/echoheader") |
617 | 625 |
618 """This function echoes back the value of a specific request header""" | 626 """This function echoes back the value of a specific request header""" |
619 """while allowing caching for 16 hours.""" | 627 """while allowing caching for 16 hours.""" |
620 def EchoHeaderCache(self): | 628 def EchoHeaderCache(self): |
621 return self.EchoHeaderHelper("/echoheadercache") | 629 return self.EchoHeaderHelper("/echoheadercache") |
622 | 630 |
623 def EchoHeaderHelper(self, echo_header): | 631 def EchoHeaderHelper(self, echo_header): |
624 """This function echoes back the value of the request header passed in.""" | 632 """This function echoes back the value of the request header passed in.""" |
625 if not self._ShouldHandleRequest(echo_header): | 633 if not self._ShouldHandleRequest(echo_header): |
626 return False | 634 return False |
627 | 635 |
628 query_char = self.path.find('?') | 636 query_char = self.path.find('?') |
629 if query_char != -1: | 637 if query_char != -1: |
630 header_name = self.path[query_char+1:] | 638 header_name = self.path[query_char+1:] |
631 | 639 |
632 self.send_response(200) | 640 self.send_response(200) |
633 self.send_header('Content-type', 'text/plain') | 641 self.send_header('Content-Type', 'text/plain') |
634 if echo_header == '/echoheadercache': | 642 if echo_header == '/echoheadercache': |
635 self.send_header('Cache-control', 'max-age=60000') | 643 self.send_header('Cache-control', 'max-age=60000') |
636 else: | 644 else: |
637 self.send_header('Cache-control', 'no-cache') | 645 self.send_header('Cache-control', 'no-cache') |
638 # insert a vary header to properly indicate that the cachability of this | 646 # insert a vary header to properly indicate that the cachability of this |
639 # request is subject to value of the request header being echoed. | 647 # request is subject to value of the request header being echoed. |
640 if len(header_name) > 0: | 648 if len(header_name) > 0: |
641 self.send_header('Vary', header_name) | 649 self.send_header('Vary', header_name) |
642 self.end_headers() | 650 self.end_headers() |
643 | 651 |
(...skipping 23 matching lines...) Expand all Loading... |
667 return body | 675 return body |
668 | 676 |
669 def EchoHandler(self): | 677 def EchoHandler(self): |
670 """This handler just echoes back the payload of the request, for testing | 678 """This handler just echoes back the payload of the request, for testing |
671 form submission.""" | 679 form submission.""" |
672 | 680 |
673 if not self._ShouldHandleRequest("/echo"): | 681 if not self._ShouldHandleRequest("/echo"): |
674 return False | 682 return False |
675 | 683 |
676 self.send_response(200) | 684 self.send_response(200) |
677 self.send_header('Content-type', 'text/html') | 685 self.send_header('Content-Type', 'text/html') |
678 self.end_headers() | 686 self.end_headers() |
679 self.wfile.write(self.ReadRequestBody()) | 687 self.wfile.write(self.ReadRequestBody()) |
680 return True | 688 return True |
681 | 689 |
682 def EchoTitleHandler(self): | 690 def EchoTitleHandler(self): |
683 """This handler is like Echo, but sets the page title to the request.""" | 691 """This handler is like Echo, but sets the page title to the request.""" |
684 | 692 |
685 if not self._ShouldHandleRequest("/echotitle"): | 693 if not self._ShouldHandleRequest("/echotitle"): |
686 return False | 694 return False |
687 | 695 |
688 self.send_response(200) | 696 self.send_response(200) |
689 self.send_header('Content-type', 'text/html') | 697 self.send_header('Content-Type', 'text/html') |
690 self.end_headers() | 698 self.end_headers() |
691 request = self.ReadRequestBody() | 699 request = self.ReadRequestBody() |
692 self.wfile.write('<html><head><title>') | 700 self.wfile.write('<html><head><title>') |
693 self.wfile.write(request) | 701 self.wfile.write(request) |
694 self.wfile.write('</title></head></html>') | 702 self.wfile.write('</title></head></html>') |
695 return True | 703 return True |
696 | 704 |
697 def EchoAllHandler(self): | 705 def EchoAllHandler(self): |
698 """This handler yields a (more) human-readable page listing information | 706 """This handler yields a (more) human-readable page listing information |
699 about the request header & contents.""" | 707 about the request header & contents.""" |
700 | 708 |
701 if not self._ShouldHandleRequest("/echoall"): | 709 if not self._ShouldHandleRequest("/echoall"): |
702 return False | 710 return False |
703 | 711 |
704 self.send_response(200) | 712 self.send_response(200) |
705 self.send_header('Content-type', 'text/html') | 713 self.send_header('Content-Type', 'text/html') |
706 self.end_headers() | 714 self.end_headers() |
707 self.wfile.write('<html><head><style>' | 715 self.wfile.write('<html><head><style>' |
708 'pre { border: 1px solid black; margin: 5px; padding: 5px }' | 716 'pre { border: 1px solid black; margin: 5px; padding: 5px }' |
709 '</style></head><body>' | 717 '</style></head><body>' |
710 '<div style="float: right">' | 718 '<div style="float: right">' |
711 '<a href="/echo">back to referring page</a></div>' | 719 '<a href="/echo">back to referring page</a></div>' |
712 '<h1>Request Body:</h1><pre>') | 720 '<h1>Request Body:</h1><pre>') |
713 | 721 |
714 if self.command == 'POST' or self.command == 'PUT': | 722 if self.command == 'POST' or self.command == 'PUT': |
715 qs = self.ReadRequestBody() | 723 qs = self.ReadRequestBody() |
(...skipping 25 matching lines...) Expand all Loading... |
741 # small chunks of data to the client. Use a fairly large buffer | 749 # small chunks of data to the client. Use a fairly large buffer |
742 # so that we'll fill chrome's IO buffer enough to force it to | 750 # so that we'll fill chrome's IO buffer enough to force it to |
743 # actually write the data. | 751 # actually write the data. |
744 # See also the comments in the client-side of this test in | 752 # See also the comments in the client-side of this test in |
745 # download_uitest.cc | 753 # download_uitest.cc |
746 # | 754 # |
747 size_chunk1 = 35*1024 | 755 size_chunk1 = 35*1024 |
748 size_chunk2 = 10*1024 | 756 size_chunk2 = 10*1024 |
749 | 757 |
750 self.send_response(200) | 758 self.send_response(200) |
751 self.send_header('Content-type', 'application/octet-stream') | 759 self.send_header('Content-Type', 'application/octet-stream') |
752 self.send_header('Cache-Control', 'max-age=0') | 760 self.send_header('Cache-Control', 'max-age=0') |
753 if send_length: | 761 if send_length: |
754 self.send_header('Content-Length', size_chunk1 + size_chunk2) | 762 self.send_header('Content-Length', size_chunk1 + size_chunk2) |
755 self.end_headers() | 763 self.end_headers() |
756 | 764 |
757 # First chunk of data: | 765 # First chunk of data: |
758 self.wfile.write("*" * size_chunk1) | 766 self.wfile.write("*" * size_chunk1) |
759 self.wfile.flush() | 767 self.wfile.flush() |
760 | 768 |
761 # handle requests until one of them clears this flag. | 769 # handle requests until one of them clears this flag. |
762 self.server.waitForDownload = True | 770 self.server.waitForDownload = True |
763 while self.server.waitForDownload: | 771 while self.server.waitForDownload: |
764 self.server.handle_request() | 772 self.server.handle_request() |
765 | 773 |
766 # Second chunk of data: | 774 # Second chunk of data: |
767 self.wfile.write("*" * size_chunk2) | 775 self.wfile.write("*" * size_chunk2) |
768 return True | 776 return True |
769 | 777 |
770 def DownloadFinishHandler(self): | 778 def DownloadFinishHandler(self): |
771 """This handler just tells the server to finish the current download.""" | 779 """This handler just tells the server to finish the current download.""" |
772 | 780 |
773 if not self._ShouldHandleRequest("/download-finish"): | 781 if not self._ShouldHandleRequest("/download-finish"): |
774 return False | 782 return False |
775 | 783 |
776 self.server.waitForDownload = False | 784 self.server.waitForDownload = False |
777 self.send_response(200) | 785 self.send_response(200) |
778 self.send_header('Content-type', 'text/html') | 786 self.send_header('Content-Type', 'text/html') |
779 self.send_header('Cache-Control', 'max-age=0') | 787 self.send_header('Cache-Control', 'max-age=0') |
780 self.end_headers() | 788 self.end_headers() |
781 return True | 789 return True |
782 | 790 |
783 def _ReplaceFileData(self, data, query_parameters): | 791 def _ReplaceFileData(self, data, query_parameters): |
784 """Replaces matching substrings in a file. | 792 """Replaces matching substrings in a file. |
785 | 793 |
786 If the 'replace_text' URL query parameter is present, it is expected to be | 794 If the 'replace_text' URL query parameter is present, it is expected to be |
787 of the form old_text:new_text, which indicates that any old_text strings in | 795 of the form old_text:new_text, which indicates that any old_text strings in |
788 the file are replaced with new_text. Multiple 'replace_text' parameters may | 796 the file are replaced with new_text. Multiple 'replace_text' parameters may |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
852 if query == 'U': | 860 if query == 'U': |
853 content_length = uncompressed_len | 861 content_length = uncompressed_len |
854 elif query == 'S': | 862 elif query == 'S': |
855 content_length = compressed_len / 2 | 863 content_length = compressed_len / 2 |
856 elif query == 'M': | 864 elif query == 'M': |
857 content_length = (compressed_len + uncompressed_len) / 2 | 865 content_length = (compressed_len + uncompressed_len) / 2 |
858 elif query == 'L': | 866 elif query == 'L': |
859 content_length = compressed_len + uncompressed_len | 867 content_length = compressed_len + uncompressed_len |
860 | 868 |
861 self.send_response(200) | 869 self.send_response(200) |
862 self.send_header('Content-type', 'application/msword') | 870 self.send_header('Content-Type', 'application/msword') |
863 self.send_header('Content-encoding', 'deflate') | 871 self.send_header('Content-encoding', 'deflate') |
864 self.send_header('Connection', 'close') | 872 self.send_header('Connection', 'close') |
865 self.send_header('Content-Length', content_length) | 873 self.send_header('Content-Length', content_length) |
866 self.send_header('ETag', '\'' + file_path + '\'') | 874 self.send_header('ETag', '\'' + file_path + '\'') |
867 self.end_headers() | 875 self.end_headers() |
868 | 876 |
869 self.wfile.write(data) | 877 self.wfile.write(data) |
870 | 878 |
871 return True | 879 return True |
872 | 880 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
931 end = int(range[1]) | 939 end = int(range[1]) |
932 | 940 |
933 self.send_response(206) | 941 self.send_response(206) |
934 content_range = 'bytes ' + str(start) + '-' + str(end) + '/' + \ | 942 content_range = 'bytes ' + str(start) + '-' + str(end) + '/' + \ |
935 str(len(data)) | 943 str(len(data)) |
936 self.send_header('Content-Range', content_range) | 944 self.send_header('Content-Range', content_range) |
937 data = data[start: end + 1] | 945 data = data[start: end + 1] |
938 else: | 946 else: |
939 self.send_response(200) | 947 self.send_response(200) |
940 | 948 |
941 self.send_header('Content-type', self.GetMIMETypeFromName(file_path)) | 949 self.send_header('Content-Type', self.GetMIMETypeFromName(file_path)) |
942 self.send_header('Accept-Ranges', 'bytes') | 950 self.send_header('Accept-Ranges', 'bytes') |
943 self.send_header('Content-Length', len(data)) | 951 self.send_header('Content-Length', len(data)) |
944 self.send_header('ETag', '\'' + file_path + '\'') | 952 self.send_header('ETag', '\'' + file_path + '\'') |
945 self.end_headers() | 953 self.end_headers() |
946 | 954 |
947 self.wfile.write(data) | 955 if (self.command != 'HEAD'): |
| 956 self.wfile.write(data) |
948 | 957 |
949 return True | 958 return True |
950 | 959 |
951 def SetCookieHandler(self): | 960 def SetCookieHandler(self): |
952 """This handler just sets a cookie, for testing cookie handling.""" | 961 """This handler just sets a cookie, for testing cookie handling.""" |
953 | 962 |
954 if not self._ShouldHandleRequest("/set-cookie"): | 963 if not self._ShouldHandleRequest("/set-cookie"): |
955 return False | 964 return False |
956 | 965 |
957 query_char = self.path.find('?') | 966 query_char = self.path.find('?') |
958 if query_char != -1: | 967 if query_char != -1: |
959 cookie_values = self.path[query_char + 1:].split('&') | 968 cookie_values = self.path[query_char + 1:].split('&') |
960 else: | 969 else: |
961 cookie_values = ("",) | 970 cookie_values = ("",) |
962 self.send_response(200) | 971 self.send_response(200) |
963 self.send_header('Content-type', 'text/html') | 972 self.send_header('Content-Type', 'text/html') |
964 for cookie_value in cookie_values: | 973 for cookie_value in cookie_values: |
965 self.send_header('Set-Cookie', '%s' % cookie_value) | 974 self.send_header('Set-Cookie', '%s' % cookie_value) |
966 self.end_headers() | 975 self.end_headers() |
967 for cookie_value in cookie_values: | 976 for cookie_value in cookie_values: |
968 self.wfile.write('%s' % cookie_value) | 977 self.wfile.write('%s' % cookie_value) |
969 return True | 978 return True |
970 | 979 |
971 def AuthBasicHandler(self): | 980 def AuthBasicHandler(self): |
972 """This handler tests 'Basic' authentication. It just sends a page with | 981 """This handler tests 'Basic' authentication. It just sends a page with |
973 title 'user/pass' if you succeed.""" | 982 title 'user/pass' if you succeed.""" |
(...skipping 21 matching lines...) Expand all Loading... |
995 raise Exception('no auth') | 1004 raise Exception('no auth') |
996 b64str = re.findall(r'Basic (\S+)', auth)[0] | 1005 b64str = re.findall(r'Basic (\S+)', auth)[0] |
997 userpass = base64.b64decode(b64str) | 1006 userpass = base64.b64decode(b64str) |
998 username, password = re.findall(r'([^:]+):(\S+)', userpass)[0] | 1007 username, password = re.findall(r'([^:]+):(\S+)', userpass)[0] |
999 if password != expected_password: | 1008 if password != expected_password: |
1000 raise Exception('wrong password') | 1009 raise Exception('wrong password') |
1001 except Exception, e: | 1010 except Exception, e: |
1002 # Authentication failed. | 1011 # Authentication failed. |
1003 self.send_response(401) | 1012 self.send_response(401) |
1004 self.send_header('WWW-Authenticate', 'Basic realm="%s"' % realm) | 1013 self.send_header('WWW-Authenticate', 'Basic realm="%s"' % realm) |
1005 self.send_header('Content-type', 'text/html') | 1014 self.send_header('Content-Type', 'text/html') |
1006 if set_cookie_if_challenged: | 1015 if set_cookie_if_challenged: |
1007 self.send_header('Set-Cookie', 'got_challenged=true') | 1016 self.send_header('Set-Cookie', 'got_challenged=true') |
1008 self.end_headers() | 1017 self.end_headers() |
1009 self.wfile.write('<html><head>') | 1018 self.wfile.write('<html><head>') |
1010 self.wfile.write('<title>Denied: %s</title>' % e) | 1019 self.wfile.write('<title>Denied: %s</title>' % e) |
1011 self.wfile.write('</head><body>') | 1020 self.wfile.write('</head><body>') |
1012 self.wfile.write('auth=%s<p>' % auth) | 1021 self.wfile.write('auth=%s<p>' % auth) |
1013 self.wfile.write('b64str=%s<p>' % b64str) | 1022 self.wfile.write('b64str=%s<p>' % b64str) |
1014 self.wfile.write('username: %s<p>' % username) | 1023 self.wfile.write('username: %s<p>' % username) |
1015 self.wfile.write('userpass: %s<p>' % userpass) | 1024 self.wfile.write('userpass: %s<p>' % userpass) |
(...skipping 18 matching lines...) Expand all Loading... |
1034 if not os.path.isfile(gif_path): | 1043 if not os.path.isfile(gif_path): |
1035 self.send_error(404) | 1044 self.send_error(404) |
1036 self.protocol_version = old_protocol_version | 1045 self.protocol_version = old_protocol_version |
1037 return True | 1046 return True |
1038 | 1047 |
1039 f = open(gif_path, "rb") | 1048 f = open(gif_path, "rb") |
1040 data = f.read() | 1049 data = f.read() |
1041 f.close() | 1050 f.close() |
1042 | 1051 |
1043 self.send_response(200) | 1052 self.send_response(200) |
1044 self.send_header('Content-type', 'image/gif') | 1053 self.send_header('Content-Type', 'image/gif') |
1045 self.send_header('Cache-control', 'max-age=60000') | 1054 self.send_header('Cache-control', 'max-age=60000') |
1046 self.send_header('Etag', 'abc') | 1055 self.send_header('Etag', 'abc') |
1047 self.end_headers() | 1056 self.end_headers() |
1048 self.wfile.write(data) | 1057 self.wfile.write(data) |
1049 else: | 1058 else: |
1050 self.send_response(200) | 1059 self.send_response(200) |
1051 self.send_header('Content-type', 'text/html') | 1060 self.send_header('Content-Type', 'text/html') |
1052 self.send_header('Cache-control', 'max-age=60000') | 1061 self.send_header('Cache-control', 'max-age=60000') |
1053 self.send_header('Etag', 'abc') | 1062 self.send_header('Etag', 'abc') |
1054 self.end_headers() | 1063 self.end_headers() |
1055 self.wfile.write('<html><head>') | 1064 self.wfile.write('<html><head>') |
1056 self.wfile.write('<title>%s/%s</title>' % (username, password)) | 1065 self.wfile.write('<title>%s/%s</title>' % (username, password)) |
1057 self.wfile.write('</head><body>') | 1066 self.wfile.write('</head><body>') |
1058 self.wfile.write('auth=%s<p>' % auth) | 1067 self.wfile.write('auth=%s<p>' % auth) |
1059 self.wfile.write('You sent:<br>%s<p>' % self.headers) | 1068 self.wfile.write('You sent:<br>%s<p>' % self.headers) |
1060 self.wfile.write('</body></html>') | 1069 self.wfile.write('</body></html>') |
1061 | 1070 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1129 hdr = ('Digest ' | 1138 hdr = ('Digest ' |
1130 'realm="%s", ' | 1139 'realm="%s", ' |
1131 'domain="/", ' | 1140 'domain="/", ' |
1132 'qop="auth", ' | 1141 'qop="auth", ' |
1133 'algorithm=MD5, ' | 1142 'algorithm=MD5, ' |
1134 'nonce="%s", ' | 1143 'nonce="%s", ' |
1135 'opaque="%s"') % (realm, nonce, opaque) | 1144 'opaque="%s"') % (realm, nonce, opaque) |
1136 if stale: | 1145 if stale: |
1137 hdr += ', stale="TRUE"' | 1146 hdr += ', stale="TRUE"' |
1138 self.send_header('WWW-Authenticate', hdr) | 1147 self.send_header('WWW-Authenticate', hdr) |
1139 self.send_header('Content-type', 'text/html') | 1148 self.send_header('Content-Type', 'text/html') |
1140 self.end_headers() | 1149 self.end_headers() |
1141 self.wfile.write('<html><head>') | 1150 self.wfile.write('<html><head>') |
1142 self.wfile.write('<title>Denied: %s</title>' % e) | 1151 self.wfile.write('<title>Denied: %s</title>' % e) |
1143 self.wfile.write('</head><body>') | 1152 self.wfile.write('</head><body>') |
1144 self.wfile.write('auth=%s<p>' % auth) | 1153 self.wfile.write('auth=%s<p>' % auth) |
1145 self.wfile.write('pairs=%s<p>' % pairs) | 1154 self.wfile.write('pairs=%s<p>' % pairs) |
1146 self.wfile.write('You sent:<br>%s<p>' % self.headers) | 1155 self.wfile.write('You sent:<br>%s<p>' % self.headers) |
1147 self.wfile.write('We are replying:<br>%s<p>' % hdr) | 1156 self.wfile.write('We are replying:<br>%s<p>' % hdr) |
1148 self.wfile.write('</body></html>') | 1157 self.wfile.write('</body></html>') |
1149 return True | 1158 return True |
1150 | 1159 |
1151 # Authentication successful. | 1160 # Authentication successful. |
1152 self.send_response(200) | 1161 self.send_response(200) |
1153 self.send_header('Content-type', 'text/html') | 1162 self.send_header('Content-Type', 'text/html') |
1154 self.end_headers() | 1163 self.end_headers() |
1155 self.wfile.write('<html><head>') | 1164 self.wfile.write('<html><head>') |
1156 self.wfile.write('<title>%s/%s</title>' % (pairs['username'], password)) | 1165 self.wfile.write('<title>%s/%s</title>' % (pairs['username'], password)) |
1157 self.wfile.write('</head><body>') | 1166 self.wfile.write('</head><body>') |
1158 self.wfile.write('auth=%s<p>' % auth) | 1167 self.wfile.write('auth=%s<p>' % auth) |
1159 self.wfile.write('pairs=%s<p>' % pairs) | 1168 self.wfile.write('pairs=%s<p>' % pairs) |
1160 self.wfile.write('</body></html>') | 1169 self.wfile.write('</body></html>') |
1161 | 1170 |
1162 return True | 1171 return True |
1163 | 1172 |
1164 def SlowServerHandler(self): | 1173 def SlowServerHandler(self): |
1165 """Wait for the user suggested time before responding. The syntax is | 1174 """Wait for the user suggested time before responding. The syntax is |
1166 /slow?0.5 to wait for half a second.""" | 1175 /slow?0.5 to wait for half a second.""" |
1167 if not self._ShouldHandleRequest("/slow"): | 1176 if not self._ShouldHandleRequest("/slow"): |
1168 return False | 1177 return False |
1169 query_char = self.path.find('?') | 1178 query_char = self.path.find('?') |
1170 wait_sec = 1.0 | 1179 wait_sec = 1.0 |
1171 if query_char >= 0: | 1180 if query_char >= 0: |
1172 try: | 1181 try: |
1173 wait_sec = int(self.path[query_char + 1:]) | 1182 wait_sec = int(self.path[query_char + 1:]) |
1174 except ValueError: | 1183 except ValueError: |
1175 pass | 1184 pass |
1176 time.sleep(wait_sec) | 1185 time.sleep(wait_sec) |
1177 self.send_response(200) | 1186 self.send_response(200) |
1178 self.send_header('Content-type', 'text/plain') | 1187 self.send_header('Content-Type', 'text/plain') |
1179 self.end_headers() | 1188 self.end_headers() |
1180 self.wfile.write("waited %d seconds" % wait_sec) | 1189 self.wfile.write("waited %d seconds" % wait_sec) |
1181 return True | 1190 return True |
1182 | 1191 |
1183 def ChunkedServerHandler(self): | 1192 def ChunkedServerHandler(self): |
1184 """Send chunked response. Allows to specify chunks parameters: | 1193 """Send chunked response. Allows to specify chunks parameters: |
1185 - waitBeforeHeaders - ms to wait before sending headers | 1194 - waitBeforeHeaders - ms to wait before sending headers |
1186 - waitBetweenChunks - ms to wait between chunks | 1195 - waitBetweenChunks - ms to wait between chunks |
1187 - chunkSize - size of each chunk in bytes | 1196 - chunkSize - size of each chunk in bytes |
1188 - chunksNumber - number of chunks | 1197 - chunksNumber - number of chunks |
(...skipping 11 matching lines...) Expand all Loading... |
1200 for param in params: | 1209 for param in params: |
1201 keyValue = param.split('=') | 1210 keyValue = param.split('=') |
1202 if len(keyValue) == 2: | 1211 if len(keyValue) == 2: |
1203 try: | 1212 try: |
1204 chunkedSettings[keyValue[0]] = int(keyValue[1]) | 1213 chunkedSettings[keyValue[0]] = int(keyValue[1]) |
1205 except ValueError: | 1214 except ValueError: |
1206 pass | 1215 pass |
1207 time.sleep(0.001 * chunkedSettings['waitBeforeHeaders']); | 1216 time.sleep(0.001 * chunkedSettings['waitBeforeHeaders']); |
1208 self.protocol_version = 'HTTP/1.1' # Needed for chunked encoding | 1217 self.protocol_version = 'HTTP/1.1' # Needed for chunked encoding |
1209 self.send_response(200) | 1218 self.send_response(200) |
1210 self.send_header('Content-type', 'text/plain') | 1219 self.send_header('Content-Type', 'text/plain') |
1211 self.send_header('Connection', 'close') | 1220 self.send_header('Connection', 'close') |
1212 self.send_header('Transfer-Encoding', 'chunked') | 1221 self.send_header('Transfer-Encoding', 'chunked') |
1213 self.end_headers() | 1222 self.end_headers() |
1214 # Chunked encoding: sending all chunks, then final zero-length chunk and | 1223 # Chunked encoding: sending all chunks, then final zero-length chunk and |
1215 # then final CRLF. | 1224 # then final CRLF. |
1216 for i in range(0, chunkedSettings['chunksNumber']): | 1225 for i in range(0, chunkedSettings['chunksNumber']): |
1217 if i > 0: | 1226 if i > 0: |
1218 time.sleep(0.001 * chunkedSettings['waitBetweenChunks']) | 1227 time.sleep(0.001 * chunkedSettings['waitBetweenChunks']) |
1219 self.sendChunkHelp('*' * chunkedSettings['chunkSize']) | 1228 self.sendChunkHelp('*' * chunkedSettings['chunkSize']) |
1220 self.wfile.flush(); # Keep in mind that we start flushing only after 1kb. | 1229 self.wfile.flush(); # Keep in mind that we start flushing only after 1kb. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1255 return False | 1264 return False |
1256 | 1265 |
1257 query_char = self.path.find('?') | 1266 query_char = self.path.find('?') |
1258 if query_char < 0 or len(self.path) <= query_char + 1: | 1267 if query_char < 0 or len(self.path) <= query_char + 1: |
1259 self.sendRedirectHelp(test_name) | 1268 self.sendRedirectHelp(test_name) |
1260 return True | 1269 return True |
1261 dest = self.path[query_char + 1:] | 1270 dest = self.path[query_char + 1:] |
1262 | 1271 |
1263 self.send_response(301) # moved permanently | 1272 self.send_response(301) # moved permanently |
1264 self.send_header('Location', dest) | 1273 self.send_header('Location', dest) |
1265 self.send_header('Content-type', 'text/html') | 1274 self.send_header('Content-Type', 'text/html') |
1266 self.end_headers() | 1275 self.end_headers() |
1267 self.wfile.write('<html><head>') | 1276 self.wfile.write('<html><head>') |
1268 self.wfile.write('</head><body>Redirecting to %s</body></html>' % dest) | 1277 self.wfile.write('</head><body>Redirecting to %s</body></html>' % dest) |
1269 | 1278 |
1270 return True | 1279 return True |
1271 | 1280 |
1272 def ClientRedirectHandler(self): | 1281 def ClientRedirectHandler(self): |
1273 """Sends a client redirect to the given URL. The syntax is | 1282 """Sends a client redirect to the given URL. The syntax is |
1274 '/client-redirect?http://foo.bar/asdf' to redirect to | 1283 '/client-redirect?http://foo.bar/asdf' to redirect to |
1275 'http://foo.bar/asdf'""" | 1284 'http://foo.bar/asdf'""" |
1276 | 1285 |
1277 test_name = "/client-redirect" | 1286 test_name = "/client-redirect" |
1278 if not self._ShouldHandleRequest(test_name): | 1287 if not self._ShouldHandleRequest(test_name): |
1279 return False | 1288 return False |
1280 | 1289 |
1281 query_char = self.path.find('?'); | 1290 query_char = self.path.find('?'); |
1282 if query_char < 0 or len(self.path) <= query_char + 1: | 1291 if query_char < 0 or len(self.path) <= query_char + 1: |
1283 self.sendRedirectHelp(test_name) | 1292 self.sendRedirectHelp(test_name) |
1284 return True | 1293 return True |
1285 dest = self.path[query_char + 1:] | 1294 dest = self.path[query_char + 1:] |
1286 | 1295 |
1287 self.send_response(200) | 1296 self.send_response(200) |
1288 self.send_header('Content-type', 'text/html') | 1297 self.send_header('Content-Type', 'text/html') |
1289 self.end_headers() | 1298 self.end_headers() |
1290 self.wfile.write('<html><head>') | 1299 self.wfile.write('<html><head>') |
1291 self.wfile.write('<meta http-equiv="refresh" content="0;url=%s">' % dest) | 1300 self.wfile.write('<meta http-equiv="refresh" content="0;url=%s">' % dest) |
1292 self.wfile.write('</head><body>Redirecting to %s</body></html>' % dest) | 1301 self.wfile.write('</head><body>Redirecting to %s</body></html>' % dest) |
1293 | 1302 |
1294 return True | 1303 return True |
1295 | 1304 |
1296 def MultipartHandler(self): | 1305 def MultipartHandler(self): |
1297 """Send a multipart response (10 text/html pages).""" | 1306 """Send a multipart response (10 text/html pages).""" |
1298 test_name = '/multipart' | 1307 test_name = '/multipart' |
1299 if not self._ShouldHandleRequest(test_name): | 1308 if not self._ShouldHandleRequest(test_name): |
1300 return False | 1309 return False |
1301 | 1310 |
1302 num_frames = 10 | 1311 num_frames = 10 |
1303 bound = '12345' | 1312 bound = '12345' |
1304 self.send_response(200) | 1313 self.send_response(200) |
1305 self.send_header('Content-type', | 1314 self.send_header('Content-Type', |
1306 'multipart/x-mixed-replace;boundary=' + bound) | 1315 'multipart/x-mixed-replace;boundary=' + bound) |
1307 self.end_headers() | 1316 self.end_headers() |
1308 | 1317 |
1309 for i in xrange(num_frames): | 1318 for i in xrange(num_frames): |
1310 self.wfile.write('--' + bound + '\r\n') | 1319 self.wfile.write('--' + bound + '\r\n') |
1311 self.wfile.write('Content-type: text/html\r\n\r\n') | 1320 self.wfile.write('Content-Type: text/html\r\n\r\n') |
1312 self.wfile.write('<title>page ' + str(i) + '</title>') | 1321 self.wfile.write('<title>page ' + str(i) + '</title>') |
1313 self.wfile.write('page ' + str(i)) | 1322 self.wfile.write('page ' + str(i)) |
1314 | 1323 |
1315 self.wfile.write('--' + bound + '--') | 1324 self.wfile.write('--' + bound + '--') |
1316 return True | 1325 return True |
1317 | 1326 |
1318 def MultipartSlowHandler(self): | 1327 def MultipartSlowHandler(self): |
1319 """Send a multipart response (3 text/html pages) with a slight delay | 1328 """Send a multipart response (3 text/html pages) with a slight delay |
1320 between each page. This is similar to how some pages show status using | 1329 between each page. This is similar to how some pages show status using |
1321 multipart.""" | 1330 multipart.""" |
1322 test_name = '/multipart-slow' | 1331 test_name = '/multipart-slow' |
1323 if not self._ShouldHandleRequest(test_name): | 1332 if not self._ShouldHandleRequest(test_name): |
1324 return False | 1333 return False |
1325 | 1334 |
1326 num_frames = 3 | 1335 num_frames = 3 |
1327 bound = '12345' | 1336 bound = '12345' |
1328 self.send_response(200) | 1337 self.send_response(200) |
1329 self.send_header('Content-type', | 1338 self.send_header('Content-Type', |
1330 'multipart/x-mixed-replace;boundary=' + bound) | 1339 'multipart/x-mixed-replace;boundary=' + bound) |
1331 self.end_headers() | 1340 self.end_headers() |
1332 | 1341 |
1333 for i in xrange(num_frames): | 1342 for i in xrange(num_frames): |
1334 self.wfile.write('--' + bound + '\r\n') | 1343 self.wfile.write('--' + bound + '\r\n') |
1335 self.wfile.write('Content-type: text/html\r\n\r\n') | 1344 self.wfile.write('Content-Type: text/html\r\n\r\n') |
1336 time.sleep(0.25) | 1345 time.sleep(0.25) |
1337 if i == 2: | 1346 if i == 2: |
1338 self.wfile.write('<title>PASS</title>') | 1347 self.wfile.write('<title>PASS</title>') |
1339 else: | 1348 else: |
1340 self.wfile.write('<title>page ' + str(i) + '</title>') | 1349 self.wfile.write('<title>page ' + str(i) + '</title>') |
1341 self.wfile.write('page ' + str(i) + '<!-- ' + ('x' * 2048) + '-->') | 1350 self.wfile.write('page ' + str(i) + '<!-- ' + ('x' * 2048) + '-->') |
1342 | 1351 |
1343 self.wfile.write('--' + bound + '--') | 1352 self.wfile.write('--' + bound + '--') |
1344 return True | 1353 return True |
1345 | 1354 |
1346 def DefaultResponseHandler(self): | 1355 def DefaultResponseHandler(self): |
1347 """This is the catch-all response handler for requests that aren't handled | 1356 """This is the catch-all response handler for requests that aren't handled |
1348 by one of the special handlers above. | 1357 by one of the special handlers above. |
1349 Note that we specify the content-length as without it the https connection | 1358 Note that we specify the content-length as without it the https connection |
1350 is not closed properly (and the browser keeps expecting data).""" | 1359 is not closed properly (and the browser keeps expecting data).""" |
1351 | 1360 |
1352 contents = "Default response given for path: " + self.path | 1361 contents = "Default response given for path: " + self.path |
1353 self.send_response(200) | 1362 self.send_response(200) |
1354 self.send_header('Content-type', 'text/html') | 1363 self.send_header('Content-Type', 'text/html') |
1355 self.send_header("Content-Length", len(contents)) | 1364 self.send_header('Content-Length', len(contents)) |
1356 self.end_headers() | 1365 self.end_headers() |
1357 self.wfile.write(contents) | 1366 if (self.command != 'HEAD'): |
| 1367 self.wfile.write(contents) |
1358 return True | 1368 return True |
1359 | 1369 |
1360 def RedirectConnectHandler(self): | 1370 def RedirectConnectHandler(self): |
1361 """Sends a redirect to the CONNECT request for www.redirect.com. This | 1371 """Sends a redirect to the CONNECT request for www.redirect.com. This |
1362 response is not specified by the RFC, so the browser should not follow | 1372 response is not specified by the RFC, so the browser should not follow |
1363 the redirect.""" | 1373 the redirect.""" |
1364 | 1374 |
1365 if (self.path.find("www.redirect.com") < 0): | 1375 if (self.path.find("www.redirect.com") < 0): |
1366 return False | 1376 return False |
1367 | 1377 |
(...skipping 21 matching lines...) Expand all Loading... |
1389 self.end_headers() | 1399 self.end_headers() |
1390 return True | 1400 return True |
1391 | 1401 |
1392 def DefaultConnectResponseHandler(self): | 1402 def DefaultConnectResponseHandler(self): |
1393 """This is the catch-all response handler for CONNECT requests that aren't | 1403 """This is the catch-all response handler for CONNECT requests that aren't |
1394 handled by one of the special handlers above. Real Web servers respond | 1404 handled by one of the special handlers above. Real Web servers respond |
1395 with 400 to CONNECT requests.""" | 1405 with 400 to CONNECT requests.""" |
1396 | 1406 |
1397 contents = "Your client has issued a malformed or illegal request." | 1407 contents = "Your client has issued a malformed or illegal request." |
1398 self.send_response(400) # bad request | 1408 self.send_response(400) # bad request |
1399 self.send_header('Content-type', 'text/html') | 1409 self.send_header('Content-Type', 'text/html') |
1400 self.send_header("Content-Length", len(contents)) | 1410 self.send_header('Content-Length', len(contents)) |
1401 self.end_headers() | 1411 self.end_headers() |
1402 self.wfile.write(contents) | 1412 self.wfile.write(contents) |
1403 return True | 1413 return True |
1404 | 1414 |
1405 def DeviceManagementHandler(self): | 1415 def DeviceManagementHandler(self): |
1406 """Delegates to the device management service used for cloud policy.""" | 1416 """Delegates to the device management service used for cloud policy.""" |
1407 if not self._ShouldHandleRequest("/device_management"): | 1417 if not self._ShouldHandleRequest("/device_management"): |
1408 return False | 1418 return False |
1409 | 1419 |
1410 raw_request = self.ReadRequestBody() | 1420 raw_request = self.ReadRequestBody() |
1411 | 1421 |
1412 if not self.server._device_management_handler: | 1422 if not self.server._device_management_handler: |
1413 import device_management | 1423 import device_management |
1414 policy_path = os.path.join(self.server.data_dir, 'device_management') | 1424 policy_path = os.path.join(self.server.data_dir, 'device_management') |
1415 self.server._device_management_handler = ( | 1425 self.server._device_management_handler = ( |
1416 device_management.TestServer(policy_path, | 1426 device_management.TestServer(policy_path, |
1417 self.server.policy_keys, | 1427 self.server.policy_keys, |
1418 self.server.policy_user)) | 1428 self.server.policy_user)) |
1419 | 1429 |
1420 http_response, raw_reply = ( | 1430 http_response, raw_reply = ( |
1421 self.server._device_management_handler.HandleRequest(self.path, | 1431 self.server._device_management_handler.HandleRequest(self.path, |
1422 self.headers, | 1432 self.headers, |
1423 raw_request)) | 1433 raw_request)) |
1424 self.send_response(http_response) | 1434 self.send_response(http_response) |
1425 if (http_response == 200): | 1435 if (http_response == 200): |
1426 self.send_header('Content-type', 'application/x-protobuffer') | 1436 self.send_header('Content-Type', 'application/x-protobuffer') |
1427 self.end_headers() | 1437 self.end_headers() |
1428 self.wfile.write(raw_reply) | 1438 self.wfile.write(raw_reply) |
1429 return True | 1439 return True |
1430 | 1440 |
1431 # called by the redirect handling function when there is no parameter | 1441 # called by the redirect handling function when there is no parameter |
1432 def sendRedirectHelp(self, redirect_name): | 1442 def sendRedirectHelp(self, redirect_name): |
1433 self.send_response(200) | 1443 self.send_response(200) |
1434 self.send_header('Content-type', 'text/html') | 1444 self.send_header('Content-Type', 'text/html') |
1435 self.end_headers() | 1445 self.end_headers() |
1436 self.wfile.write('<html><body><h1>Error: no redirect destination</h1>') | 1446 self.wfile.write('<html><body><h1>Error: no redirect destination</h1>') |
1437 self.wfile.write('Use <pre>%s?http://dest...</pre>' % redirect_name) | 1447 self.wfile.write('Use <pre>%s?http://dest...</pre>' % redirect_name) |
1438 self.wfile.write('</body></html>') | 1448 self.wfile.write('</body></html>') |
1439 | 1449 |
1440 # called by chunked handling function | 1450 # called by chunked handling function |
1441 def sendChunkHelp(self, chunk): | 1451 def sendChunkHelp(self, chunk): |
1442 # Each chunk consists of: chunk size (hex), CRLF, chunk body, CRLF | 1452 # Each chunk consists of: chunk size (hex), CRLF, chunk body, CRLF |
1443 self.wfile.write('%X\r\n' % len(chunk)) | 1453 self.wfile.write('%X\r\n' % len(chunk)) |
1444 self.wfile.write(chunk) | 1454 self.wfile.write(chunk) |
(...skipping 11 matching lines...) Expand all Loading... |
1456 self.ChromiumSyncSendNotificationOpHandler, | 1466 self.ChromiumSyncSendNotificationOpHandler, |
1457 self.ChromiumSyncBirthdayErrorOpHandler, | 1467 self.ChromiumSyncBirthdayErrorOpHandler, |
1458 self.ChromiumSyncTransientErrorOpHandler, | 1468 self.ChromiumSyncTransientErrorOpHandler, |
1459 self.ChromiumSyncSyncTabsOpHandler, | 1469 self.ChromiumSyncSyncTabsOpHandler, |
1460 self.ChromiumSyncErrorOpHandler, | 1470 self.ChromiumSyncErrorOpHandler, |
1461 self.ChromiumSyncCredHandler] | 1471 self.ChromiumSyncCredHandler] |
1462 | 1472 |
1463 post_handlers = [self.ChromiumSyncCommandHandler, | 1473 post_handlers = [self.ChromiumSyncCommandHandler, |
1464 self.ChromiumSyncTimeHandler] | 1474 self.ChromiumSyncTimeHandler] |
1465 BasePageHandler.__init__(self, request, client_address, | 1475 BasePageHandler.__init__(self, request, client_address, |
1466 sync_http_server, [], get_handlers, | 1476 sync_http_server, [], get_handlers, [], |
1467 post_handlers, []) | 1477 post_handlers, []) |
1468 | 1478 |
1469 | 1479 |
1470 def ChromiumSyncTimeHandler(self): | 1480 def ChromiumSyncTimeHandler(self): |
1471 """Handle Chromium sync .../time requests. | 1481 """Handle Chromium sync .../time requests. |
1472 | 1482 |
1473 The syncer sometimes checks server reachability by examining /time. | 1483 The syncer sometimes checks server reachability by examining /time. |
1474 """ | 1484 """ |
1475 test_name = "/chromiumsync/time" | 1485 test_name = "/chromiumsync/time" |
1476 if not self._ShouldHandleRequest(test_name): | 1486 if not self._ShouldHandleRequest(test_name): |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1915 'random key if none is specified on the command ' | 1925 'random key if none is specified on the command ' |
1916 'line.') | 1926 'line.') |
1917 option_parser.add_option('', '--policy-user', default='user@example.com', | 1927 option_parser.add_option('', '--policy-user', default='user@example.com', |
1918 dest='policy_user', | 1928 dest='policy_user', |
1919 help='Specify the user name the server should ' | 1929 help='Specify the user name the server should ' |
1920 'report back to the client as the user owning the ' | 1930 'report back to the client as the user owning the ' |
1921 'token used for making the policy request.') | 1931 'token used for making the policy request.') |
1922 options, args = option_parser.parse_args() | 1932 options, args = option_parser.parse_args() |
1923 | 1933 |
1924 sys.exit(main(options, args)) | 1934 sys.exit(main(options, args)) |
OLD | NEW |