Example #1
0
    def serve(self):
        """
        Listen for http requests forever and trigger processing.
        """

        try:
            c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            c.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            c.bind(('localhost', self.port))
            c.listen(1)
        except socket.error as msg:
            log(0, msg)
            return

        log(0, "Server running on http://{}:{} .".format('localhost', self.port))

        while 1:
            csock, caddr = c.accept()
            conn = csock.makefile(mode='rwb', buffering=1)
            self.request = Request()
            self.response = Response(conn, self)

            if self.request.parse(conn):
                self.request.origin = caddr[0]
                log(2, "Request: %s" % self.request)
                try:
                    # preprocessing (middlewares)
                    for m in self.middlewares:
                        m.process_request(self.request, self.response)

                    # processing (check registered routes for actions)
                    processed = False
                    for route in self.routes:
                        log(2, "Matche %s gegen %s" % (route[0], self.request.path))
                        match = re.match(route[0], self.request.path)
                        if match:
                            if not route[2] or self.request.method.lower() in [x.lower() for x in route[2]]:
                                log(2, "Route {} und Methode {} matcht Request {}".format(route[0], self.request.method, self.request.path))
                                route[1](self.request, self.response, match)
                                processed = True
                                break

                    if not processed:
                        raise StopProcessing(404, "No matching route.")

                except StopProcessing as spe:
                    self.response.send(code=spe.code, body=spe.reason)

                # preprocessing (middlewares)
                for m in self.middlewares:
                    m.process_response(self.response)

                # actually write response to server connection
                try:
                    self.response.commit()
                except (ConnectionAbortedError, BrokenPipeError):
                    pass

            conn.close()
            csock.close()
Example #2
0
    def commit(self):
        def w(txt):
            """Decode as UTF-8 and write to client connection"""
            self.conn.write(bytes(txt, 'UTF-8'))

        # TT: blatt6 - default values have been moved to constructor
        # TT: to make them available to logging

        from server.statuscodes import statuscode

        (phrase, explanation) = statuscode(self.code)
        w("HTTP/1.1 %d %s\n" % (self.code, phrase))
        log(1, "HTTP/1.1 %d %s (%s)\n" % (self.code, phrase, explanation))

        import datetime

        w("Date: %s\n" %
          datetime.datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S"))
        w("Connection: close\n")

        # send cookies
        for c in self.cookies:
            w(c.get_header())

        # send other headers
        for key, value in self.headers.items():
            w("%s: %s\n" % (key, value))
        w("\n")  # extra leerzeile schliesst header ab

        if self.body:
            if isinstance(self.body, str):  # UTF-8
                w(self.body)
            else:  # bytes, e.g. binary data
                self.conn.write(self.body)
Example #3
0
    async def send_transaction(self, wif, address_from, address_to, amount,
                               txid, vout):
        io = await self.transaction_io(txid, vout, amount, address_from,
                                       address_to)

        if io["inputs"] is None:
            return io
        else:
            outputs = io["outputs"]
            inputs = io["inputs"]

        # creates a replaceable transaction.
        tx = await self.call("createrawtransaction", [inputs, outputs])

        if tx["error"] is None:
            signed = await self.call("signrawtransactionwithkey",
                                     [tx["result"], [wif]])
            if signed["error"] is None:
                sent = await self.call("sendrawtransaction",
                                       [signed["result"]["hex"], 0])
                if sent["result"] is not None:
                    log(f"created tx {sent['result']}")
                return self.parse_response(sent)
            else:
                return self.parse_response(signed)
        else:
            return self.parse_response(tx)
Example #4
0
    def sendfile(self, request, response, pathmatch=None):
        """Serve a static file from local filesystem."""

        # path might be urlencoded
        from urllib.parse import unquote

        resource = unquote(pathmatch.group('file'))

        # directory traversal protection
        # os function os.path.abspath calculates normalized absolute path
        # self.path must be a prefix of it
        from os.path import abspath

        log(
            2,
            "check for directory traversal attack: does %s start with %s ?" %
            (abspath(self.path + resource), abspath(self.path)))
        if not abspath(self.path + resource).startswith(abspath(self.path)):
            raise StopProcessing(
                500,
                "500 internal server error.\nDirectory traversal attack attempted.\n"
            )

        # open, read and server file
        try:
            log(2, "Try to open %s" % resource)
            with open(self.path + resource, 'rb') as f:
                # guess type from extension
                import mimetypes

                (content_type, encoding) = mimetypes.guess_type(resource)
                response.set_content_type(content_type)
                response.send(body=f.read())  # read and dump whole file
        except IOError:
            raise StopProcessing(404, "File not found: %s" % resource)
Example #5
0
 def generate():
     generated = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1)
     private = generated.to_string()
     public = generated.get_verifying_key().to_string()
     # not logged for security reasons.
     # log(f"generated private key '{private.hex()}'")
     log(f"generated public key '{public.hex()}'")
     return Address.create_from(private, public)
