summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryoz@chromium.org <yoz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-21 00:25:28 +0000
committeryoz@chromium.org <yoz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-21 00:25:28 +0000
commit211b80bf18ff553288d28696edeb444fe126ba50 (patch)
tree52c466520e96868c0abd0a101a784fbfa271220c
parentb48641366de449bb8fcbd3cc401420f65daae63b (diff)
downloadchromium_src-211b80bf18ff553288d28696edeb444fe126ba50.zip
chromium_src-211b80bf18ff553288d28696edeb444fe126ba50.tar.gz
chromium_src-211b80bf18ff553288d28696edeb444fe126ba50.tar.bz2
Revert 152439 - Initial checkin for devtools-based automation
It fails check_licenses. Review URL: https://chromiumcodereview.appspot.com/10825463 TBR=nduca@chromium.org Review URL: https://chromiumcodereview.appspot.com/10831399 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@152445 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--tools/devtools_auto/OWNERS5
-rw-r--r--tools/devtools_auto/README4
-rw-r--r--tools/devtools_auto/third_party/websocket-client/.gitignore8
-rw-r--r--tools/devtools_auto/third_party/websocket-client/LICENSE506
-rw-r--r--tools/devtools_auto/third_party/websocket-client/MANIFEST.in2
-rw-r--r--tools/devtools_auto/third_party/websocket-client/README.chromium19
-rw-r--r--tools/devtools_auto/third_party/websocket-client/README.rst140
-rwxr-xr-xtools/devtools_auto/third_party/websocket-client/bin/wsdump.py111
-rw-r--r--tools/devtools_auto/third_party/websocket-client/data/header01.txt6
-rw-r--r--tools/devtools_auto/third_party/websocket-client/data/header02.txt6
-rw-r--r--tools/devtools_auto/third_party/websocket-client/examples/echo_client.py12
-rw-r--r--tools/devtools_auto/third_party/websocket-client/examples/echoapp_client.py41
-rw-r--r--tools/devtools_auto/third_party/websocket-client/setup.py28
-rw-r--r--tools/devtools_auto/third_party/websocket-client/test_websocket.py311
-rw-r--r--tools/devtools_auto/third_party/websocket-client/websocket.py756
15 files changed, 0 insertions, 1955 deletions
diff --git a/tools/devtools_auto/OWNERS b/tools/devtools_auto/OWNERS
deleted file mode 100644
index 5f68319..0000000
--- a/tools/devtools_auto/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# The set noparent is temporary until src/OWNERS isn't *.
-set noparent
-nduca@chromium.org
-alokp@chromium.org
-dtu@chromium.org
diff --git a/tools/devtools_auto/README b/tools/devtools_auto/README
deleted file mode 100644
index 0d1d5f2..0000000
--- a/tools/devtools_auto/README
+++ /dev/null
@@ -1,4 +0,0 @@
-devtools_auto provides automation of chrome instances on top of the chrome developer tools protocol.
-
-The protocol we use:
-https://developers.google.com/chrome-developer-tools/docs/remote-debugging
diff --git a/tools/devtools_auto/third_party/websocket-client/.gitignore b/tools/devtools_auto/third_party/websocket-client/.gitignore
deleted file mode 100644
index c7d73ad..0000000
--- a/tools/devtools_auto/third_party/websocket-client/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-*.pyc
-*~
-*\#
-.\#*
-
-build
-dist
-websocket_client.egg-info
diff --git a/tools/devtools_auto/third_party/websocket-client/LICENSE b/tools/devtools_auto/third_party/websocket-client/LICENSE
deleted file mode 100644
index c255f4a..0000000
--- a/tools/devtools_auto/third_party/websocket-client/LICENSE
+++ /dev/null
@@ -1,506 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
-
-
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
-
-
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
diff --git a/tools/devtools_auto/third_party/websocket-client/MANIFEST.in b/tools/devtools_auto/third_party/websocket-client/MANIFEST.in
deleted file mode 100644
index 9d5d250..0000000
--- a/tools/devtools_auto/third_party/websocket-client/MANIFEST.in
+++ /dev/null
@@ -1,2 +0,0 @@
-include LICENSE
-include README.rst
diff --git a/tools/devtools_auto/third_party/websocket-client/README.chromium b/tools/devtools_auto/third_party/websocket-client/README.chromium
deleted file mode 100644
index 0ef7731..0000000
--- a/tools/devtools_auto/third_party/websocket-client/README.chromium
+++ /dev/null
@@ -1,19 +0,0 @@
-Name: Python websocket-client
-Short Name: websocket-client
-URL: https://github.com/liris/websocket-client
-Version: 0
-Revision: 861f9cf354833fe3992315b60292865c5245c821
-Date: Tue Jul 10 19:57:00 2012 -0700
-License: LGPL-2.1
-License File: NOT_SHIPPED
-Security Critical: no
-
-Description:
-
-websocket-client module is WebSocket client for python. This provide the low
-level APIs for WebSocket. All APIs are the synchronous functions.
-
-Used by the python code in devtools-auto to communicate with a running Chrome instance.
-
-Local Modifications:
-None.
diff --git a/tools/devtools_auto/third_party/websocket-client/README.rst b/tools/devtools_auto/third_party/websocket-client/README.rst
deleted file mode 100644
index 1b7faeb..0000000
--- a/tools/devtools_auto/third_party/websocket-client/README.rst
+++ /dev/null
@@ -1,140 +0,0 @@
-=================
-websocket-client
-=================
-
-websocket-client module is WebSocket client for python. This provide the low level APIs for WebSocket. All APIs are the synchronous functions.
-
-websocket-client supports only hybi-13.
-
-License
-============
-
- - LGPL
-
-Installation
-=============
-
-This module is tested on only Python 2.7.
-
-Type "python setup.py install" or "pip install websocket-client" to install.
-
-This module does not depend on any other module.
-
-Example
-============
-
-Low Level API example::
-
- from websocket import create_connection
- ws = create_connection("ws://echo.websocket.org/")
- print "Sending 'Hello, World'..."
- ws.send("Hello, World")
- print "Sent"
- print "Reeiving..."
- result = ws.recv()
- print "Received '%s'" % result
- ws.close()
-
-
-JavaScript websocket-like API example::
-
- import websocket
- import thread
- import time
-
- def on_message(ws, message):
- print message
-
- def on_error(ws, error):
- print error
-
- def on_close(ws):
- print "### closed ###"
-
- def on_open(ws):
- def run(*args):
- for i in range(3):
- time.sleep(1)
- ws.send("Hello %d" % i)
- time.sleep(1)
- ws.close()
- print "thread terminating..."
- thread.start_new_thread(run, ())
-
-
- if __name__ == "__main__":
- websocket.enableTrace(True)
- ws = websocket.WebSocketApp("ws://echo.websocket.org/",
- on_message = on_message,
- on_error = on_error,
- on_close = on_close)
- ws.on_open = on_open
-
- ws.run_forever()
-
-
-wsdump.py
-============
-
-wsdump.py is simple WebSocket test(debug) tool.
-
-sample for echo.websocket.org::
-
- $ wsdump.py ws://echo.websocket.org/
- Press Ctrl+C to quit
- > Hello, WebSocket
- < Hello, WebSocket
- > How are you?
- < How are you?
-
-Usage
----------
-
-usage::
- wsdump.py [-h] [-v [VERBOSE]] ws_url
-
-WebSocket Simple Dump Tool
-
-positional arguments:
- ws_url websocket url. ex. ws://echo.websocket.org/
-
-optional arguments:
- -h, --help show this help message and exit
-
- -v VERBOSE, --verbose VERBOSE set verbose mode. If set to 1, show opcode. If set to 2, enable to trace websocket module
-
-example::
-
- $ wsdump.py ws://echo.websocket.org/
- $ wsdump.py ws://echo.websocket.org/ -v
- $ wsdump.py ws://echo.websocket.org/ -vv
-
-ChangeLog
-============
-
-- v0.7.0
-
- - fixed problem to read long data.(ISSUE#12)
- - fix buffer size boundary violation
-
-- v0.6.0
-
- - Patches: UUID4, self.keep_running, mask_key (ISSUE#11)
- - add wsdump.py tool
-
-- v0.5.2
-
- - fix Echo App Demo Throw Error: 'NoneType' object has no attribute 'opcode (ISSUE#10)
-
-- v0.5.1
-
- - delete invalid print statement.
-
-- v0.5.0
-
- - support hybi-13 protocol.
-
-- v0.4.1
-
- - fix incorrect custom header order(ISSUE#1)
-
diff --git a/tools/devtools_auto/third_party/websocket-client/bin/wsdump.py b/tools/devtools_auto/third_party/websocket-client/bin/wsdump.py
deleted file mode 100755
index 02b40af..0000000
--- a/tools/devtools_auto/third_party/websocket-client/bin/wsdump.py
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/env python
-
-import argparse
-import code
-import sys
-import threading
-import websocket
-try:
- import readline
-except:
- pass
-
-
-OPCODE_DATA = (websocket.ABNF.OPCODE_TEXT, websocket.ABNF.OPCODE_BINARY)
-ENCODING = getattr(sys.stdin, "encoding", "").lower()
-
-class VAction(argparse.Action):
- def __call__(self, parser, args, values, option_string=None):
- if values==None:
- values = "1"
- try:
- values = int(values)
- except ValueError:
- values = values.count("v")+1
- setattr(args, self.dest, values)
-
-def parse_args():
- parser = argparse.ArgumentParser(description="WebSocket Simple Dump Tool")
- parser.add_argument("url", metavar="ws_url",
- help="websocket url. ex. ws://echo.websocket.org/")
- parser.add_argument("-v", "--verbose", default=0, nargs='?', action=VAction,
- dest="verbose",
- help="set verbose mode. If set to 1, show opcode. "
- "If set to 2, enable to trace websocket module")
-
- return parser.parse_args()
-
-
-class InteractiveConsole(code.InteractiveConsole):
- def write(self, data):
- sys.stdout.write("\033[2K\033[E")
- # sys.stdout.write("\n")
- sys.stdout.write("\033[34m" + data + "\033[39m")
- sys.stdout.write("\n> ")
- sys.stdout.flush()
-
-
- def raw_input(self, prompt):
- line = raw_input(prompt)
- if ENCODING and ENCODING != "utf-8" and not isinstance(line, unicode):
- line = line.decode(ENCODING).encode("utf-8")
- elif isinstance(line, unicode):
- line = encode("utf-8")
-
- return line
-
-
-def main():
- args = parse_args()
- console = InteractiveConsole()
- ws = websocket.create_connection(args.url)
- if args.verbose > 1:
- websocket.enableTrace(True)
- print "Press Ctrl+C to quit"
-
- def recv():
- frame = ws.recv_frame()
- if not frame:
- raise websocket.WebSocketException("Not a valid frame %s" % frame)
- elif frame.opcode in OPCODE_DATA:
- return (frame.opcode, frame.data)
- elif frame.opcode == websocket.ABNF.OPCODE_CLOSE:
- ws.send_close()
- return (frame.opcode, None)
- elif frame.opcode == websocket.ABNF.OPCODE_PING:
- ws.pong("Hi!")
-
- return None, None
-
-
- def recv_ws():
- while True:
- opcode, data = recv()
- msg = None
- if not args.verbose and opcode in OPCODE_DATA:
- msg = "< %s" % data
- elif args.verbose:
- msg = "< %s: %s" % (websocket.ABNF.OPCODE_MAP.get(opcode), data)
-
- if msg:
- console.write(msg)
-
- thread = threading.Thread(target=recv_ws)
- thread.daemon = True
- thread.start()
-
- while True:
- try:
- message = console.raw_input("> ")
- ws.send(message)
- except KeyboardInterrupt:
- return
- except EOFError:
- return
-
-
-if __name__ == "__main__":
- try:
- main()
- except Exception, e:
- print e
diff --git a/tools/devtools_auto/third_party/websocket-client/data/header01.txt b/tools/devtools_auto/third_party/websocket-client/data/header01.txt
deleted file mode 100644
index 3142b43..0000000
--- a/tools/devtools_auto/third_party/websocket-client/data/header01.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-HTTP/1.1 101 WebSocket Protocol Handshake
-Connection: Upgrade
-Upgrade: WebSocket
-Sec-WebSocket-Accept: Kxep+hNu9n51529fGidYu7a3wO0=
-some_header: something
-
diff --git a/tools/devtools_auto/third_party/websocket-client/data/header02.txt b/tools/devtools_auto/third_party/websocket-client/data/header02.txt
deleted file mode 100644
index a9dd2ce..0000000
--- a/tools/devtools_auto/third_party/websocket-client/data/header02.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-HTTP/1.1 101 WebSocket Protocol Handshake
-Connection: Upgrade
-Upgrade WebSocket
-Sec-WebSocket-Accept: Kxep+hNu9n51529fGidYu7a3wO0=
-some_header: something
-
diff --git a/tools/devtools_auto/third_party/websocket-client/examples/echo_client.py b/tools/devtools_auto/third_party/websocket-client/examples/echo_client.py
deleted file mode 100644
index 1eb5f1b..0000000
--- a/tools/devtools_auto/third_party/websocket-client/examples/echo_client.py
+++ /dev/null
@@ -1,12 +0,0 @@
-import websocket
-
-if __name__ == "__main__":
- websocket.enableTrace(True)
- ws = websocket.create_connection("ws://echo.websocket.org/")
- print "Sending 'Hello, World'..."
- ws.send("Hello, World")
- print "Sent"
- print "Receiving..."
- result = ws.recv()
- print "Received '%s'" % result
- ws.close()
diff --git a/tools/devtools_auto/third_party/websocket-client/examples/echoapp_client.py b/tools/devtools_auto/third_party/websocket-client/examples/echoapp_client.py
deleted file mode 100644
index 438e4b3..0000000
--- a/tools/devtools_auto/third_party/websocket-client/examples/echoapp_client.py
+++ /dev/null
@@ -1,41 +0,0 @@
-import websocket
-import thread
-import time
-import sys
-
-def on_message(ws, message):
- print message
-
-def on_error(ws, error):
- print error
-
-def on_close(ws):
- print "### closed ###"
-
-def on_open(ws):
- def run(*args):
- for i in range(3):
- # send the message, then wait
- # so thread doesnt exit and socket
- # isnt closed
- ws.send("Hello %d" % i)
- time.sleep(1)
-
- time.sleep(1)
- ws.close()
- print "Thread terminating..."
-
- thread.start_new_thread(run, ())
-
-if __name__ == "__main__":
- websocket.enableTrace(True)
- if len(sys.argv) < 2:
- host = "ws://echo.websocket.org/"
- else:
- host = sys.argv[1]
- ws = websocket.WebSocketApp(host,
- on_message = on_message,
- on_error = on_error,
- on_close = on_close)
- ws.on_open = on_open
- ws.run_forever()
diff --git a/tools/devtools_auto/third_party/websocket-client/setup.py b/tools/devtools_auto/third_party/websocket-client/setup.py
deleted file mode 100644
index e11400e..0000000
--- a/tools/devtools_auto/third_party/websocket-client/setup.py
+++ /dev/null
@@ -1,28 +0,0 @@
-from setuptools import setup
-
-VERSION = "0.7.0"
-
-
-setup(
- name="websocket-client",
- version=VERSION,
- description="WebSocket client for python. hybi13 is supported.",
- long_description=open("README.rst").read(),
- author="liris",
- author_email="liris.pp@gmail.com",
- license="LGPL",
- url="https://github.com/liris/websocket-client",
- classifiers = [
- "Development Status :: 3 - Alpha",
- "License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",
- "Programming Language :: Python",
- "Operating System :: MacOS :: MacOS X",
- "Operating System :: POSIX",
- "Operating System :: Microsoft :: Windows",
- "Topic :: Internet",
- "Topic :: Software Development :: Libraries :: Python Modules",
- "Intended Audience :: Developers",
- ],
- py_modules=["websocket"],
- scripts=["bin/wsdump.py"]
-)
diff --git a/tools/devtools_auto/third_party/websocket-client/test_websocket.py b/tools/devtools_auto/third_party/websocket-client/test_websocket.py
deleted file mode 100644
index 3471f4e..0000000
--- a/tools/devtools_auto/third_party/websocket-client/test_websocket.py
+++ /dev/null
@@ -1,311 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-
-import base64
-import uuid
-import unittest
-
-# websocket-client
-import websocket as ws
-
-TRACABLE=False
-
-def create_mask_key(n):
- return "abcd"
-
-class StringSockMock:
- def __init__(self):
- self.set_data("")
- self.sent = []
-
- def set_data(self, data):
- self.data = data
- self.pos = 0
- self.len = len(data)
-
- def recv(self, bufsize):
- if self.len < self.pos:
- return
- buf = self.data[self.pos: self.pos + bufsize]
- self.pos += bufsize
- return buf
-
- def send(self, data):
- self.sent.append(data)
-
-
-class HeaderSockMock(StringSockMock):
- def __init__(self, fname):
- self.set_data(open(fname).read())
- self.sent = []
-
-
-class WebSocketTest(unittest.TestCase):
- def setUp(self):
- ws.enableTrace(TRACABLE)
-
- def tearDown(self):
- pass
-
- def testDefaultTimeout(self):
- self.assertEquals(ws.getdefaulttimeout(), None)
- ws.setdefaulttimeout(10)
- self.assertEquals(ws.getdefaulttimeout(), 10)
- ws.setdefaulttimeout(None)
-
- def testParseUrl(self):
- p = ws._parse_url("ws://www.example.com/r")
- self.assertEquals(p[0], "www.example.com")
- self.assertEquals(p[1], 80)
- self.assertEquals(p[2], "/r")
- self.assertEquals(p[3], False)
-
- p = ws._parse_url("ws://www.example.com/r/")
- self.assertEquals(p[0], "www.example.com")
- self.assertEquals(p[1], 80)
- self.assertEquals(p[2], "/r/")
- self.assertEquals(p[3], False)
-
- p = ws._parse_url("ws://www.example.com/")
- self.assertEquals(p[0], "www.example.com")
- self.assertEquals(p[1], 80)
- self.assertEquals(p[2], "/")
- self.assertEquals(p[3], False)
-
- p = ws._parse_url("ws://www.example.com")
- self.assertEquals(p[0], "www.example.com")
- self.assertEquals(p[1], 80)
- self.assertEquals(p[2], "/")
- self.assertEquals(p[3], False)
-
- p = ws._parse_url("ws://www.example.com:8080/r")
- self.assertEquals(p[0], "www.example.com")
- self.assertEquals(p[1], 8080)
- self.assertEquals(p[2], "/r")
- self.assertEquals(p[3], False)
-
- p = ws._parse_url("ws://www.example.com:8080/")
- self.assertEquals(p[0], "www.example.com")
- self.assertEquals(p[1], 8080)
- self.assertEquals(p[2], "/")
- self.assertEquals(p[3], False)
-
- p = ws._parse_url("ws://www.example.com:8080")
- self.assertEquals(p[0], "www.example.com")
- self.assertEquals(p[1], 8080)
- self.assertEquals(p[2], "/")
- self.assertEquals(p[3], False)
-
- p = ws._parse_url("wss://www.example.com:8080/r")
- self.assertEquals(p[0], "www.example.com")
- self.assertEquals(p[1], 8080)
- self.assertEquals(p[2], "/r")
- self.assertEquals(p[3], True)
-
- p = ws._parse_url("wss://www.example.com:8080/r?key=value")
- self.assertEquals(p[0], "www.example.com")
- self.assertEquals(p[1], 8080)
- self.assertEquals(p[2], "/r?key=value")
- self.assertEquals(p[3], True)
-
- self.assertRaises(ValueError, ws._parse_url, "http://www.example.com/r")
-
- def testWSKey(self):
- key = ws._create_sec_websocket_key()
- self.assert_(key != 24)
- self.assert_("¥n" not in key)
-
- def testWsUtils(self):
- sock = ws.WebSocket()
-
- key = "c6b8hTg4EeGb2gQMztV1/g=="
- required_header = {
- "upgrade": "websocket",
- "connection": "upgrade",
- "sec-websocket-accept": "Kxep+hNu9n51529fGidYu7a3wO0=",
- }
- self.assertEquals(sock._validate_header(required_header, key), True)
-
- header = required_header.copy()
- header["upgrade"] = "http"
- self.assertEquals(sock._validate_header(header, key), False)
- del header["upgrade"]
- self.assertEquals(sock._validate_header(header, key), False)
-
- header = required_header.copy()
- header["connection"] = "something"
- self.assertEquals(sock._validate_header(header, key), False)
- del header["connection"]
- self.assertEquals(sock._validate_header(header, key), False)
-
-
- header = required_header.copy()
- header["sec-websocket-accept"] = "something"
- self.assertEquals(sock._validate_header(header, key), False)
- del header["sec-websocket-accept"]
- self.assertEquals(sock._validate_header(header, key), False)
-
- def testReadHeader(self):
- sock = ws.WebSocket()
- sock.io_sock = sock.sock = HeaderSockMock("data/header01.txt")
- status, header = sock._read_headers()
- self.assertEquals(status, 101)
- self.assertEquals(header["connection"], "upgrade")
-
- sock.io_sock = sock.sock = HeaderSockMock("data/header02.txt")
- self.assertRaises(ws.WebSocketException, sock._read_headers)
-
- def testSend(self):
- # TODO: add longer frame data
- sock = ws.WebSocket()
- sock.set_mask_key(create_mask_key)
- s = sock.io_sock = sock.sock = HeaderSockMock("data/header01.txt")
- sock.send("Hello")
- self.assertEquals(s.sent[0], "\x81\x85abcd)\x07\x0f\x08\x0e")
-
- sock.send("こんにちは")
- self.assertEquals(s.sent[1], "\x81\x8fabcd\x82\xe3\xf0\x87\xe3\xf1\x80\xe5\xca\x81\xe2\xc5\x82\xe3\xcc")
-
- sock.send(u"こんにちは")
- self.assertEquals(s.sent[1], "\x81\x8fabcd\x82\xe3\xf0\x87\xe3\xf1\x80\xe5\xca\x81\xe2\xc5\x82\xe3\xcc")
-
- def testRecv(self):
- # TODO: add longer frame data
- sock = ws.WebSocket()
- s = sock.io_sock = sock.sock = StringSockMock()
- s.set_data("\x81\x8fabcd\x82\xe3\xf0\x87\xe3\xf1\x80\xe5\xca\x81\xe2\xc5\x82\xe3\xcc")
- data = sock.recv()
- self.assertEquals(data, "こんにちは")
-
- s.set_data("\x81\x85abcd)\x07\x0f\x08\x0e")
- data = sock.recv()
- self.assertEquals(data, "Hello")
-
- def testWebSocket(self):
- s = ws.create_connection("ws://echo.websocket.org/") #ws://localhost:8080/echo")
- self.assertNotEquals(s, None)
- s.send("Hello, World")
- result = s.recv()
- self.assertEquals(result, "Hello, World")
-
- s.send("こにゃにゃちは、世界")
- result = s.recv()
- self.assertEquals(result, "こにゃにゃちは、世界")
- s.close()
-
- def testPingPong(self):
- s = ws.create_connection("ws://echo.websocket.org/")
- self.assertNotEquals(s, None)
- s.ping("Hello")
- s.pong("Hi")
- s.close()
-
- def testSecureWebSocket(self):
- s = ws.create_connection("wss://echo.websocket.org/")
- self.assertNotEquals(s, None)
- self.assert_(isinstance(s.io_sock, ws._SSLSocketWrapper))
- s.send("Hello, World")
- result = s.recv()
- self.assertEquals(result, "Hello, World")
- s.send("こにゃにゃちは、世界")
- result = s.recv()
- self.assertEquals(result, "こにゃにゃちは、世界")
- s.close()
-
- def testWebSocketWihtCustomHeader(self):
- s = ws.create_connection("ws://echo.websocket.org/",
- headers={"User-Agent": "PythonWebsocketClient"})
- self.assertNotEquals(s, None)
- s.send("Hello, World")
- result = s.recv()
- self.assertEquals(result, "Hello, World")
- s.close()
-
- def testAfterClose(self):
- from socket import error
- s = ws.create_connection("ws://echo.websocket.org/")
- self.assertNotEquals(s, None)
- s.close()
- self.assertRaises(error, s.send, "Hello")
- self.assertRaises(error, s.recv)
-
- def testUUID4(self):
- """ WebSocket key should be a UUID4.
- """
- key = ws._create_sec_websocket_key()
- u = uuid.UUID(bytes=base64.b64decode(key))
- self.assertEquals(4, u.version)
-
-class WebSocketAppTest(unittest.TestCase):
-
- class NotSetYet(object):
- """ A marker class for signalling that a value hasn't been set yet.
- """
-
- def setUp(self):
- ws.enableTrace(TRACABLE)
-
- WebSocketAppTest.keep_running_open = WebSocketAppTest.NotSetYet()
- WebSocketAppTest.keep_running_close = WebSocketAppTest.NotSetYet()
- WebSocketAppTest.get_mask_key_id = WebSocketAppTest.NotSetYet()
-
- def tearDown(self):
-
- WebSocketAppTest.keep_running_open = WebSocketAppTest.NotSetYet()
- WebSocketAppTest.keep_running_close = WebSocketAppTest.NotSetYet()
- WebSocketAppTest.get_mask_key_id = WebSocketAppTest.NotSetYet()
-
- def testKeepRunning(self):
- """ A WebSocketApp should keep running as long as its self.keep_running
- is not False (in the boolean context).
- """
-
- def on_open(self, *args, **kwargs):
- """ Set the keep_running flag for later inspection and immediately
- close the connection.
- """
- WebSocketAppTest.keep_running_open = self.keep_running
- self.close()
-
- def on_close(self, *args, **kwargs):
- """ Set the keep_running flag for the test to use.
- """
- WebSocketAppTest.keep_running_close = self.keep_running
-
- app = ws.WebSocketApp('ws://echo.websocket.org/', on_open=on_open, on_close=on_close)
- app.run_forever()
-
- self.assertFalse(isinstance(WebSocketAppTest.keep_running_open,
- WebSocketAppTest.NotSetYet))
-
- self.assertFalse(isinstance(WebSocketAppTest.keep_running_close,
- WebSocketAppTest.NotSetYet))
-
- self.assertEquals(True, WebSocketAppTest.keep_running_open)
- self.assertEquals(False, WebSocketAppTest.keep_running_close)
-
- def testSockMaskKey(self):
- """ A WebSocketApp should forward the received mask_key function down
- to the actual socket.
- """
-
- def my_mask_key_func():
- pass
-
- def on_open(self, *args, **kwargs):
- """ Set the value so the test can use it later on and immediately
- close the connection.
- """
- WebSocketAppTest.get_mask_key_id = id(self.get_mask_key)
- self.close()
-
- app = ws.WebSocketApp('ws://echo.websocket.org/', on_open=on_open, get_mask_key=my_mask_key_func)
- app.run_forever()
-
- # Note: We can't use 'is' for comparing the functions directly, need to use 'id'.
- self.assertEquals(WebSocketAppTest.get_mask_key_id, id(my_mask_key_func))
-
-
-if __name__ == "__main__":
- unittest.main()
-
diff --git a/tools/devtools_auto/third_party/websocket-client/websocket.py b/tools/devtools_auto/third_party/websocket-client/websocket.py
deleted file mode 100644
index 480bfc0..0000000
--- a/tools/devtools_auto/third_party/websocket-client/websocket.py
+++ /dev/null
@@ -1,756 +0,0 @@
-"""
-websocket - WebSocket client library for Python
-
-Copyright (C) 2010 Hiroki Ohtani(liris)
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-"""
-
-
-import socket
-from urlparse import urlparse
-import os
-import struct
-import uuid
-import hashlib
-import base64
-import logging
-
-"""
-websocket python client.
-=========================
-
-This version support only hybi-13.
-Please see http://tools.ietf.org/html/rfc6455 for protocol.
-"""
-
-
-# websocket supported version.
-VERSION = 13
-
-# closing frame status codes.
-STATUS_NORMAL = 1000
-STATUS_GOING_AWAY = 1001
-STATUS_PROTOCOL_ERROR = 1002
-STATUS_UNSUPPORTED_DATA_TYPE = 1003
-STATUS_STATUS_NOT_AVAILABLE = 1005
-STATUS_ABNORMAL_CLOSED = 1006
-STATUS_INVALID_PAYLOAD = 1007
-STATUS_POLICY_VIOLATION = 1008
-STATUS_MESSAGE_TOO_BIG = 1009
-STATUS_INVALID_EXTENSION = 1010
-STATUS_UNEXPECTED_CONDITION = 1011
-STATUS_TLS_HANDSHAKE_ERROR = 1015
-
-logger = logging.getLogger()
-
-class WebSocketException(Exception):
- """
- websocket exeception class.
- """
- pass
-
-class WebSocketConnectionClosedException(WebSocketException):
- """
- If remote host closed the connection or some network error happened,
- this exception will be raised.
- """
- pass
-
-default_timeout = None
-traceEnabled = False
-
-def enableTrace(tracable):
- """
- turn on/off the tracability.
-
- tracable: boolean value. if set True, tracability is enabled.
- """
- global traceEnabled
- traceEnabled = tracable
- if tracable:
- if not logger.handlers:
- logger.addHandler(logging.StreamHandler())
- logger.setLevel(logging.DEBUG)
-
-def setdefaulttimeout(timeout):
- """
- Set the global timeout setting to connect.
-
- timeout: default socket timeout time. This value is second.
- """
- global default_timeout
- default_timeout = timeout
-
-def getdefaulttimeout():
- """
- Return the global timeout setting(second) to connect.
- """
- return default_timeout
-
-def _parse_url(url):
- """
- parse url and the result is tuple of
- (hostname, port, resource path and the flag of secure mode)
-
- url: url string.
- """
- if ":" not in url:
- raise ValueError("url is invalid")
-
- scheme, url = url.split(":", 1)
-
- parsed = urlparse(url, scheme="http")
- if parsed.hostname:
- hostname = parsed.hostname
- else:
- raise ValueError("hostname is invalid")
- port = 0
- if parsed.port:
- port = parsed.port
-
- is_secure = False
- if scheme == "ws":
- if not port:
- port = 80
- elif scheme == "wss":
- is_secure = True
- if not port:
- port = 443
- else:
- raise ValueError("scheme %s is invalid" % scheme)
-
- if parsed.path:
- resource = parsed.path
- else:
- resource = "/"
-
- if parsed.query:
- resource += "?" + parsed.query
-
- return (hostname, port, resource, is_secure)
-
-def create_connection(url, timeout=None, **options):
- """
- connect to url and return websocket object.
-
- Connect to url and return the WebSocket object.
- Passing optional timeout parameter will set the timeout on the socket.
- If no timeout is supplied, the global default timeout setting returned by getdefauttimeout() is used.
- You can customize using 'options'.
- If you set "header" dict object, you can set your own custom header.
-
- >>> conn = create_connection("ws://echo.websocket.org/",
- ... header={"User-Agent: MyProgram",
- ... "x-custom: header"})
-
-
- timeout: socket timeout time. This value is integer.
- if you set None for this value, it means "use default_timeout value"
-
- options: current support option is only "header".
- if you set header as dict value, the custom HTTP headers are added.
- """
- websock = WebSocket()
- websock.settimeout(timeout != None and timeout or default_timeout)
- websock.connect(url, **options)
- return websock
-
-_MAX_INTEGER = (1 << 32) -1
-_AVAILABLE_KEY_CHARS = range(0x21, 0x2f + 1) + range(0x3a, 0x7e + 1)
-_MAX_CHAR_BYTE = (1<<8) -1
-
-# ref. Websocket gets an update, and it breaks stuff.
-# http://axod.blogspot.com/2010/06/websocket-gets-update-and-it-breaks.html
-
-def _create_sec_websocket_key():
- uid = uuid.uuid4()
- return base64.encodestring(uid.bytes).strip()
-
-_HEADERS_TO_CHECK = {
- "upgrade": "websocket",
- "connection": "upgrade",
- }
-
-class _SSLSocketWrapper(object):
- def __init__(self, sock):
- self.ssl = socket.ssl(sock)
-
- def recv(self, bufsize):
- return self.ssl.read(bufsize)
-
- def send(self, payload):
- return self.ssl.write(payload)
-
-_BOOL_VALUES = (0, 1)
-def _is_bool(*values):
- for v in values:
- if v not in _BOOL_VALUES:
- return False
-
- return True
-
-class ABNF(object):
- """
- ABNF frame class.
- see http://tools.ietf.org/html/rfc5234
- and http://tools.ietf.org/html/rfc6455#section-5.2
- """
-
- # operation code values.
- OPCODE_TEXT = 0x1
- OPCODE_BINARY = 0x2
- OPCODE_CLOSE = 0x8
- OPCODE_PING = 0x9
- OPCODE_PONG = 0xa
-
- # available operation code value tuple
- OPCODES = (OPCODE_TEXT, OPCODE_BINARY, OPCODE_CLOSE,
- OPCODE_PING, OPCODE_PONG)
-
- # opcode human readable string
- OPCODE_MAP = {
- OPCODE_TEXT: "text",
- OPCODE_BINARY: "binary",
- OPCODE_CLOSE: "close",
- OPCODE_PING: "ping",
- OPCODE_PONG: "pong"
- }
-
- # data length threashold.
- LENGTH_7 = 0x7d
- LENGTH_16 = 1 << 16
- LENGTH_63 = 1 << 63
-
- def __init__(self, fin = 0, rsv1 = 0, rsv2 = 0, rsv3 = 0,
- opcode = OPCODE_TEXT, mask = 1, data = ""):
- """
- Constructor for ABNF.
- please check RFC for arguments.
- """
- self.fin = fin
- self.rsv1 = rsv1
- self.rsv2 = rsv2
- self.rsv3 = rsv3
- self.opcode = opcode
- self.mask = mask
- self.data = data
- self.get_mask_key = os.urandom
-
- @staticmethod
- def create_frame(data, opcode):
- """
- create frame to send text, binary and other data.
-
- data: data to send. This is string value(byte array).
- if opcode is OPCODE_TEXT and this value is uniocde,
- data value is conveted into unicode string, automatically.
-
- opcode: operation code. please see OPCODE_XXX.
- """
- if opcode == ABNF.OPCODE_TEXT and isinstance(data, unicode):
- data = data.encode("utf-8")
- # mask must be set if send data from client
- return ABNF(1, 0, 0, 0, opcode, 1, data)
-
- def format(self):
- """
- format this object to string(byte array) to send data to server.
- """
- if not _is_bool(self.fin, self.rsv1, self.rsv2, self.rsv3):
- raise ValueError("not 0 or 1")
- if self.opcode not in ABNF.OPCODES:
- raise ValueError("Invalid OPCODE")
- length = len(self.data)
- if length >= ABNF.LENGTH_63:
- raise ValueError("data is too long")
-
- frame_header = chr(self.fin << 7
- | self.rsv1 << 6 | self.rsv2 << 5 | self.rsv3 << 4
- | self.opcode)
- if length < ABNF.LENGTH_7:
- frame_header += chr(self.mask << 7 | length)
- elif length < ABNF.LENGTH_16:
- frame_header += chr(self.mask << 7 | 0x7e)
- frame_header += struct.pack("!H", length)
- else:
- frame_header += chr(self.mask << 7 | 0x7f)
- frame_header += struct.pack("!Q", length)
-
- if not self.mask:
- return frame_header + self.data
- else:
- mask_key = self.get_mask_key(4)
- return frame_header + self._get_masked(mask_key)
-
- def _get_masked(self, mask_key):
- s = ABNF.mask(mask_key, self.data)
- return mask_key + "".join(s)
-
- @staticmethod
- def mask(mask_key, data):
- """
- mask or unmask data. Just do xor for each byte
-
- mask_key: 4 byte string(byte).
-
- data: data to mask/unmask.
- """
- _m = map(ord, mask_key)
- _d = map(ord, data)
- for i in range(len(_d)):
- _d[i] ^= _m[i % 4]
- s = map(chr, _d)
- return "".join(s)
-
-class WebSocket(object):
- """
- Low level WebSocket interface.
- This class is based on
- The WebSocket protocol draft-hixie-thewebsocketprotocol-76
- http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
-
- We can connect to the websocket server and send/recieve data.
- The following example is a echo client.
-
- >>> import websocket
- >>> ws = websocket.WebSocket()
- >>> ws.connect("ws://echo.websocket.org")
- >>> ws.send("Hello, Server")
- >>> ws.recv()
- 'Hello, Server'
- >>> ws.close()
-
- get_mask_key: a callable to produce new mask keys, see the set_mask_key
- function's docstring for more details
- """
- def __init__(self, get_mask_key = None):
- """
- Initalize WebSocket object.
- """
- self.connected = False
- self.io_sock = self.sock = socket.socket()
- self.get_mask_key = get_mask_key
-
- def set_mask_key(self, func):
- """
- set function to create musk key. You can custumize mask key generator.
- Mainly, this is for testing purpose.
-
- func: callable object. the fuct must 1 argument as integer.
- The argument means length of mask key.
- This func must be return string(byte array),
- which length is argument specified.
- """
- self.get_mask_key = func
-
- def settimeout(self, timeout):
- """
- Set the timeout to the websocket.
-
- timeout: timeout time(second).
- """
- self.sock.settimeout(timeout)
-
- def gettimeout(self):
- """
- Get the websocket timeout(second).
- """
- return self.sock.gettimeout()
-
- def connect(self, url, **options):
- """
- Connect to url. url is websocket url scheme. ie. ws://host:port/resource
- You can customize using 'options'.
- If you set "header" dict object, you can set your own custom header.
-
- >>> ws = WebSocket()
- >>> ws.connect("ws://echo.websocket.org/",
- ... header={"User-Agent: MyProgram",
- ... "x-custom: header"})
-
- timeout: socket timeout time. This value is integer.
- if you set None for this value,
- it means "use default_timeout value"
-
- options: current support option is only "header".
- if you set header as dict value,
- the custom HTTP headers are added.
-
- """
- hostname, port, resource, is_secure = _parse_url(url)
- # TODO: we need to support proxy
- self.sock.connect((hostname, port))
- if is_secure:
- self.io_sock = _SSLSocketWrapper(self.sock)
- self._handshake(hostname, port, resource, **options)
-
- def _handshake(self, host, port, resource, **options):
- sock = self.io_sock
- headers = []
- headers.append("GET %s HTTP/1.1" % resource)
- headers.append("Upgrade: websocket")
- headers.append("Connection: Upgrade")
- if port == 80:
- hostport = host
- else:
- hostport = "%s:%d" % (host, port)
- headers.append("Host: %s" % hostport)
- headers.append("Origin: %s" % hostport)
-
- key = _create_sec_websocket_key()
- headers.append("Sec-WebSocket-Key: %s" % key)
- headers.append("Sec-WebSocket-Version: %s" % VERSION)
- if "header" in options:
- headers.extend(options["header"])
-
- headers.append("")
- headers.append("")
-
- header_str = "\r\n".join(headers)
- sock.send(header_str)
- if traceEnabled:
- logger.debug( "--- request header ---")
- logger.debug( header_str)
- logger.debug("-----------------------")
-
- status, resp_headers = self._read_headers()
- if status != 101:
- self.close()
- raise WebSocketException("Handshake Status %d" % status)
-
- success = self._validate_header(resp_headers, key)
- if not success:
- self.close()
- raise WebSocketException("Invalid WebSocket Header")
-
- self.connected = True
-
- def _validate_header(self, headers, key):
- for k, v in _HEADERS_TO_CHECK.iteritems():
- r = headers.get(k, None)
- if not r:
- return False
- r = r.lower()
- if v != r:
- return False
-
- result = headers.get("sec-websocket-accept", None)
- if not result:
- return False
- result = result.lower()
-
- value = key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
- hashed = base64.encodestring(hashlib.sha1(value).digest()).strip().lower()
- return hashed == result
-
- def _read_headers(self):
- status = None
- headers = {}
- if traceEnabled:
- logger.debug("--- response header ---")
-
- while True:
- line = self._recv_line()
- if line == "\r\n":
- break
- line = line.strip()
- if traceEnabled:
- logger.debug(line)
- if not status:
- status_info = line.split(" ", 2)
- status = int(status_info[1])
- else:
- kv = line.split(":", 1)
- if len(kv) == 2:
- key, value = kv
- headers[key.lower()] = value.strip().lower()
- else:
- raise WebSocketException("Invalid header")
-
- if traceEnabled:
- logger.debug("-----------------------")
-
- return status, headers
-
- def send(self, payload, opcode = ABNF.OPCODE_TEXT):
- """
- Send the data as string.
-
- payload: Payload must be utf-8 string or unicoce,
- if the opcode is OPCODE_TEXT.
- Otherwise, it must be string(byte array)
-
- opcode: operation code to send. Please see OPCODE_XXX.
- """
- frame = ABNF.create_frame(payload, opcode)
- if self.get_mask_key:
- frame.get_mask_key = self.get_mask_key
- data = frame.format()
- self.io_sock.send(data)
- if traceEnabled:
- logger.debug("send: " + repr(data))
-
- def ping(self, payload = ""):
- """
- send ping data.
-
- payload: data payload to send server.
- """
- self.send(payload, ABNF.OPCODE_PING)
-
- def pong(self, payload):
- """
- send pong data.
-
- payload: data payload to send server.
- """
- self.send(payload, ABNF.OPCODE_PONG)
-
- def recv(self):
- """
- Receive string data(byte array) from the server.
-
- return value: string(byte array) value.
- """
- opcode, data = self.recv_data()
- return data
-
- def recv_data(self):
- """
- Recieve data with operation code.
-
- return value: tuple of operation code and string(byte array) value.
- """
- while True:
- frame = self.recv_frame()
- if not frame:
- # handle error:
- # 'NoneType' object has no attribute 'opcode'
- raise WebSocketException("Not a valid frame %s" % frame)
- elif frame.opcode in (ABNF.OPCODE_TEXT, ABNF.OPCODE_BINARY):
- return (frame.opcode, frame.data)
- elif frame.opcode == ABNF.OPCODE_CLOSE:
- self.send_close()
- return (frame.opcode, None)
- elif frame.opcode == ABNF.OPCODE_PING:
- self.pong("Hi!")
-
-
- def recv_frame(self):
- """
- recieve data as frame from server.
-
- return value: ABNF frame object.
- """
- header_bytes = self._recv(2)
- if not header_bytes:
- return None
- b1 = ord(header_bytes[0])
- fin = b1 >> 7 & 1
- rsv1 = b1 >> 6 & 1
- rsv2 = b1 >> 5 & 1
- rsv3 = b1 >> 4 & 1
- opcode = b1 & 0xf
- b2 = ord(header_bytes[1])
- mask = b2 >> 7 & 1
- length = b2 & 0x7f
-
- length_data = ""
- if length == 0x7e:
- length_data = self._recv(2)
- length = struct.unpack("!H", length_data)[0]
- elif length == 0x7f:
- length_data = self._recv(8)
- length = struct.unpack("!Q", length_data)[0]
-
- mask_key = ""
- if mask:
- mask_key = self._recv(4)
- data = self._recv_strict(length)
- if traceEnabled:
- recieved = header_bytes + length_data + mask_key + data
- logger.debug("recv: " + repr(recieved))
-
- if mask:
- data = ABNF.mask(mask_key, data)
-
- frame = ABNF(fin, rsv1, rsv2, rsv3, opcode, mask, data)
- return frame
-
- def send_close(self, status = STATUS_NORMAL, reason = ""):
- """
- send close data to the server.
-
- status: status code to send. see STATUS_XXX.
-
- reason: the reason to close. This must be string.
- """
- if status < 0 or status >= ABNF.LENGTH_16:
- raise ValueError("code is invalid range")
- self.send(struct.pack('!H', status) + reason, ABNF.OPCODE_CLOSE)
-
-
-
- def close(self, status = STATUS_NORMAL, reason = ""):
- """
- Close Websocket object
-
- status: status code to send. see STATUS_XXX.
-
- reason: the reason to close. This must be string.
- """
- if self.connected:
- if status < 0 or status >= ABNF.LENGTH_16:
- raise ValueError("code is invalid range")
-
- try:
- self.send(struct.pack('!H', status) + reason, ABNF.OPCODE_CLOSE)
- timeout = self.sock.gettimeout()
- self.sock.settimeout(3)
- try:
- frame = self.recv_frame()
- if logger.isEnabledFor(logging.DEBUG):
- logger.error("close status: " + repr(frame.data))
- except:
- pass
- self.sock.settimeout(timeout)
- self.sock.shutdown(socket.SHUT_RDWR)
- except:
- pass
- self._closeInternal()
-
- def _closeInternal(self):
- self.connected = False
- self.sock.close()
- self.io_sock = self.sock
-
- def _recv(self, bufsize):
- bytes = self.io_sock.recv(bufsize)
- if bytes == 0:
- raise WebSocketConnectionClosedException()
- return bytes
-
- def _recv_strict(self, bufsize):
- remaining = bufsize
- bytes = ""
- while remaining:
- bytes += self._recv(remaining)
- remaining = bufsize - len(bytes)
-
- return bytes
-
- def _recv_line(self):
- line = []
- while True:
- c = self._recv(1)
- line.append(c)
- if c == "\n":
- break
- return "".join(line)
-
-class WebSocketApp(object):
- """
- Higher level of APIs are provided.
- The interface is like JavaScript WebSocket object.
- """
- def __init__(self, url,
- on_open = None, on_message = None, on_error = None,
- on_close = None, keep_running = True, get_mask_key = None):
- """
- url: websocket url.
- on_open: callable object which is called at opening websocket.
- this function has one argument. The arugment is this class object.
- on_message: callbale object which is called when recieved data.
- on_message has 2 arguments.
- The 1st arugment is this class object.
- The passing 2nd arugment is utf-8 string which we get from the server.
- on_error: callable object which is called when we get error.
- on_error has 2 arguments.
- The 1st arugment is this class object.
- The passing 2nd arugment is exception object.
- on_close: callable object which is called when closed the connection.
- this function has one argument. The arugment is this class object.
- keep_running: a boolean flag indicating whether the app's main loop should
- keep running, defaults to True
- get_mask_key: a callable to produce new mask keys, see the WebSocket.set_mask_key's
- docstring for more information
- """
- self.url = url
- self.on_open = on_open
- self.on_message = on_message
- self.on_error = on_error
- self.on_close = on_close
- self.keep_running = keep_running
- self.get_mask_key = get_mask_key
- self.sock = None
-
- def send(self, data):
- """
- send message. data must be utf-8 string or unicode.
- """
- if self.sock.send(data) == 0:
- raise WebSocketConnectionClosedException()
-
- def close(self):
- """
- close websocket connection.
- """
- self.keep_running = False
- self.sock.close()
-
- def run_forever(self):
- """
- run event loop for WebSocket framework.
- This loop is infinite loop and is alive during websocket is available.
- """
- if self.sock:
- raise WebSocketException("socket is already opened")
- try:
- self.sock = WebSocket(self.get_mask_key)
- self.sock.connect(self.url)
- self._run_with_no_err(self.on_open)
- while self.keep_running:
- data = self.sock.recv()
- if data is None:
- break
- self._run_with_no_err(self.on_message, data)
- except Exception, e:
- self._run_with_no_err(self.on_error, e)
- finally:
- self.sock.close()
- self._run_with_no_err(self.on_close)
- self.sock = None
-
- def _run_with_no_err(self, callback, *args):
- if callback:
- try:
- callback(self, *args)
- except Exception, e:
- if logger.isEnabledFor(logging.DEBUG):
- logger.error(e)
-
-
-if __name__ == "__main__":
- enableTrace(True)
- ws = create_connection("ws://echo.websocket.org/")
- print "Sending 'Hello, World'..."
- ws.send("Hello, World")
- print "Sent"
- print "Receiving..."
- result = ws.recv()
- print "Received '%s'" % result
- ws.close()