#!/usr/bin/env python # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # A simple native client in python. # All this client does is echo the text it receives back at the extension. import os import platform import sys import struct def WriteMessage(message): try: sys.stdout.write(struct.pack("I", len(message))) sys.stdout.write(message) sys.stdout.flush() return True except IOError: return False def Main(): message_number = 0 caller_url = None parent_window = None if len(sys.argv) < 2: sys.stderr.write("URL of the calling application is not specified.\n") return 1 # TODO(sergeyu): Use argparse module to parse the arguments (not available in # Python 2.6). for arg in sys.argv[1:]: if arg.startswith('--'): if arg.startswith('--parent-window='): parent_window = long(arg[len('--parent-window='):]) elif caller_url == None: caller_url = arg if platform.system() == 'Windows' and parent_window: import win32gui if not win32gui.IsWindow(parent_window): sys.stderr.write('Invalid --parent-window.\n') return 1 while 1: # Read the message type (first 4 bytes). text_length_bytes = sys.stdin.read(4) if len(text_length_bytes) == 0: break # Read the message length (4 bytes). text_length = struct.unpack('i', text_length_bytes)[0] # Read the text (JSON object) of the message. text = sys.stdin.read(text_length).decode('utf-8') # bigMessage() test sends a special message that is sent to verify that # chrome rejects messages that are too big. Try sending a message bigger # than 1MB after receiving a message that contains 'bigMessageTest'. if 'bigMessageTest' in text: text = '{"key": "' + ("x" * 1024 * 1024) + '"}' # "stopHostTest" verifies that Chrome properly handles the case when the # host quits before port is closed. When the test receives response it # will try sending second message and it should fail becasue the stdin # pipe will be closed at that point. if 'stopHostTest' in text: # Using os.close() here because sys.stdin.close() doesn't really close # the pipe (it just marks it as closed, but doesn't close the file # descriptor). os.close(sys.stdin.fileno()) WriteMessage('{"stopped": true }') sys.exit(0) message_number += 1 message = '{{"id": {0}, "echo": {1}, "caller_url": "{2}"}}'.format( message_number, text, caller_url).encode('utf-8') if not WriteMessage(message): break if __name__ == '__main__': sys.exit(Main())