Example #6
0
 def process_request(self, request, response):
     """Get session ID from request cookies and load session."""
     if self.cookiename in request.cookies: # try to recover old session
         self.session = Session(request.cookies[self.cookiename], cookiename=self.cookiename)
         log(2,"Loaded from Session: %s" % self.session.data)
     else: # new session
         self.session = Session(cookiename=self.cookiename)
         log(2, "Created New Session")
     request.session = self.session # assignment does not copy objects!
Example #7
0
 def process_response(self, response):
     """Add Session cookie to repsonse or delete session cookie if no session."""
     if self.session and self.session.sessid:
         self.session.save()  # write session to data store
         response.add_cookie(self.session.make_cookie())
         log(2, "Added Session Cookie")
     else:  # delete nonexistant or destroyed empty sessions
         response.add_cookie(self.session.make_delete_cookie())
         log(2, "Delete Session Cookie")
Example #8
0
    def send(self, code=None, headers=None, body=""):
        if not headers:
            headers = {}

        def w(txt):
            """Decode as UTF-8 and write to client connection"""
            self.conn.write(bytes(txt, 'UTF-8'))

        # method parameters overwrite/add to instance variables
        if code:
            self.code = code
        if body:
            self.body = body
        if headers:
            self.headers.update(headers)

        # Set ETag in Header
        tag = self.generate_eTag(self.body)
        if tag == self.etag:
            self.body = None
            self.code = 304

        # default values
        if not self.code:
            self.code = 200
        if 'Content-Type' not in self.headers:
            self.headers['Content-Type'] = "text/html; charset=utf-8"

        from server.statuscodes import statuscode

        (phrase, explanation) = statuscode(self.code)
        w("HTTP/1.1 %d %s\n" % (self.code, phrase))
        log(1, "HTTP/1.1 %d %s (%s)\n" % (self.code, phrase, explanation))

        import datetime

        w("Date: %s\n" %
          datetime.datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S"))
        w("Content-Type: %s\n" % self.headers['Content-Type'])
        w("Connection: close\n")
        for key, value in self.headers.items():
            w("%s: %s\n" % (key, value))

        #Etag Header setzen
        w("ETag: {}\n".format(tag))

        # Addition: Set proper Content Length
        if self.body and not 'Content-Length' in self.headers:
            w("Content-Length: %d\n" % len(self.body))

        w("\n")  # extra leerzeile schliesst header ab

        if self.body:
            if isinstance(self.body, str):
                w(self.body)
            else:
                self.conn.write(self.body)
Example #9
0
    def serve(self):
        """
        Listen for http requests forever and trigger processing.
        """

        try:
            c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            c.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,
                         1)  # ignore TIME_WAIT (also has other side effects!)
            c.bind(('localhost', self.port))
            c.listen(1)
        except socket.error as msg:
            log(0, msg)
            return

        log(0,
            "Server running on http://{}:{} .".format('localhost', self.port))

        while 1:
            csock, caddr = c.accept()
            conn = csock.makefile(mode='rwb', buffering=1)
            self.request = Request()
            self.response = Response(conn)

            if self.request.parse(conn):

                # Blatt 3: Pass etag to response (ugly, we will get to know a more elegant architecture for this later)
                self.response.etag = self.request.etag

                self.request.origin = caddr[0]
                log(2, "Request: %s\n" % self.request)
                try:
                    # processing (check registered routes for actions)
                    processed = False
                    for route in self.routes:
                        log(
                            2, "Matche %s gegen %s" %
                            (route[0], self.request.resource))
                        match = re.match(route[0], self.request.resource)
                        if match:
                            log(
                                2, "Route %s matcht Request %s" %
                                (route[0], self.request.resource))
                            route[1](self.request, self.response, match)
                            processed = True
                            break
                    if not processed:
                        raise StopProcessing(404, "No matching route.")

                except StopProcessing as spe:
                    self.response.send(code=spe.code, body=spe.reason)
                except ConnectionAbortedError as cae:
                    print("Client closed connection: {}. Ignore and go on.".
                          format(cae))
            conn.close()
            csock.close()
