blob: 28e02f735555f8af58de220e97df68ce4fc72018 [file] [log] [blame]
#!/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):
sys.stdout.write(struct.pack("I", len(message)))
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
# Verify that the process was started in the correct directory.
cwd = os.getcwd()
script_path = os.path.dirname(os.path.abspath(sys.argv[0]))
if cwd.lower() != script_path.lower():
sys.stderr.write('Native messaging host started in a wrong directory.')
return 1
# Verify that --parent-window parameter is correct.
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 =
if len(text_length_bytes) == 0:
# Read the message length (4 bytes).
text_length = struct.unpack('i', text_length_bytes)[0]
# Read the text (JSON object) of the message.
text ='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).
WriteMessage('{"stopped": true }')
message_number += 1
message = '{{"id": {0}, "echo": {1}, "caller_url": "{2}"}}'.format(
message_number, text, caller_url).encode('utf-8')
if not WriteMessage(message):
if __name__ == '__main__':