diff options
Diffstat (limited to 'Foundation/TestData/GTMHTTPFetcherTestServer')
-rwxr-xr-x | Foundation/TestData/GTMHTTPFetcherTestServer | 274 |
1 files changed, 0 insertions, 274 deletions
diff --git a/Foundation/TestData/GTMHTTPFetcherTestServer b/Foundation/TestData/GTMHTTPFetcherTestServer deleted file mode 100755 index 838c110..0000000 --- a/Foundation/TestData/GTMHTTPFetcherTestServer +++ /dev/null @@ -1,274 +0,0 @@ -#!/usr/bin/python -# -# Copyright 2006-2008 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may not -# use this file except in compliance with the License. You may obtain a copy -# of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations under -# the License. -# -# A simple server for testing the http calls - -"""A simple BaseHTTPRequestHandler for unit testing GTM Network code - -This http server is for use by GTMHTTPFetcherTest.m in testing -both authentication and object retrieval. - -Requests to the path /accounts/ClientLogin are assumed to be -for login; other requests are for object retrieval -""" - -__author__ = 'Google Inc.' - -import string -import cgi -import time -import os -import sys -import re -import mimetypes -import socket -from BaseHTTPServer import BaseHTTPRequestHandler -from BaseHTTPServer import HTTPServer -from optparse import OptionParser - -class ServerTimeoutException(Exception): - pass - - -class TimeoutServer(HTTPServer): - - """HTTP server for testing GTM network requests. - - This server will throw an exception if it receives no connections for - several minutes. We use this to ensure that the server will be cleaned - up if something goes wrong during the unit testing. - """ - - def get_request(self): - self.socket.settimeout(120.0) - result = None - while result is None: - try: - result = self.socket.accept() - except socket.timeout: - raise ServerTimeoutException - result[0].settimeout(None) - return result - - -class SimpleServer(BaseHTTPRequestHandler): - - """HTTP request handler for testing GTM network requests. - - This is an implementation of a request handler for BaseHTTPServer, - specifically designed for GTM network code usage. - - Normal requests for GET/POST/PUT simply retrieve the file from the - supplied path, starting in the current directory. A cookie called - TestCookie is set by the response header, with the value of the filename - requested. - - DELETE requests always succeed. - - Appending ?status=n results in a failure with status value n. - - Paths ending in .auth have the .auth extension stripped, and must have - an authorization header of "GoogleLogin auth=GoodAuthToken" to succeed. - - Successful results have a Last-Modified header set; if that header's value - ("thursday") is supplied in a request's "If-Modified-Since" header, the - result is 304 (Not Modified). - - Requests to /accounts/ClientLogin will fail if supplied with a body - containing Passwd=bad. If they contain logintoken and logincaptcha values, - those must be logintoken=CapToken&logincaptch=good to succeed. - """ - - def do_GET(self): - self.doAllRequests() - - def do_POST(self): - self.doAllRequests() - - def do_PUT(self): - self.doAllRequests() - - def do_DELETE(self): - self.doAllRequests() - - def doAllRequests(self): - # This method handles all expected incoming requests - # - # Requests to path /accounts/ClientLogin are assumed to be for signing in - # - # Other paths are for retrieving a local file. An .auth appended - # to a file path will require authentication (meaning the Authorization - # header must be present with the value "GoogleLogin auth=GoodAuthToken".) - # If the token is present, the file (without uthe .auth at the end) will - # be returned. - # - # HTTP Delete commands succeed but return no data. - # - # GData override headers (putting the verb in X-HTTP-Method-Override) - # are supported. - # - # Any auth password is valid except "bad", which will fail, and "captcha", - # which will fail unless the authentication request's post string includes - # "logintoken=CapToken&logincaptcha=good" - - # We will use a readable default result string since it should never show up - # in output - resultString = "default GTMHTTPFetcherTestServer result\n"; - resultStatus = 0 - headerType = "text/plain" - postString = "" - modifiedDate = "thursday" # clients should treat dates as opaque, generally - - # auth queries and some others may include post data - postLength = int(self.headers.getheader("Content-Length", "0")); - if postLength > 0: - postString = self.rfile.read(postLength) - - # auth queries and some GData queries include post data - ifModifiedSince = self.headers.getheader("If-Modified-Since", ""); - - # retrieve the auth header; require it if the file path ends - # with the string ".auth" - authorization = self.headers.getheader("Authorization", "") - if self.path.endswith(".auth"): - if authorization != "GoogleLogin auth=GoodAuthToken": - self.send_error(401,"Unauthorized: %s" % self.path) - return - self.path = self.path[:-5] # remove the .auth at the end - - overrideHeader = self.headers.getheader("X-HTTP-Method-Override", "") - httpCommand = self.command - if httpCommand == "POST" and len(overrideHeader) > 0: - httpCommand = overrideHeader - - try: - if self.path.endswith("/accounts/ClientLogin"): - # - # it's a sign-in attempt; it's good unless the password is "bad" or - # "captcha" - # - - # use regular expression to find the password - password = "" - searchResult = re.search("(Passwd=)([^&\n]*)", postString) - if searchResult: - password = searchResult.group(2) - - if password == "bad": - resultString = "Error=BadAuthentication\n" - resultStatus = 403 - - elif password == "captcha": - logintoken = "" - logincaptcha = "" - - # use regular expressions to find the captcha token and answer - searchResult = re.search("(logintoken=)([^&\n]*)", postString); - if searchResult: - logintoken = searchResult.group(2) - - searchResult = re.search("(logincaptcha=)([^&\n]*)", postString); - if searchResult: - logincaptcha = searchResult.group(2) - - # if the captcha token is "CapToken" and the answer is "good" - # then it's a valid sign in - if (logintoken == "CapToken") and (logincaptcha == "good"): - resultString = "SID=GoodSID\nLSID=GoodLSID\nAuth=GoodAuthToken\n" - resultStatus = 200 - else: - # incorrect captcha token or answer provided - resultString = ("Error=CaptchaRequired\nCaptchaToken=CapToken" - "\nCaptchaUrl=CapUrl\n") - resultStatus = 403 - - else: - # valid username/password - resultString = "SID=GoodSID\nLSID=GoodLSID\nAuth=GoodAuthToken\n" - resultStatus = 200 - - elif httpCommand == "DELETE": - # - # it's an object delete; read and return empty data - # - resultString = "" - resultStatus = 200 - headerType = "text/plain" - - else: - # queries that have something like "?status=456" should fail with the - # status code - searchResult = re.search("(status=)([0-9]+)", self.path) - if searchResult: - status = searchResult.group(2) - self.send_error(int(status), - "Test HTTP server status parameter: %s" % self.path) - return - - # if the client gave us back our not modified date, then say there's no - # change in the response - if ifModifiedSince == modifiedDate: - self.send_response(304) # Not Modified - return - - else: - # - # it's a file fetch; read and return the data file - # - f = open("." + self.path) - resultString = f.read() - f.close() - resultStatus = 200 - fileTypeInfo = mimetypes.guess_type("." + self.path) - headerType = fileTypeInfo[0] # first part of the tuple is mime type - - self.send_response(resultStatus) - self.send_header("Content-type", headerType) - self.send_header("Last-Modified", modifiedDate) - - cookieValue = os.path.basename("." + self.path) - self.send_header('Set-Cookie', 'TestCookie=%s' % cookieValue) - self.end_headers() - self.wfile.write(resultString) - - except IOError: - self.send_error(404,"File Not Found: %s" % self.path) - - -def main(): - try: - parser = OptionParser() - parser.add_option("-p", "--port", dest="port", help="Port to run server on", - type="int", default="80") - parser.add_option("-r", "--root", dest="root", help="Where to root server", - default=".") - (options, args) = parser.parse_args() - os.chdir(options.root) - server = TimeoutServer(("127.0.0.1", options.port), SimpleServer) - sys.stdout.write("started GTMHTTPFetcherTestServer," - " serving files from root directory %s..." % os.getcwd()); - sys.stdout.flush(); - server.serve_forever() - except KeyboardInterrupt: - print "^C received, shutting down server" - server.socket.close() - except ServerTimeoutException: - print "Too long since the last request, shutting down server" - server.socket.close() - - -if __name__ == "__main__": - main() |