Example #10
0
    def parse(self, profile):
        if profile is not None:
            try:
                result = self.decode_html(profile['body']['storage']['value'])
                result['name'] = profile['title']
                result['id'] = profile['id']
                return result
            except:
                log("skipped broken profile {}".format(profile['title']))

        return None
Example #11
0
    def findByUsername(self, username):
        with self.con:
            cur = self.con.cursor()
            cur.execute("SELECT * FROM users WHERE username=?", username)
            row = cur.fetchone()
            log(2, "findByUsername(%s)=%s" % (username, row if row else "[empty result]"))

        if row:
            return User(row)
        else:
            None  # None if no user found
Example #12
0
    def send(self, code=None, headers=None, body=""):

        if not headers:
            headers = {}

        def w(txt):
            """Decode as UTF-8 and write to client connection"""
            self.conn.write(bytes(txt, 'UTF-8'))

        # method parameters overwrite/add to instance variables
        if code:
            self.code = code
        if body:
            self.body = body
        if headers:
            self.headers.update(headers)

        # default values
        if not self.code:
            self.code = 200
        if 'Content-Type' not in self.headers:
            self.headers['Content-Type'] = "text/html; charset=UTF-8"

        from server.statuscodes import statuscode

        (phrase, explanation) = statuscode(self.code)
        w("HTTP/1.1 %d %s\n" % (self.code, phrase))
        log(1, "HTTP/1.1 %d %s (%s)\n" % (self.code, phrase, explanation))

        import datetime

        w("Date: %s\n" %
          datetime.datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S"))
        w("Connection: close\n")
        for key, value in self.headers.items():
            w("%s: %s\n" % (key, value))

        # Addition: Set proper Content Length
        if self.body and 'Content-Length' not in self.headers:
            if isinstance(
                    self.body, str
            ):  # we need length in bytes, so we might have to convert it first
                length = len(bytes(self.body, 'UTF8'))
            else:
                length = len(self.body)
            w("Content-Length: %d\n" % length)

        w("\n")  # extra leerzeile schliesst header ab

        if self.body:
            if isinstance(self.body, str):
                w(self.body)
            else:
                self.conn.write(self.body)
Example #13
0
 def __init__(self, host, port, url, command, data, mimeType):
     log.log(2, "creating command thread for command %s" % command)
     self._connection = http.HTTPConnection(host,
                                            port,
                                            timeout=self.commandTimeout)
     self.url = url
     self.cmd_name = command
     self.data = data
     self.mimeType = mimeType
     threading.Thread.__init__(self)
     self.answer = None
Example #14
0
    def set_number_trigger(self, value):
        headers = {}
        headers['Content-type'] = 'application/json; charset=utf-8'
        data = json.dumps({'value': value})

        log.log(3, "setting ntrigger to %s" % value)
        self._connection.request('PUT',
                                 self.ntrigger_url,
                                 body=data,
                                 headers=headers)
        response = self._connection.getresponse()
        log.log(3, "setting ntrigger returns %s " % str(response))
Example #15
0
    def serve(self):
        """
        Listen for http requests forever and trigger processing.
        """

        try:
            c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            c.bind(('localhost', self.port))
            c.listen(1)
        except socket.error as msg:
            log(0, msg)
            return

        log(0,
            "Server running on http://{}:{} .".format('localhost', self.port))

        while 1:
            csock, caddr = c.accept()
            conn = csock.makefile(mode='rwb', buffering=1)
            self.request = Request()

            if self.request.parse(conn):
                self.request.origin = caddr[0]
                log(2, "Request: %s\n" % self.request)
                etag = self.request.get_etag()
                if etag is False:
                    self.response = Response(conn)
                else:
                    self.response = Response(conn, etag)
                try:
                    # processing (check registered routes for actions)
                    processed = False
                    for route in self.routes:
                        log(
                            2, "Matche %s gegen %s" %
                            (route[0], self.request.resource))
                        match = re.match(route[0], self.request.resource)
                        if match:
                            log(
                                2, "Route %s matcht Request %s" %
                                (route[0], self.request.resource))
                            route[1](self.request, self.response, match)
                            processed = True
                            break
                    if not processed:
                        raise StopProcessing(404, "No matching route.")

                except StopProcessing as spe:
                    self.response.send(code=spe.code, body=spe.reason)

            conn.close()
            csock.close()
Example #16
0
async def run(loop, lamp):
    lifx = lamps.CircadianLifx()
    league = LeagueApi(loop)

    lamp = lifx.get_device_by_name(lamp)

    while True:
        try:
            health = await league.health_percent()
            lifx.set_color(lamp, color(health))
            await asyncio.sleep(0.5)
        except:
            log("no active game - sleeping for 5 seconds.")
            await asyncio.sleep(5)
Example #17
0
def load_from_file():
    log("loading configuration from '{}'..".format(CONFIG_FILE))
    with open(CONFIG_FILE, 'r') as file:
        config = yaml.safe_load(file)
        log('configuration parsed.')
        configurations = {}

        for lamp in config['lamps']:
            lamp_config = LampConfiguration(lamp['name'])
            for schema in lamp['schema']:
                lamp_config.add_schema(SchemaConfiguration(**schema))
            configurations[lamp['name']] = lamp_config

        return configurations
Example #18
0
    def run_command(self, cmdname, url):
        log.log(2, "command %s - (%s) is running" % (self.cmd_name, cmdname))

        headers = {}
        headers['Content-type'] = self.mimeType

        self._connection.request('PUT', url, body=self.data, headers=headers)
        response = self._connection.getresponse()
        status = response.status
        data = response.read()

        if status == 200:
            data_l = json.loads(data)
            if cmdname in ['arm', 'trigger']:
                if 'sequence_id' in data_l.keys():
                    answer = data_l['sequence id']
                else:
                    log.log(
                        3, "answer to %s contains keys: %s" %
                        (cmdname, data_l.keys()))
                    answer = data_l
            else:
                answer = data_l
            log.log(2,
                    "response from %s command :  %s" % (cmdname, str(answer)))
            return answer
        else:
            log.log(
                1, "cannot get response from %s command - status: %s" %
                (cmdname, status))
            return None
Example #19
0
    def login(self, username, password):
        """Checks credentials and return user object if they are correct."""

        with self.con:
            cur = self.con.cursor()
            query = "SELECT * FROM users WHERE username=? AND password=?"
            cur.execute(query, username, password)
            row = cur.fetchone()
            log(2, "login(%s,%s)=%s" % (username, password, row if row else "[empty result]"))

        if row:
            return User(row)
        else:
            return None
Example #20
0
 async def all(self):
     """ lists all profiles and then resolves each. """
     log('retrieving profile cards..')
     start = time.monotonic()
     profiles = await asyncio.gather(*list(
         map(lambda profile: self.retrieve(str(profile['id'])), await
             self.list())))
     elapsed = "%0.2fs" % (time.monotonic() - start, )
     log("retrieved {} profile cards in {}".format(len(profiles), elapsed))
     return {
         "hits": len(profiles),
         "updated": time.time() * 1000,
         "time": elapsed,
         "applicants": list(filter(None, map(self.parse, profiles)))
     }
Example #21
0
async def update():
    con = aiohttp.TCPConnector(limit=8)
    auth = aiohttp.BasicAuth(username, password)

    async with aiohttp.ClientSession(connector=con, auth=auth) as session:
        profiles = ProfileApi(session)
        while True:
            cards = await profiles.all()
            with open(OUTPUT, 'w') as output:
                logger.log('writing user profiles to {}'.format(OUTPUT))
                output.write(json.dumps(cards, indent=4, sort_keys=False))
            logger.log(
                'user profiles written to file, next update in {}s.'.format(
                    UPDATE))
            await asyncio.sleep(UPDATE)
Example #22
0
    def parse(self, conn):
        """Parses an http-Request and return a dictionary with process_request line values and headers."""
        self.headers = {}

        # read process_request line
        request_line = conn.readline().decode('utf-8').strip()
        log(1, "Request-Line: %s" % request_line)
        if not request_line:  # rfc says "server SHOULD ignore blank request lines"
            return None

        # parse process_request line
        try:
            self.method, self.resource, self.protocol = request_line.split(" ")
        except ValueError:
            raise StopProcessing(400, "Bad request-line: %s\n" % request_line)

        # parse resource to path and params
        # extract GET parameters
        from urllib.parse import urlparse, parse_qs # analyse urls and parse query strings
        requrl = urlparse(self.resource)
        self.path = requrl.path
        self.params.update(parse_qs(requrl.query))

        # read and parse Request-Headers
        while True:
            header_line = conn.readline().decode('utf-8').strip()
            if not header_line:
                break
            log(2, "Header-Line: " + header_line)
            (headerfield, headervalue) = header_line.split(":", 1)
            self.headers[headerfield.strip()] = headervalue.strip()

        # read cookies
        if 'Cookie' in self.headers:
            log(2, "Cookie ist: %s" % self.headers['Cookie'])
            self.cookies = Cookie.parse(self.headers['Cookie'])
        else:
            self.cookies = {}

        # parse POST parameters
        log(1,"Methode %s" % self.method)
        if self.method.lower() == 'post' or self.method.lower() == 'put':
            postbody = conn.read(int(self.headers['Content-Length'])).decode('utf-8')
            if 'Content-Type' in self.headers and self.headers['Content-Type'] == 'application/json':  # JSON data
                try:
                    self.jsondata = json.loads(postbody)
                except json.decoder.JSONDecodeError as err:
                    raise StopProcessing(code=400, reason="Unable to decode JSON data: {}".format(err))
            else:  # default is x-www-form-urlencoded
                self.params.update(parse_qs(postbody))

        # all parameter values are lists
        # replace lists by the only element if there is only one
        for key in self.params:
            if len(self.params[key])==1:
                self.params[key] = self.params[key][0]

        return self.headers
Example #23
0
    def commit(self):
        def w(txt):
            """Decode as UTF-8 and write to client connection"""
            self.conn.write(bytes(txt, 'UTF-8'))

        # default values
        if not self.code:
            self.code = 200
        if 'Content-Type' not in self.headers:
            self.headers['Content-Type'] = "text/html; charset=UTF-8"

        from server.statuscodes import statuscode

        (phrase, explanation) = statuscode(self.code)
        w("HTTP/1.1 %d %s\n" % (self.code, phrase))
        log(1, "HTTP/1.1 %d %s (%s)\n" % (self.code, phrase, explanation))

        import datetime

        w("Date: %s\n" %
          datetime.datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S"))
        w("Connection: close\n")

        # send cookies
        for c in self.cookies:
            w(c.get_header())

        # send other headers
        for key, value in self.headers.items():
            w("%s: %s\n" % (key, value))

        # Addition: Set proper Content Length
        if self.body and 'Content-Length' not in self.headers:
            if isinstance(
                    self.body, str
            ):  # we need length in bytes, so we might have to convert it first
                length = len(bytes(self.body, 'UTF8'))
            else:
                length = len(self.body)
            w("Content-Length: %d\n" % length)

        w("\n")  # extra leerzeile schliesst header ab

        if self.body:
            if isinstance(self.body, str):  # UTF-8
                w(self.body)
            else:  # bytes, e.g. binary data
                self.conn.write(self.body)
Example #24
0
 def serve(self):
     log("serving contents of /web.")
     app = web.Application()
     app.add_routes([
         web.get('/', self.index),
         web.post('/api/info', self.info),
         web.post('/api/blockhash', self.blockhash),
         web.post('/api/block', self.block),
         web.post('/api/minecraft', self.mine),
         web.post('/api/txinfo', self.txinfo),
         web.post('/api/outputs', self.outputs),
         web.get('/api/address', self.address),
         web.post('/api/transact', self.transact)
     ])
     app.router.add_static('/', './web')
     web.run_app(app)
Example #25
0
    async def call(self, method, params=[], cache=False):
        data = {"method": method, "params": params}
        log(f"invoking rpc call '{method}'")

        payload = json.dumps(data)
        tag = hash(payload)
        try:
            if cache and tag in self.cache:
                return self.cache[tag]
            else:
                async with self.session.post(URL, data=payload) as response:
                    response = json.loads(await response.text())
                    if cache:
                        self.cache[tag] = response
                    return response
        except Exception as e:
            log("Failed to call {}, {}".format(URL, repr(e)))
            return None
Example #26
0
    def updateCommandStatus(self):
        if self.detector_command is None:
            return

        cmd_alive = self.detector_command.is_alive()

        if cmd_alive is False:
            try:
                cmd_name = self.detector_command.getCommandName()
                ret_value = self.detector_command.getCommandAnswer()
                self.cmd_answer[cmd_name] = ret_value
                log.log(
                    2, "command %s finished execution. answer is: %s" %
                    (cmd_name, ret_value))
            except BaseException as e:
                log.log(1, "error update command: %s" % str(e))

            self.detector_command = None
Example #27
0
    def __init__(self,
                 host='127.0.0.1',
                 port=80,
                 verbose=False,
                 urlPrefix=None,
                 user=None):
        """
        Create a client object to talk to the EIGER API.
        Args:
            host: hostname of the detector computer
            port: port usually 80 (http)
            verbose: bool value
            urlPrefix: String prepended to the urls. Should be None. Added for future convenience.
            user: "******". Should be None. Added for future convenience.
        """
        super(DEigerClient, self).__init__()
        self._host = host
        self._port = port
        self._version = Version
        self._verbose = verbose
        self._urlPrefix = ""
        self._user = None
        self._connectionTimeout = MAX_TIMEOUT

        #pingret = os.system("ping -c 1 -w 1 -W 10 %s > /dev/null 2>&1" % self._host)
        #if pingret != 0:
        #raise BaseException("Cannot access DCU")

        try:
            self._connection = http.HTTPConnection(
                self._host, self._port, timeout=self._connectionTimeout)
        except BaseException as exc:
            log.log(1, "Exception while connecting to Eiger DCU %s" % str(exc))
            raise (e)

        self._serializer = None

        self.detector_command = None
        self.cmd_answer = {}

        self.read_thread = None
        self.read_value = {}
        self.setUrlPrefix(urlPrefix)
        self.setUser(user)
Example #28
0
    def startAcquisition(self, need_arm=True, trigger_mode='ints', ntrigger=1):
        if self.isExecutingCommand():
            log.log(1, "cannot start acquisition while a command is running")
            return False

        arm_url = self._url('detector', 'command', 'arm')
        trigger_url = self._url('detector', 'command', 'trigger')
        ntrigger_url = self._url('detector', 'config', 'ntrigger')

        self.detector_command = StartAcquisitionThread(self._host, self._port, \
                arm_url, trigger_url, ntrigger_url)

        self.detector_command.set_arm_needed(need_arm)
        self.detector_command.set_trigger_mode(trigger_mode)
        self.detector_command.set_ntrigger(ntrigger)

        self.startDetectorCommand()

        return True
 def authenticate(self):
     """Check if user is authenticated. If not, send 401."""
     log(2, "Checking for authentication")
     if self.request.user:  #
         log(2, "Authentication OK")
         return True
     else:
         log(2, "Authentication not OK, send 401")
         self.response.add_header(
             "WWW-Authenticate", 'RestBasic realm="We need your password."')
         self.response.add_header('Content-Type', 'application/json')
         raise StopProcessing(
             401, json.dumps({"error": "Authentiction required."}))
Example #30
0
    def parse(self, conn):
        """Parses an http-Request and return a dictionary with process_request line values and headers."""
        self.headers = {}

        # read process_request line
        request_line = conn.readline().decode('utf-8').strip()
        log(1, "Request-Line: %s" % request_line)
        if not request_line:  # rfc says "server SHOULD ignore blank request lines"
            return None

        # parse process_request line
        try:
            self.method, self.resource, self.protocol = request_line.split(" ")
        except ValueError:
            raise StopProcessing(400, "Bad request-line: %s\n" % request_line)

        # parse resource to path and params
        # extract GET parameters
        from urllib.parse import urlparse, parse_qs  # analyse urls and parse query strings
        requrl = urlparse(self.resource)
        self.path = requrl.path
        self.params.update(parse_qs(requrl.query))

        # read and parse Request-Headers
        while True:
            header_line = conn.readline().decode('utf-8').strip()
            if not header_line:
                break
            log(2, "Header-Line: " + header_line)
            (headerfield, headervalue) = header_line.split(":", 1)
            self.headers[headerfield.strip()] = headervalue.strip()

        # parse POST parameters
        log(1, "Methode %s" % self.method)
        if self.method == 'POST' or self.method == 'post':
            postbody = conn.read(int(
                self.headers['Content-Length'])).decode('utf-8')
            self.params.update(parse_qs(postbody))

        # all parameter values are lists
        # replace lists by the only element if there is only one
        for key in self.params:
            if len(self.params[key]) == 1:
                self.params[key] = self.params[key][0]

        # Blatt 03: Add Etag handling (If-None-Matches header)
        if "If-None-Match" in self.headers:
            self.etag = self.headers['If-None-Match'].strip(
                '"')  # strip off quotes

        return self.headers
Example #31
0
host='localhost'
## Server port.
port=8000

## Display the help of the server.
def displayHelp():
	print("python server.py [host port]\n\tStart a local server at address ws://%s:%s/." % (host, port))
	print("python server.py -d\n\tStart a server at address ws://%s:%s/." % (socket.gethostbyname(socket.gethostname()), port))

if __name__ == '__main__':
	# Parse command line arguments
	if len(sys.argv)==1:
		pass
	elif len(sys.argv)==2 and sys.argv[1]=="-d":
		host=socket.gethostbyname(socket.gethostname())
	elif len(sys.argv)==3:
		host=sys.argv[1]
		port=int(sys.argv[2])
	else:
		displayHelp()
		exit(1)

	# Start the computation thread
	threading.Thread(target=simulationCompute).start()

	# Start the server
	log("Server started on ws://%s:%s/ with PID %s." % (host, port, os.getpid()))
	start_server = websockets.serve(clientHandler, host, port, klass=IPGetterProtocol)
	asyncio.get_event_loop().run_until_complete(start_server)
	asyncio.get_event_loop().run_forever()