Annotation of embedaddon/curl/tests/dictserver.py, revision 1.1.1.1
1.1 misho 1: #!/usr/bin/env python
2: # -*- coding: utf-8 -*-
3: #***************************************************************************
4: # _ _ ____ _
5: # Project ___| | | | _ \| |
6: # / __| | | | |_) | |
7: # | (__| |_| | _ <| |___
8: # \___|\___/|_| \_\_____|
9: #
10: # Copyright (C) 2008 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
11: #
12: # This software is licensed as described in the file COPYING, which
13: # you should have received as part of this distribution. The terms
14: # are also available at https://curl.haxx.se/docs/copyright.html.
15: #
16: # You may opt to use, copy, modify, merge, publish, distribute and/or sell
17: # copies of the Software, and permit persons to whom the Software is
18: # furnished to do so, under the terms of the COPYING file.
19: #
20: # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21: # KIND, either express or implied.
22: #
23: ###########################################################################
24: #
25: """ DICT server """
26:
27: from __future__ import (absolute_import, division, print_function,
28: unicode_literals)
29: import argparse
30: import os
31: import sys
32: import logging
33: try: # Python 2
34: import SocketServer as socketserver
35: except ImportError: # Python 3
36: import socketserver
37:
38:
39: log = logging.getLogger(__name__)
40: HOST = "localhost"
41:
42: # The strings that indicate the test framework is checking our aliveness
43: VERIFIED_REQ = b"verifiedserver"
44: VERIFIED_RSP = "WE ROOLZ: {pid}"
45:
46:
47: def dictserver(options):
48: """
49: Starts up a TCP server with a DICT handler and serves DICT requests
50: forever.
51: """
52: if options.pidfile:
53: pid = os.getpid()
54: # see tests/server/util.c function write_pidfile
55: if os.name == "nt":
56: pid += 65536
57: with open(options.pidfile, "w") as f:
58: f.write(str(pid))
59:
60: local_bind = (options.host, options.port)
61: log.info("[DICT] Listening on %s", local_bind)
62:
63: # Need to set the allow_reuse on the class, not on the instance.
64: socketserver.TCPServer.allow_reuse_address = True
65: server = socketserver.TCPServer(local_bind, DictHandler)
66: server.serve_forever()
67:
68: return ScriptRC.SUCCESS
69:
70:
71: class DictHandler(socketserver.BaseRequestHandler):
72: """Handler class for DICT connections.
73:
74: """
75: def handle(self):
76: """
77: Simple function which responds to all queries with a 552.
78: """
79: try:
80: # First, send a response to allow the server to continue.
81: rsp = "220 dictserver <xnooptions> <msgid@msgid>\n"
82: self.request.sendall(rsp.encode("utf-8"))
83:
84: # Receive the request.
85: data = self.request.recv(1024).strip()
86: log.debug("[DICT] Incoming data: %r", data)
87:
88: if VERIFIED_REQ in data:
89: log.debug("[DICT] Received verification request from test "
90: "framework")
91: pid = os.getpid()
92: # see tests/server/util.c function write_pidfile
93: if os.name == "nt":
94: pid += 65536
95: response_data = VERIFIED_RSP.format(pid=pid)
96: else:
97: log.debug("[DICT] Received normal request")
98: response_data = "No matches"
99:
100: # Send back a failure to find.
101: response = "552 {0}\n".format(response_data)
102: log.debug("[DICT] Responding with %r", response)
103: self.request.sendall(response.encode("utf-8"))
104:
105: except IOError:
106: log.exception("[DICT] IOError hit during request")
107:
108:
109: def get_options():
110: parser = argparse.ArgumentParser()
111:
112: parser.add_argument("--port", action="store", default=9016,
113: type=int, help="port to listen on")
114: parser.add_argument("--host", action="store", default=HOST,
115: help="host to listen on")
116: parser.add_argument("--verbose", action="store", type=int, default=0,
117: help="verbose output")
118: parser.add_argument("--pidfile", action="store",
119: help="file name for the PID")
120: parser.add_argument("--logfile", action="store",
121: help="file name for the log")
122: parser.add_argument("--srcdir", action="store", help="test directory")
123: parser.add_argument("--id", action="store", help="server ID")
124: parser.add_argument("--ipv4", action="store_true", default=0,
125: help="IPv4 flag")
126:
127: return parser.parse_args()
128:
129:
130: def setup_logging(options):
131: """
132: Set up logging from the command line options
133: """
134: root_logger = logging.getLogger()
135: add_stdout = False
136:
137: formatter = logging.Formatter("%(asctime)s %(levelname)-5.5s %(message)s")
138:
139: # Write out to a logfile
140: if options.logfile:
141: handler = logging.FileHandler(options.logfile, mode="w")
142: handler.setFormatter(formatter)
143: handler.setLevel(logging.DEBUG)
144: root_logger.addHandler(handler)
145: else:
146: # The logfile wasn't specified. Add a stdout logger.
147: add_stdout = True
148:
149: if options.verbose:
150: # Add a stdout logger as well in verbose mode
151: root_logger.setLevel(logging.DEBUG)
152: add_stdout = True
153: else:
154: root_logger.setLevel(logging.INFO)
155:
156: if add_stdout:
157: stdout_handler = logging.StreamHandler(sys.stdout)
158: stdout_handler.setFormatter(formatter)
159: stdout_handler.setLevel(logging.DEBUG)
160: root_logger.addHandler(stdout_handler)
161:
162:
163: class ScriptRC(object):
164: """Enum for script return codes"""
165: SUCCESS = 0
166: FAILURE = 1
167: EXCEPTION = 2
168:
169:
170: class ScriptException(Exception):
171: pass
172:
173:
174: if __name__ == '__main__':
175: # Get the options from the user.
176: options = get_options()
177:
178: # Setup logging using the user options
179: setup_logging(options)
180:
181: # Run main script.
182: try:
183: rc = dictserver(options)
184: except Exception as e:
185: log.exception(e)
186: rc = ScriptRC.EXCEPTION
187:
188: log.info("[DICT] Returning %d", rc)
189: sys.exit(rc)
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>