def do_GET(self):
        """
        Returns True if the requested URL is supported
        """

        if RobotWebHandler.do_GET(self):
            return True

        global motor_max_speed
        global medium_motor_max_speed
        global max_move_xy_seq
        global joystick_engaged

        if medium_motor_max_speed is None:
            motor_max_speed = self.robot.left_motor.max_speed

            if hasattr(self.robot, 'medium_motor'):
                medium_motor_max_speed = self.robot.medium_motor.max_speed
            else:
                medium_motor_max_speed = 0

        '''
        Sometimes we get AJAX requests out of order like this:
        2016-09-06 02:29:35,846 DEBUG: seq 65: (x, y): 0, 44 -> speed 462 462
        2016-09-06 02:29:35,910 DEBUG: seq 66: (x, y): 0, 45 -> speed 473 473
        2016-09-06 02:29:35,979 DEBUG: seq 67: (x, y): 0, 46 -> speed 483 483
        2016-09-06 02:29:36,033 DEBUG: seq 69: (x, y): -1, 48 -> speed 491 504
        2016-09-06 02:29:36,086 DEBUG: seq 68: (x, y): -1, 47 -> speed 480 494
        2016-09-06 02:29:36,137 DEBUG: seq 70: (x, y): -1, 49 -> speed 501 515
        2016-09-06 02:29:36,192 DEBUG: seq 73: (x, y): -2, 51 -> speed 509 536
        2016-09-06 02:29:36,564 DEBUG: seq 74: (x, y): -3, 51 -> speed 496 536
        2016-09-06 02:29:36,649  INFO: seq 75: CLIENT LOG: touchend
        2016-09-06 02:29:36,701 DEBUG: seq 71: (x, y): -1, 50 -> speed 512 525
        2016-09-06 02:29:36,760 DEBUG: seq 76: move stop
        2016-09-06 02:29:36,814 DEBUG: seq 72: (x, y): -1, 51 -> speed 522 536

        This can be bad because the last command sequentially was #76 which was "move stop"
        but we RXed seq #72 after that so we started moving again and never stopped

        A quick fix is to have the client send us an AJAX request to let us know
        when the joystick has been engaged so that we can ignore any move-xy events
        that we get out of order and show up after "move stop" but before the
        next "joystick-engaged"

        We can also ignore any move-xy requests that show up late by tracking the
        max seq for any move-xy we service.
        '''
        path = self.path.split('/')
        seq = int(path[1])
        action = path[2]

        # desktop interface
        if action == 'move-start':
            direction = path[3]
            speed_percentage = path[4]
            log.debug("seq %d: move %s" % (seq, direction))

            left_speed = int(int(speed_percentage) * motor_max_speed)/100.0
            right_speed = int(int(speed_percentage) * motor_max_speed)/100.0

            if direction == 'forward':
                self.robot.left_motor.run_forever(speed_sp=left_speed)
                self.robot.right_motor.run_forever(speed_sp=right_speed)

            elif direction == 'backward':
                self.robot.left_motor.run_forever(speed_sp=left_speed * -1)
                self.robot.right_motor.run_forever(speed_sp=right_speed * -1)

            elif direction == 'left':
                self.robot.left_motor.run_forever(speed_sp=left_speed * -1)
                self.robot.right_motor.run_forever(speed_sp=right_speed)

            elif direction == 'right':
                self.robot.left_motor.run_forever(speed_sp=left_speed)
                self.robot.right_motor.run_forever(speed_sp=right_speed * -1)

        # desktop & mobile interface
        elif action == 'move-stop':
            log.debug("seq %d: move stop" % seq)
            self.robot.left_motor.stop()
            self.robot.right_motor.stop()
            joystick_engaged = False

        # medium motor
        elif action == 'motor-stop':
            motor = path[3]
            log.debug("seq %d: motor-stop %s" % (seq, motor))

            if motor == 'medium':
                if hasattr(self.robot, 'medium_motor'):
                    self.robot.medium_motor.stop()
            else:
                raise Exception("motor %s not supported yet" % motor)

        elif action == 'motor-start':
            motor = path[3]
            direction = path[4]
            speed_percentage = path[5]
            log.debug("seq %d: start motor %s, direction %s, speed_percentage %s" % (seq, motor, direction, speed_percentage))

            if motor == 'medium':
                if hasattr(self.robot, 'medium_motor'):
                    if direction == 'clockwise':
                        medium_speed = int(int(speed_percentage) * medium_motor_max_speed)/100.0
                        self.robot.medium_motor.run_forever(speed_sp=medium_speed)

                    elif direction == 'counter-clockwise':
                        medium_speed = int(int(speed_percentage) * medium_motor_max_speed)/100.0
                        self.robot.medium_motor.run_forever(speed_sp=medium_speed * -1)
                else:
                    log.info("we do not have a medium_motor")
            else:
                raise Exception("motor %s not supported yet" % motor)

        # mobile interface
        elif action == 'move-xy':
            x = int(path[3])
            y = int(path[4])

            if joystick_engaged:
                if seq > max_move_xy_seq:
                    self.robot.on(x, y)
                    max_move_xy_seq = seq
                    log.debug("seq %d: (x, y) (%4d, %4d)" % (seq, x, y))
                else:
                    log.debug("seq %d: (x, y) %4d, %4d (ignore, max seq %d)" %
                              (seq, x, y, max_move_xy_seq))
            else:
                log.debug("seq %d: (x, y) %4d, %4d (ignore, joystick idle)" %
                          (seq, x, y))

        elif action == 'joystick-engaged':
            joystick_engaged = True

        elif action == 'log':
            msg = ''.join(path[3:])
            re_msg = re.search('^(.*)\?', msg)

            if re_msg:
                msg = re_msg.group(1)

            log.debug("seq %d: CLIENT LOG: %s" % (seq, msg))

        else:
            log.warning("Unsupported URL %s" % self.path)

        # It is good practice to send this but if we are getting move-xy we
        # tend to get a lot of them and we need to be as fast as possible so
        # be bad and don't send a reply. This takes ~20ms.
        if action != 'move-xy':
            self.send_response(204)

        return True
Returns True if the requested URL is supported