Full Code of nicokaiser/php-websocket for AI

master 7f10c31144d3 cached
141 files
303.3 KB
78.8k tokens
428 symbols
1 requests
Download .txt
Showing preview only (338K chars total). Download the full file or copy to clipboard to get everything.
Repository: nicokaiser/php-websocket
Branch: master
Commit: 7f10c31144d3
Files: 141
Total size: 303.3 KB

Directory structure:
gitextract_kle3fe4a/

├── .gitignore
├── .travis
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── TODO.md
├── VERSION
├── composer.json
├── doc/
│   ├── Makefile
│   ├── requirements.txt
│   └── source/
│       ├── api/
│       │   ├── Application/
│       │   │   ├── Application.rst
│       │   │   ├── EchoApplication.rst
│       │   │   └── index.rst
│       │   ├── BasicServer.rst
│       │   ├── Client.rst
│       │   ├── Connection.rst
│       │   ├── ConnectionManager.rst
│       │   ├── Exception/
│       │   │   ├── BadRequestException.rst
│       │   │   ├── CloseException.rst
│       │   │   ├── ConnectionException.rst
│       │   │   ├── Exception.rst
│       │   │   ├── FrameException.rst
│       │   │   ├── HandshakeException.rst
│       │   │   ├── InvalidOriginException.rst
│       │   │   ├── PayloadException.rst
│       │   │   ├── RateLimiterException.rst
│       │   │   ├── SocketException.rst
│       │   │   └── index.rst
│       │   ├── Frame/
│       │   │   ├── Frame.rst
│       │   │   ├── HybiFrame.rst
│       │   │   └── index.rst
│       │   ├── Listener/
│       │   │   ├── HandshakeRequestListener.rst
│       │   │   ├── Listener.rst
│       │   │   ├── OriginPolicy.rst
│       │   │   ├── RateLimiter.rst
│       │   │   └── index.rst
│       │   ├── Payload/
│       │   │   ├── HybiPayload.rst
│       │   │   ├── Payload.rst
│       │   │   └── index.rst
│       │   ├── Protocol/
│       │   │   ├── Hybi10Protocol.rst
│       │   │   ├── HybiProtocol.rst
│       │   │   ├── Protocol.rst
│       │   │   ├── Rfc6455Protocol.rst
│       │   │   └── index.rst
│       │   ├── Resource.rst
│       │   ├── Server.rst
│       │   ├── Socket/
│       │   │   ├── ClientSocket.rst
│       │   │   ├── ServerClientSocket.rst
│       │   │   ├── ServerSocket.rst
│       │   │   ├── Socket.rst
│       │   │   ├── UriSocket.rst
│       │   │   └── index.rst
│       │   ├── Util/
│       │   │   ├── Configurable.rst
│       │   │   ├── Ssl.rst
│       │   │   └── index.rst
│       │   └── index.rst
│       ├── authors.rst
│       ├── conf.py
│       ├── getting-started.rst
│       ├── index.rst
│       ├── installing.rst
│       ├── introduction.rst
│       ├── performance.rst
│       └── setup.py
├── examples/
│   ├── StatusApplication.php
│   ├── coffeescript/
│   │   ├── coffee/
│   │   │   ├── client.coffee
│   │   │   └── status.coffee
│   │   ├── css/
│   │   │   ├── client.css
│   │   │   └── status.css
│   │   ├── index.html
│   │   └── status.html
│   ├── server.pem
│   ├── server.php
│   └── server_ssl.php
├── lib/
│   ├── SplClassLoader.php
│   └── Wrench/
│       ├── Application/
│       │   ├── Application.php
│       │   ├── EchoApplication.php
│       │   └── ServerTimeApplication.php
│       ├── BasicServer.php
│       ├── Client.php
│       ├── Connection.php
│       ├── ConnectionManager.php
│       ├── Exception/
│       │   ├── BadRequestException.php
│       │   ├── CloseException.php
│       │   ├── ConnectionException.php
│       │   ├── Exception.php
│       │   ├── FrameException.php
│       │   ├── HandshakeException.php
│       │   ├── InvalidOriginException.php
│       │   ├── PayloadException.php
│       │   ├── RateLimiterException.php
│       │   └── SocketException.php
│       ├── Frame/
│       │   ├── Frame.php
│       │   └── HybiFrame.php
│       ├── Listener/
│       │   ├── HandshakeRequestListener.php
│       │   ├── Listener.php
│       │   ├── OriginPolicy.php
│       │   └── RateLimiter.php
│       ├── Payload/
│       │   ├── HybiPayload.php
│       │   ├── Payload.php
│       │   └── PayloadHandler.php
│       ├── Protocol/
│       │   ├── Hybi10Protocol.php
│       │   ├── HybiProtocol.php
│       │   ├── Protocol.php
│       │   └── Rfc6455Protocol.php
│       ├── Resource.php
│       ├── Server.php
│       ├── Socket/
│       │   ├── ClientSocket.php
│       │   ├── ServerClientSocket.php
│       │   ├── ServerSocket.php
│       │   ├── Socket.php
│       │   └── UriSocket.php
│       ├── Tests/
│       │   ├── Application/
│       │   │   └── EchoApplicationTest.php
│       │   ├── BasicServerTest.php
│       │   ├── ClientTest.php
│       │   ├── ConnectionManagerTest.php
│       │   ├── ConnectionTest.php
│       │   ├── Frame/
│       │   │   ├── BaseSubclassFrameTest.php
│       │   │   ├── FrameTest.php
│       │   │   └── HybiFrameTest.php
│       │   ├── Listener/
│       │   │   ├── ListenerTest.php
│       │   │   ├── OriginPolicyTest.php
│       │   │   └── RateLimiterTest.php
│       │   ├── Payload/
│       │   │   ├── HybiPayloadTest.php
│       │   │   └── PayloadTest.php
│       │   ├── Protocol/
│       │   │   ├── ProtocolTest.php
│       │   │   └── Rfc6455ProtocolTest.php
│       │   ├── ServerTest.php
│       │   ├── ServerTestHelper.php
│       │   ├── Socket/
│       │   │   ├── ClientSocketTest.php
│       │   │   ├── ServerClientSocketTest.php
│       │   │   ├── ServerSocketTest.php
│       │   │   ├── SocketTest.php
│       │   │   └── UriSocketTest.php
│       │   ├── Test.php
│       │   ├── bootstrap.php
│       │   └── server.php
│       └── Util/
│           ├── Configurable.php
│           └── Ssl.php
└── phpunit.xml

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
*.sw[m-p]
phpunit
build
doc/build


================================================
FILE: .travis
================================================
#!/bin/bash

phpunit
return=$?

echo ""
echo "Server error log"
cat build/server.err.log

echo ""
echo "Server log"
cat build/server.log

exit $return


================================================
FILE: .travis.yml
================================================
language: php

script: ./.travis

php:
  - 5.3
  - 5.4

branches:
  only:
    - master
    - devel
    - 2.0

notifications:
  email:
    - dominic@varspool.com


================================================
FILE: CHANGELOG.md
================================================
<!-- vim: set tw=79 sw=4 ts=4 et ft=markdown : -->
# Changelog

## 2.0.0

* Name change: php-websocket was renamed to Wrench, along with a top-level
  namespace change.
* Moved to a more traditional project layout.
* Added composer.json: wrench/wrench is the new package name.
* Added PHPUnit tests, and Travis CI integration
* Everything is now much nicer to override and customize.
* Extensive changes to the protected API, not much change to the public API
  * Deprecated: `$server->removeClientOnClose($client)`,
    `$server->removeClientOnError($client)` (both cases should be managed by
    overriding the server, or hooking into `$client->onDisconnect()`)
  * Deprecated: `StatusApplication` and `DemoApplication`, both moved to
    examples directory.
* Split out new classes (and in some cases hierarchies) for protocol, payload
  frame, connection and event handling.
* Added dependency injection patterns everywhere to split logic out into
  loosely coupled, replacable aggregate classes.
* Added the Configurable interface, providing a way to configure most of the
  primary classes in detail (if you don't feel like extending them).
* Refactored the client class to be in the same namespace as the server
  libraries.
* @vincentdieltiens worked on SSL configuration, and added a method to generate
  a certificate file.

## 1.0.0

* Refactored methods to open up more of the protected API.
* @lemmingzshadow switched the server to use streams instead of sockets, and
  implemented SSL support.
* @mazhack added support for the new WebSocket object in Firefox 11.
* Plenty of bugfixes


================================================
FILE: LICENSE
================================================
            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
                    Version 2, December 2004

 Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>

 Everyone is permitted to copy and distribute verbatim or modified
 copies of this license document, and changing it is allowed as long
 as the name is changed.

            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. You just DO WHAT THE FUCK YOU WANT TO.


================================================
FILE: README.md
================================================
<!-- vim: set tw=79 sw=4 ts=4 et ft=markdown : -->
# Wrench
## Simple WebSocket Client/Server for PHP
### Formerly known as php-websocket

* Version: **2.0.0**
* Build Status: [![Build Status](https://secure.travis-ci.org/varspool/Wrench.png?branch=master)](http://travis-ci.org/varspool/Wrench)
* Documentation: [wrench.readthedocs.org](http://wrench.readthedocs.org/en/latest/index.html)

A simple websocket server and client package for PHP 5.3/5.4, using
streams. Protocol support is based around [RFC 6455](http://tools.ietf.org/html/rfc6455),
targeting the latest stable versions of Chrome and Firefox. 
(Suggest other clients [here](https://github.com/varspool/Wrench/wiki))

### Backward compatibility

#### Public API

The new vendor namespace is Wrench. This namespace begins in the `/lib`
directory, rather than `server/lib`.

Apart from the new namespace, the public API of this new major version is
fairly compatible with that of php-websocket 1.0.0.

#### Protected API

The protected API has changed, a lot. Many method have been broken up into
simple protected methods. This makes the Server class much easier to extend. In
fact, almost all of the classes involved in your typical daemon can now be
replaced or extended, including the socket handling and protocol handling.

#### What happened to the `client` dir?

The client-side libraries are no longer supported: some libraries are included
but are packaged only as examples. You're free to use whatever client-side
libraries you'd like with the server. If you're still using them, see the 1.0
branch.

## Installation

The library is PSR-0 compatible, with a vendor name of **Wrench**. An
SplClassLoader is bundled for convenience.

## Usage

This creates a server on 127.0.0.1:8000 with one Application that listens for
WebSocket requests to `ws://localhost:8000/echo` and `ws://localhost:8000/chat`:

```php
$server = new \Wrench\BasicServer('ws://localhost:8000', array(
    'allowed_origins' => array(
        'mysite.com',
        'mysite.dev.localdomain'
    )
));
$server->registerApplication('echo', new \Wrench\Examples\EchoApplication());
$server->registerApplication('chat', new \My\ChatApplication());
$server->run();
```
## Authors

The original maintainer and author was
[@nicokaiser](https://github.com/nicokaiser). Plentiful improvements were
contributed by [@lemmingzshadow](https://github.com/lemmingzshadow) and
[@mazhack](https://github.com/mazhack). Parts of the Socket class were written
by Moritz Wutz. The server is licensed under the WTFPL, a free software compatible
license.

## Bugs/Todos/Hints

- Add tests around fragmented payloads (split into many frames).
- To report issues, see the [issue tracker](https://github.com/varspool/Wrench/issues).

## Examples

- See server.php in the examples directory and
  Wrench\Application\EchoApplication
- [Jitt.li](http://jitt.li), a Twitter API sample project.
- For Symfony2, [VarspoolWebsocketBundle](https://github.com/varspool/WebsocketBundle)
  extends this library for use with the Service Container.


================================================
FILE: TODO.md
================================================
# TODO

 - Unify the socket handling of `WebSocket\Client` with that of `Websocket\Socket`
 - Moar tests!

================================================
FILE: VERSION
================================================
2.0.0


================================================
FILE: composer.json
================================================
{
    "name": "wrench/wrench",
    "type": "library",
    "description": "PHP WebSocket client/server library",
    "keywords": ["websocket", "websockets", "hybi"],
    "homepage": "http://github.com/varspool/Wrench",
    "license": "WTFPL",
    "authors": [
        {
            "name":     "Dominic Scheirlinck",
            "email":    "dominic@varspool.com",
            "homepage": "http://www.somethingemporium.com/"
        },
        {
            "name":     "Simon Samtleben",
            "email":    "web@lemmingzshadow.net",
            "homepage": "http://lemmingzshadow.net/"
        },
        {
            "name":     "Nico Kaiser",
            "email":    "nico@kaiser.me",
            "homepage": "http://siriux.net/"
        }
    ],
    "require": {
        "php": ">=5.3"
    },
    "autoload": {
        "psr-0": {
            "Wrench": "lib/"
        }
    }
}


================================================
FILE: doc/Makefile
================================================
# Makefile for Sphinx documentation
#

# You can set these variables from the command line.
SPHINXOPTS    =
SPHINXBUILD   = sphinx-build
PAPER         =
BUILDDIR      = build
SPHPDOX       = /usr/bin/env php ~/workspace/external/sphpdox/sphpdox.php

# Internal variables.
PAPEROPT_a4     = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source

.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext

help:
	@echo "Please use \`make <target>' where <target> is one of"
	@echo "  html       to make standalone HTML files"
	@echo "  dirhtml    to make HTML files named index.html in directories"
	@echo "  singlehtml to make a single large HTML file"
	@echo "  pickle     to make pickle files"
	@echo "  json       to make JSON files"
	@echo "  htmlhelp   to make HTML files and a HTML help project"
	@echo "  qthelp     to make HTML files and a qthelp project"
	@echo "  devhelp    to make HTML files and a Devhelp project"
	@echo "  epub       to make an epub"
	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
	@echo "  text       to make text files"
	@echo "  man        to make manual pages"
	@echo "  texinfo    to make Texinfo files"
	@echo "  info       to make Texinfo files and run them through makeinfo"
	@echo "  gettext    to make PO message catalogs"
	@echo "  changes    to make an overview of all changed/added/deprecated items"
	@echo "  linkcheck  to check all external links for integrity"
	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"

clean:
	-rm -rf $(BUILDDIR)/*

api: buildapi clean copyapi html singlehtml

buildapi:
	cd ~/workspace/external/sphpdox && ${SPHPDOX} process -t "API Documentation" -x "Wrench\Tests" Wrench ../../wrench/lib

copyapi:
	rm -rf ~/workspace/wrench/doc/source/api
	cp -r ~/workspace/external/sphpdox/build/Wrench ~/workspace/wrench/doc/source/api

html:
	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
	@echo
	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."

dirhtml:
	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
	@echo
	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."

singlehtml:
	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
	@echo
	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."

pickle:
	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
	@echo
	@echo "Build finished; now you can process the pickle files."

json:
	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
	@echo
	@echo "Build finished; now you can process the JSON files."

htmlhelp:
	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
	@echo
	@echo "Build finished; now you can run HTML Help Workshop with the" \
	      ".hhp project file in $(BUILDDIR)/htmlhelp."

qthelp:
	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
	@echo
	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Wrench.qhcp"
	@echo "To view the help file:"
	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Wrench.qhc"

devhelp:
	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
	@echo
	@echo "Build finished."
	@echo "To view the help file:"
	@echo "# mkdir -p $$HOME/.local/share/devhelp/Wrench"
	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Wrench"
	@echo "# devhelp"

epub:
	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
	@echo
	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."

latex:
	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
	@echo
	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
	@echo "Run \`make' in that directory to run these through (pdf)latex" \
	      "(use \`make latexpdf' here to do that automatically)."

latexpdf:
	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
	@echo "Running LaTeX files through pdflatex..."
	$(MAKE) -C $(BUILDDIR)/latex all-pdf
	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."

text:
	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
	@echo
	@echo "Build finished. The text files are in $(BUILDDIR)/text."

man:
	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
	@echo
	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."

texinfo:
	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
	@echo
	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
	@echo "Run \`make' in that directory to run these through makeinfo" \
	      "(use \`make info' here to do that automatically)."

info:
	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
	@echo "Running Texinfo files through makeinfo..."
	make -C $(BUILDDIR)/texinfo info
	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."

gettext:
	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
	@echo
	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."

changes:
	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
	@echo
	@echo "The overview file is in $(BUILDDIR)/changes."

linkcheck:
	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
	@echo
	@echo "Link check complete; look for any errors in the above output " \
	      "or in $(BUILDDIR)/linkcheck/output.txt."

doctest:
	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
	@echo "Testing of doctests in the sources finished, look at the " \
	      "results in $(BUILDDIR)/doctest/output.txt."


================================================
FILE: doc/requirements.txt
================================================
sphinxcontrib-phpdomain


================================================
FILE: doc/source/api/Application/Application.rst
================================================
--------------------------------
Wrench\\Application\\Application
--------------------------------

.. php:namespace: Wrench\\Application

.. php:class:: Application

    Wrench Server Application

    .. php:method:: onData($payload, $connection)

        Handle data received from a client

        :type $payload: Payload
        :param $payload: A payload object, that supports __toString()
        :type $connection: Connection
        :param $connection:


================================================
FILE: doc/source/api/Application/EchoApplication.rst
================================================
------------------------------------
Wrench\\Application\\EchoApplication
------------------------------------

.. php:namespace: Wrench\\Application

.. php:class:: EchoApplication

    Example application for Wrench: echo server

    .. php:method:: onData($data, $client)

        :param $data:
        :param $client:


================================================
FILE: doc/source/api/Application/index.rst
================================================
:::::::::::::::::::
Wrench\\Application
:::::::::::::::::::

.. php:namespace: Wrench\\Application

.. toctree::

   Application
   EchoApplication


================================================
FILE: doc/source/api/BasicServer.rst
================================================
-------------------
Wrench\\BasicServer
-------------------

.. php:namespace: Wrench

.. php:class:: BasicServer

    .. php:const:: EVENT_SOCKET_CONNECT

        Events

    .. php:attr:: rateLimiter

        protected

    .. php:attr:: originPolicy

        protected

    .. php:attr:: uri

        protected string

        The URI of the server

    .. php:attr:: options

        protected array

        Options

    .. php:attr:: logger

        protected Closure

        A logging callback

        The default callback simply prints to stdout. You can pass your own logger
        in the options array. It should take a string message and string priority
        as parameters.

    .. php:attr:: listeners

        protected array<string

        Event listeners

        Add listeners using the addListener() method.

    .. php:attr:: connectionManager

        protected ConnectionManager

        Connection manager

    .. php:attr:: applications

        protected array<string

        Applications

    .. php:attr:: protocol

        protected Protocol

    .. php:method:: __construct($uri, $options = array())

        Constructor

        :type $uri: string
        :param $uri:
        :type $options: array
        :param $options:

    .. php:method:: configure($options)

        :param $options:

    .. php:method:: configureRateLimiter()

    .. php:method:: configureOriginPolicy()

        Configures the origin policy

    .. php:method:: addAllowedOrigin($origin)

        Adds an allowed origin

        :type $origin: array
        :param $origin:

    .. php:method:: configureLogger()

        Configures the logger

        :returns: void

    .. php:method:: configureConnectionManager()

        Configures the connection manager

        :returns: void

    .. php:method:: getConnectionManager()

        Gets the connection manager

        :returns: \Wrench\ConnectionManager

    .. php:method:: getUri()

        :returns: string

    .. php:method:: setLogger($logger)

        Sets a logger

        :type $logger: Closure
        :param $logger:
        :returns: void

    .. php:method:: run()

        Main server loop

        :returns: void This method does not return!

    .. php:method:: log($message, $priority = 'info')

        Logs a message to the server log

        The default logger simply prints the message to stdout. You can provide a
        logging closure. This is useful, for instance, if you've daemonized and
        closed STDOUT.

        :type $message: string
        :param $message: Message to display.
        :param $priority:
        :returns: void

    .. php:method:: notify($event, $arguments = array())

        Notifies listeners of an event

        :type $event: string
        :param $event:
        :type $arguments: array
        :param $arguments: Event arguments
        :returns: void

    .. php:method:: addListener($event, $callback)

        Adds a listener

        Provide an event (see the Server::EVENT_* constants) and a callback
        closure. Some arguments may be provided to your callback, such as the
        connection the caused the event.

        :type $event: string
        :param $event:
        :type $callback: Closure
        :param $callback:
        :returns: void

    .. php:method:: getApplication($key)

        Returns a server application.

        :type $key: string
        :param $key: Name of application.
        :returns: Application The application object.

    .. php:method:: registerApplication($key, $application)

        Adds a new application object to the application storage.

        :type $key: string
        :param $key: Name of application.
        :type $application: object
        :param $application: The application object
        :returns: void

    .. php:method:: configureProtocol()

        Configures the protocol option


================================================
FILE: doc/source/api/Client.rst
================================================
--------------
Wrench\\Client
--------------

.. php:namespace: Wrench

.. php:class:: Client

    Client class

    Represents a Wrench client

    .. php:const:: MAX_HANDSHAKE_RESPONSE

    .. php:attr:: uri

        protected

    .. php:attr:: origin

        protected

    .. php:attr:: socket

        protected

    .. php:attr:: headers

        protected array

        Request headers

    .. php:attr:: protocol

        protected Protocol

        Protocol instance

    .. php:attr:: options

        protected array

        Options

    .. php:attr:: connected

        protected boolean

        Whether the client is connected

    .. php:method:: __construct($uri, $origin, $options = array())

        Constructor

        :type $uri: string
        :param $uri:
        :type $origin: string
        :param $origin: The origin to include in the handshake (required in later versions of the protocol)
        :param $options:

    .. php:method:: configure($options)

        Configure options

        :type $options: array
        :param $options:
        :returns: void

    .. php:method:: __destruct()

        Destructor

    .. php:method:: addRequestHeader($name, $value)

        Adds a request header to be included in the initial handshake

        For example, to include a Cookie header

        :type $name: string
        :param $name:
        :type $value: string
        :param $value:
        :returns: void

    .. php:method:: sendData($data, $type = 'text', $masked = true)

        Sends data to the socket

        :type $data: string
        :param $data:
        :type $type: string
        :param $type: Payload type
        :type $masked: boolean
        :param $masked:
        :returns: int bytes written

    .. php:method:: connect()

        Connect to the Wrench server

        :returns: boolean Whether a new connection was made

    .. php:method:: isConnected()

        Whether the client is currently connected

        :returns: boolean

    .. php:method:: disconnect()


================================================
FILE: doc/source/api/Connection.rst
================================================
------------------
Wrench\\Connection
------------------

.. php:namespace: Wrench

.. php:class:: Connection

    Represents a client connection on the server side

    i.e. the `Server` manages a bunch of `Connection`s

    .. php:attr:: manager

        protected Wrench\ConnectionManager

        The connection manager

    .. php:attr:: socket

        protected Socket

        Socket object

        Wraps the client connection resource

    .. php:attr:: handshaked

        protected boolean

        Whether the connection has successfully handshaken

    .. php:attr:: application

        protected Application

        The application this connection belongs to

    .. php:attr:: ip

        protected string

        The IP address of the client

    .. php:attr:: port

        protected int

        The port of the client

    .. php:attr:: id

        protected string|null

        Connection ID

    .. php:attr:: payload

        protected

        The current payload

    .. php:attr:: options

        protected array

    .. php:attr:: protocol

        protected Protocol

    .. php:method:: __construct(ConnectionManager $manager, ServerClientSocket $socket, $options = array())

        Constructor

        :type $manager: ConnectionManager
        :param $manager:
        :type $socket: ServerClientSocket
        :param $socket:
        :type $options: array
        :param $options:

    .. php:method:: getConnectionManager()

        Gets the connection manager of this connection

        :returns: \Wrench\ConnectionManager

    .. php:method:: configure($options)

        :param $options:

    .. php:method:: configureClientInformation()

    .. php:method:: configureClientId()

        Configures the client ID

        We hash the client ID to prevent leakage of information if another client
        happens to get a hold of an ID. The secret *must* be lengthy, and must be
        kept secret for this to work: otherwise it's trivial to search the space
        of possible IP addresses/ports (well, if not trivial, at least very fast).

    .. php:method:: onData($data)

        Data receiver

        Called by the connection manager when the connection has received data

        :type $data: string
        :param $data:

    .. php:method:: handshake($data)

        Performs a websocket handshake

        :type $data: string
        :param $data:

    .. php:method:: export($data)

        Returns a string export of the given binary data

        :type $data: string
        :param $data:
        :returns: string

    .. php:method:: handle($data)

        Handle data received from the client

        The data passed in may belong to several different frames across one or
        more protocols. It may not even contain a single complete frame. This
        method manages slotting the data into separate payload objects.

        :type $data: string
        :param $data:

    .. php:method:: handlePayload(Payload $payload)

        Handle a complete payload received from the client

        :type $payload: Payload
        :param $payload:

    .. php:method:: send($data, $type = Protocol::TYPE_TEXT)

        Sends the payload to the connection

        :param $data:
        :type $type: string
        :param $type:
        :returns: boolean

    .. php:method:: process()

        Processes data on the socket

    .. php:method:: close($code = Protocol::CLOSE_NORMAL)

        Closes the connection according to the WebSocket protocol

        :param $code:
        :returns: boolean

    .. php:method:: log($message, $priority = 'info')

        Logs a message

        :type $message: string
        :param $message:
        :type $priority: string
        :param $priority:

    .. php:method:: getIp()

        Gets the IP address of the connection

        :returns: string Usually dotted quad notation

    .. php:method:: getPort()

        Gets the port of the connection

        :returns: int

    .. php:method:: getId()

        Gets the connection ID

        :returns: string

    .. php:method:: getSocket()

        Gets the socket object

        :returns: Socket\ServerClientSocket

    .. php:method:: getClientApplication()

        Gets the client application

        :returns: Application

    .. php:method:: configureProtocol()

        Configures the protocol option


================================================
FILE: doc/source/api/ConnectionManager.rst
================================================
-------------------------
Wrench\\ConnectionManager
-------------------------

.. php:namespace: Wrench

.. php:class:: ConnectionManager

    .. php:attr:: server

        protected Server

    .. php:attr:: socket

        protected Socket

        Master socket

    .. php:attr:: connections

        protected array<int

        An array of client connections

    .. php:attr:: resources

        protected array<int

        An array of raw socket resources, corresponding to connections, roughly

    .. php:attr:: options

        protected array

    .. php:attr:: protocol

        protected Protocol

    .. php:method:: __construct(Server $server, $options = array())

        Constructor

        :type $server: Server
        :param $server:
        :type $options: array
        :param $options:

    .. php:method:: count()

    .. php:method:: configure($options)

        :param $options:

    .. php:method:: getApplicationForPath($path)

        Gets the application associated with the given path

        :type $path: string
        :param $path:

    .. php:method:: configureMasterSocket()

        Configures the main server socket

    .. php:method:: listen()

        Listens on the main socket

        :returns: void

    .. php:method:: getAllResources()

        Gets all resources

        :returns: array<int => resource)

    .. php:method:: getConnectionForClientSocket($socket)

        Returns the Connection associated with the specified socket resource

        :type $socket: resource
        :param $socket:
        :returns: Connection

    .. php:method:: selectAndProcess()

        Select and process an array of resources

    .. php:method:: processMasterSocket()

        Process events on the master socket ($this->socket)

        :returns: void

    .. php:method:: createConnection($resource)

        Creates a connection from a socket resource

        The create connection object is based on the options passed into the
        constructor ('connection_class', 'connection_options'). This connection
        instance and its associated socket resource are then stored in the
        manager.

        :type $resource: resource
        :param $resource: A socket resource
        :returns: Connection

    .. php:method:: processClientSocket($socket)

        Process events on a client socket

        :type $socket: resource
        :param $socket:

    .. php:method:: resourceId($resource)

        This server makes an explicit assumption: PHP resource types may be cast
        to a integer. Furthermore, we assume this is bijective. Both seem to be
        true in most circumstances, but may not be guaranteed.

        This method (and $this->getResourceId()) exist to make this assumption
        explicit.

        This is needed on the connection manager as well as on resources

        :type $resource: resource
        :param $resource:

    .. php:method:: getUri()

        Gets the connection manager's listening URI

        :returns: string

    .. php:method:: log($message, $priority = 'info')

        Logs a message

        :type $message: string
        :param $message:
        :type $priority: string
        :param $priority:

    .. php:method:: getServer()

        :returns: \Wrench\Server

    .. php:method:: removeConnection(Connection $connection)

        Removes a connection

        :type $connection: Connection
        :param $connection:

    .. php:method:: configureProtocol()

        Configures the protocol option


================================================
FILE: doc/source/api/Exception/BadRequestException.rst
================================================
--------------------------------------
Wrench\\Exception\\BadRequestException
--------------------------------------

.. php:namespace: Wrench\\Exception

.. php:class:: BadRequestException

    .. php:attr:: message

        protected

    .. php:attr:: code

        protected

    .. php:attr:: file

        protected

    .. php:attr:: line

        protected

    .. php:method:: __construct($message = null, $code = null, $previous = null)

        :param $message:
        :param $code:
        :type $previous: Exception
        :param $previous:

    .. php:method:: __clone()

    .. php:method:: getMessage()

    .. php:method:: getCode()

    .. php:method:: getFile()

    .. php:method:: getLine()

    .. php:method:: getTrace()

    .. php:method:: getPrevious()

    .. php:method:: getTraceAsString()

    .. php:method:: __toString()


================================================
FILE: doc/source/api/Exception/CloseException.rst
================================================
---------------------------------
Wrench\\Exception\\CloseException
---------------------------------

.. php:namespace: Wrench\\Exception

.. php:class:: CloseException

    Close connection exception

    .. php:attr:: message

        protected

    .. php:attr:: code

        protected

    .. php:attr:: file

        protected

    .. php:attr:: line

        protected

    .. php:method:: __construct($message = null, $code = null, $previous = null)

        :param $message:
        :param $code:
        :type $previous: Exception
        :param $previous:

    .. php:method:: __clone()

    .. php:method:: getMessage()

    .. php:method:: getCode()

    .. php:method:: getFile()

    .. php:method:: getLine()

    .. php:method:: getTrace()

    .. php:method:: getPrevious()

    .. php:method:: getTraceAsString()

    .. php:method:: __toString()


================================================
FILE: doc/source/api/Exception/ConnectionException.rst
================================================
--------------------------------------
Wrench\\Exception\\ConnectionException
--------------------------------------

.. php:namespace: Wrench\\Exception

.. php:class:: ConnectionException

    .. php:attr:: message

        protected

    .. php:attr:: code

        protected

    .. php:attr:: file

        protected

    .. php:attr:: line

        protected

    .. php:method:: __clone()

    .. php:method:: __construct($message, $code, $previous)

        :param $message:
        :param $code:
        :param $previous:

    .. php:method:: getMessage()

    .. php:method:: getCode()

    .. php:method:: getFile()

    .. php:method:: getLine()

    .. php:method:: getTrace()

    .. php:method:: getPrevious()

    .. php:method:: getTraceAsString()

    .. php:method:: __toString()


================================================
FILE: doc/source/api/Exception/Exception.rst
================================================
----------------------------
Wrench\\Exception\\Exception
----------------------------

.. php:namespace: Wrench\\Exception

.. php:class:: Exception

    .. php:attr:: message

        protected

    .. php:attr:: code

        protected

    .. php:attr:: file

        protected

    .. php:attr:: line

        protected

    .. php:method:: __clone()

    .. php:method:: __construct($message, $code, $previous)

        :param $message:
        :param $code:
        :param $previous:

    .. php:method:: getMessage()

    .. php:method:: getCode()

    .. php:method:: getFile()

    .. php:method:: getLine()

    .. php:method:: getTrace()

    .. php:method:: getPrevious()

    .. php:method:: getTraceAsString()

    .. php:method:: __toString()


================================================
FILE: doc/source/api/Exception/FrameException.rst
================================================
---------------------------------
Wrench\\Exception\\FrameException
---------------------------------

.. php:namespace: Wrench\\Exception

.. php:class:: FrameException

    .. php:attr:: message

        protected

    .. php:attr:: code

        protected

    .. php:attr:: file

        protected

    .. php:attr:: line

        protected

    .. php:method:: __clone()

    .. php:method:: __construct($message, $code, $previous)

        :param $message:
        :param $code:
        :param $previous:

    .. php:method:: getMessage()

    .. php:method:: getCode()

    .. php:method:: getFile()

    .. php:method:: getLine()

    .. php:method:: getTrace()

    .. php:method:: getPrevious()

    .. php:method:: getTraceAsString()

    .. php:method:: __toString()


================================================
FILE: doc/source/api/Exception/HandshakeException.rst
================================================
-------------------------------------
Wrench\\Exception\\HandshakeException
-------------------------------------

.. php:namespace: Wrench\\Exception

.. php:class:: HandshakeException

    .. php:attr:: message

        protected

    .. php:attr:: code

        protected

    .. php:attr:: file

        protected

    .. php:attr:: line

        protected

    .. php:method:: __construct($message = null, $code = null, $previous = null)

        :param $message:
        :param $code:
        :type $previous: Exception
        :param $previous:

    .. php:method:: __clone()

    .. php:method:: getMessage()

    .. php:method:: getCode()

    .. php:method:: getFile()

    .. php:method:: getLine()

    .. php:method:: getTrace()

    .. php:method:: getPrevious()

    .. php:method:: getTraceAsString()

    .. php:method:: __toString()


================================================
FILE: doc/source/api/Exception/InvalidOriginException.rst
================================================
-----------------------------------------
Wrench\\Exception\\InvalidOriginException
-----------------------------------------

.. php:namespace: Wrench\\Exception

.. php:class:: InvalidOriginException

    Invalid origin exception

    .. php:attr:: message

        protected

    .. php:attr:: code

        protected

    .. php:attr:: file

        protected

    .. php:attr:: line

        protected

    .. php:method:: __construct($message = null, $code = null, $previous = null)

        :param $message:
        :param $code:
        :type $previous: Exception
        :param $previous:

    .. php:method:: __clone()

    .. php:method:: getMessage()

    .. php:method:: getCode()

    .. php:method:: getFile()

    .. php:method:: getLine()

    .. php:method:: getTrace()

    .. php:method:: getPrevious()

    .. php:method:: getTraceAsString()

    .. php:method:: __toString()


================================================
FILE: doc/source/api/Exception/PayloadException.rst
================================================
-----------------------------------
Wrench\\Exception\\PayloadException
-----------------------------------

.. php:namespace: Wrench\\Exception

.. php:class:: PayloadException

    .. php:attr:: message

        protected

    .. php:attr:: code

        protected

    .. php:attr:: file

        protected

    .. php:attr:: line

        protected

    .. php:method:: __clone()

    .. php:method:: __construct($message, $code, $previous)

        :param $message:
        :param $code:
        :param $previous:

    .. php:method:: getMessage()

    .. php:method:: getCode()

    .. php:method:: getFile()

    .. php:method:: getLine()

    .. php:method:: getTrace()

    .. php:method:: getPrevious()

    .. php:method:: getTraceAsString()

    .. php:method:: __toString()


================================================
FILE: doc/source/api/Exception/RateLimiterException.rst
================================================
---------------------------------------
Wrench\\Exception\\RateLimiterException
---------------------------------------

.. php:namespace: Wrench\\Exception

.. php:class:: RateLimiterException

    .. php:attr:: message

        protected

    .. php:attr:: code

        protected

    .. php:attr:: file

        protected

    .. php:attr:: line

        protected

    .. php:method:: __construct($message = null, $code = null, $previous = null)

        :param $message:
        :param $code:
        :type $previous: Exception
        :param $previous:

    .. php:method:: __clone()

    .. php:method:: getMessage()

    .. php:method:: getCode()

    .. php:method:: getFile()

    .. php:method:: getLine()

    .. php:method:: getTrace()

    .. php:method:: getPrevious()

    .. php:method:: getTraceAsString()

    .. php:method:: __toString()


================================================
FILE: doc/source/api/Exception/SocketException.rst
================================================
----------------------------------
Wrench\\Exception\\SocketException
----------------------------------

.. php:namespace: Wrench\\Exception

.. php:class:: SocketException

    .. php:attr:: message

        protected

    .. php:attr:: code

        protected

    .. php:attr:: file

        protected

    .. php:attr:: line

        protected

    .. php:method:: __clone()

    .. php:method:: __construct($message, $code, $previous)

        :param $message:
        :param $code:
        :param $previous:

    .. php:method:: getMessage()

    .. php:method:: getCode()

    .. php:method:: getFile()

    .. php:method:: getLine()

    .. php:method:: getTrace()

    .. php:method:: getPrevious()

    .. php:method:: getTraceAsString()

    .. php:method:: __toString()


================================================
FILE: doc/source/api/Exception/index.rst
================================================
:::::::::::::::::
Wrench\\Exception
:::::::::::::::::

.. php:namespace: Wrench\\Exception

.. toctree::

   BadRequestException
   CloseException
   ConnectionException
   Exception
   FrameException
   HandshakeException
   InvalidOriginException
   PayloadException
   RateLimiterException
   SocketException


================================================
FILE: doc/source/api/Frame/Frame.rst
================================================
--------------------
Wrench\\Frame\\Frame
--------------------

.. php:namespace: Wrench\\Frame

.. php:class:: Frame

    Represents a WebSocket frame

    .. php:attr:: length

        protected int

        The frame data length

    .. php:attr:: type

        protected int

        The type of this payload

    .. php:attr:: buffer

        protected string

        The buffer

        May not be a complete payload, because this frame may still be receiving
        data. See

    .. php:attr:: payload

        protected string

        The enclosed frame payload

        May not be a complete payload, because this frame might indicate a
        continuation frame. See isFinal() versus isComplete()

    .. php:method:: getLength()

        Gets the length of the payload

        :returns: int

    .. php:method:: encode($data, $type = Protocol::TYPE_TEXT, $masked = false)

        Resets the frame and encodes the given data into it

        :type $data: string
        :param $data:
        :type $type: int
        :param $type:
        :type $masked: boolean
        :param $masked:
        :returns: Frame

    .. php:method:: isFinal()

        Whether the frame is the final one in a continuation

        :returns: boolean

    .. php:method:: getType()

        :returns: int

    .. php:method:: decodeFramePayloadFromBuffer()

        Decodes a frame payload from the buffer

        :returns: void

    .. php:method:: getExpectedBufferLength()

        Gets the expected length of the buffer once all the data has been
        receieved

        :returns: int

    .. php:method:: isComplete()

        Whether the frame is complete

        :returns: boolean

    .. php:method:: receiveData($data)

        Receieves data into the frame

        :param $data:

    .. php:method:: getRemainingData()

        Gets the remaining number of bytes before this frame will be complete

        :returns: number

    .. php:method:: isWaitingForData()

        Whether this frame is waiting for more data

        :returns: boolean

    .. php:method:: getFramePayload()

        Gets the contents of the frame payload

        The frame must be complete to call this method.

        :returns: string

    .. php:method:: getFrameBuffer()

        Gets the contents of the frame buffer

        This is the encoded value, receieved into the frame with recieveData().

        :returns: string binary

    .. php:method:: getBufferLength()

        Gets the expected length of the frame payload

        :returns: int


================================================
FILE: doc/source/api/Frame/HybiFrame.rst
================================================
------------------------
Wrench\\Frame\\HybiFrame
------------------------

.. php:namespace: Wrench\\Frame

.. php:class:: HybiFrame

    .. php:attr:: masked

        protected boolean

        Whether the payload is masked

    .. php:attr:: mask

        protected string

        Masking key

    .. php:attr:: offset_payload

        protected int

        Byte offsets

    .. php:attr:: offset_mask

        protected

    .. php:attr:: length

        protected int

        The frame data length

    .. php:attr:: type

        protected int

        The type of this payload

    .. php:attr:: buffer

        protected string

        The buffer

        May not be a complete payload, because this frame may still be receiving
        data. See

    .. php:attr:: payload

        protected string

        The enclosed frame payload

        May not be a complete payload, because this frame might indicate a
        continuation frame. See isFinal() versus isComplete()

    .. php:method:: encode($payload, $type = Protocol::TYPE_TEXT, $masked = false)

        :param $payload:
        :param $type:
        :param $masked:

    .. php:method:: mask($payload)

        Masks/Unmasks the frame

        :type $payload: string
        :param $payload:
        :returns: string

    .. php:method:: unmask($payload)

        Masks a payload

        :type $payload: string
        :param $payload:
        :returns: string

    .. php:method:: receiveData($data)

        :param $data:

    .. php:method:: getMask()

        Gets the mask

        :returns: string

    .. php:method:: generateMask()

        Generates a suitable masking key

        :returns: string

    .. php:method:: isMasked()

        Whether the frame is masked

        :returns: boolean

    .. php:method:: getExpectedBufferLength()

    .. php:method:: getPayloadOffset()

        Gets the offset of the payload in the frame

        :returns: int

    .. php:method:: getMaskOffset()

        Gets the offset in the frame to the masking bytes

        :returns: int

    .. php:method:: getLength()

    .. php:method:: getInitialLength()

        Gets the inital length value, stored in the first length byte

        This determines how the rest of the length value is parsed out of the
        frame.

        :returns: int

    .. php:method:: getLengthSize()

        Returns the byte size of the length part of the frame

        Not including the initial 7 bit part

        :returns: int

    .. php:method:: getMaskSize()

        Returns the byte size of the mask part of the frame

        :returns: int

    .. php:method:: decodeFramePayloadFromBuffer()

    .. php:method:: isFinal()

    .. php:method:: getType()

    .. php:method:: isComplete()

        Whether the frame is complete

        :returns: boolean

    .. php:method:: getRemainingData()

        Gets the remaining number of bytes before this frame will be complete

        :returns: number

    .. php:method:: isWaitingForData()

        Whether this frame is waiting for more data

        :returns: boolean

    .. php:method:: getFramePayload()

        Gets the contents of the frame payload

        The frame must be complete to call this method.

        :returns: string

    .. php:method:: getFrameBuffer()

        Gets the contents of the frame buffer

        This is the encoded value, receieved into the frame with recieveData().

        :returns: string binary

    .. php:method:: getBufferLength()

        Gets the expected length of the frame payload

        :returns: int


================================================
FILE: doc/source/api/Frame/index.rst
================================================
:::::::::::::
Wrench\\Frame
:::::::::::::

.. php:namespace: Wrench\\Frame

.. toctree::

   Frame
   HybiFrame


================================================
FILE: doc/source/api/Listener/HandshakeRequestListener.rst
================================================
------------------------------------------
Wrench\\Listener\\HandshakeRequestListener
------------------------------------------

.. php:namespace: Wrench\\Listener

.. php:class:: HandshakeRequestListener

    .. php:method:: onHandshakeRequest(Connection $connection, $path, $origin, $key, $extensions)

        Handshake request listener

        :type $connection: Connection
        :param $connection:
        :type $path: string
        :param $path:
        :type $origin: string
        :param $origin:
        :type $key: string
        :param $key:
        :type $extensions: array
        :param $extensions:


================================================
FILE: doc/source/api/Listener/Listener.rst
================================================
--------------------------
Wrench\\Listener\\Listener
--------------------------

.. php:namespace: Wrench\\Listener

.. php:class:: Listener

    .. php:method:: listen(Server $server)

        :type $server: Server
        :param $server:


================================================
FILE: doc/source/api/Listener/OriginPolicy.rst
================================================
------------------------------
Wrench\\Listener\\OriginPolicy
------------------------------

.. php:namespace: Wrench\\Listener

.. php:class:: OriginPolicy

    .. php:attr:: allowed

        protected

    .. php:method:: __construct($allowed)

        :param $allowed:

    .. php:method:: onHandshakeRequest(Connection $connection, $path, $origin, $key, $extensions)

        Handshake request listener

        Closes the connection on handshake from an origin that isn't allowed

        :type $connection: Connection
        :param $connection:
        :type $path: string
        :param $path:
        :type $origin: string
        :param $origin:
        :type $key: string
        :param $key:
        :type $extensions: array
        :param $extensions:

    .. php:method:: isAllowed($origin)

        Whether the specified origin is allowed under this policy

        :type $origin: string
        :param $origin:
        :returns: boolean

    .. php:method:: listen(Server $server)

        :type $server: Server
        :param $server:


================================================
FILE: doc/source/api/Listener/RateLimiter.rst
================================================
-----------------------------
Wrench\\Listener\\RateLimiter
-----------------------------

.. php:namespace: Wrench\\Listener

.. php:class:: RateLimiter

    .. php:attr:: server

        protected Server

        The server being limited

    .. php:attr:: ips

        protected array<int>

        Connection counts per IP address

    .. php:attr:: requests

        protected array<array<int>>

        Request tokens per IP address

    .. php:attr:: options

        protected array

    .. php:attr:: protocol

        protected Protocol

    .. php:method:: __construct($options = array())

        Constructor

        :type $options: array
        :param $options:

    .. php:method:: configure($options)

        :type $options: array
        :param $options:

    .. php:method:: listen(Server $server)

        :type $server: Server
        :param $server:

    .. php:method:: onSocketConnect($socket, $connection)

        Event listener

        :type $socket: resource
        :param $socket:
        :type $connection: Connection
        :param $connection:

    .. php:method:: onSocketDisconnect($socket, $connection)

        Event listener

        :type $socket: resource
        :param $socket:
        :type $connection: Connection
        :param $connection:

    .. php:method:: onClientData($socket, $connection)

        Event listener

        :type $socket: resource
        :param $socket:
        :type $connection: Connection
        :param $connection:

    .. php:method:: checkConnections($connection)

        Idempotent

        :type $connection: Connection
        :param $connection:

    .. php:method:: checkConnectionsPerIp($connection)

        NOT idempotent, call once per connection

        :type $connection: Connection
        :param $connection:

    .. php:method:: releaseConnection($connection)

        NOT idempotent, call once per disconnection

        :type $connection: Connection
        :param $connection:

    .. php:method:: checkRequestsPerMinute($connection)

        NOT idempotent, call once per data

        :type $connection: Connection
        :param $connection:

    .. php:method:: limit($connection, $limit)

        Limits the given connection

        :type $connection: Connection
        :param $connection:
        :type $limit: string
        :param $limit: Reason

    .. php:method:: log($message, $priority = 'info')

        Logger

        :type $message: string
        :param $message:
        :type $priority: string
        :param $priority:

    .. php:method:: configureProtocol()

        Configures the protocol option


================================================
FILE: doc/source/api/Listener/index.rst
================================================
::::::::::::::::
Wrench\\Listener
::::::::::::::::

.. php:namespace: Wrench\\Listener

.. toctree::

   HandshakeRequestListener
   Listener
   OriginPolicy
   RateLimiter


================================================
FILE: doc/source/api/Payload/HybiPayload.rst
================================================
----------------------------
Wrench\\Payload\\HybiPayload
----------------------------

.. php:namespace: Wrench\\Payload

.. php:class:: HybiPayload

    Gets a HyBi payload

    .. php:attr:: frames

        protected array<Frame>

        A payload may consist of one or more frames

    .. php:method:: getFrame()

    .. php:method:: getCurrentFrame()

        Gets the current frame for the payload

        :returns: mixed

    .. php:method:: getReceivingFrame()

        Gets the frame into which data should be receieved

        :returns: Frame

    .. php:method:: isComplete()

        Whether the payload is complete

        :returns: boolean

    .. php:method:: encode($data, $type = Protocol::TYPE_TEXT, $masked = false)

        Encodes a payload

        :type $data: string
        :param $data:
        :type $type: int
        :param $type:
        :type $masked: boolean
        :param $masked:
        :returns: Payload

    .. php:method:: getRemainingData()

        Gets the number of remaining bytes before this payload will be
        complete

        May return 0 (no more bytes required) or null (unknown number of bytes
        required).

        :returns: number|NULL

    .. php:method:: isWaitingForData()

        Whether this payload is waiting for more data

        :returns: boolean

    .. php:method:: sendToSocket(Socket $socket)

        :type $socket: Socket
        :param $socket:
        :returns: boolean

    .. php:method:: receiveData($data)

        Receive raw data into the payload

        :type $data: string
        :param $data:
        :returns: void

    .. php:method:: getPayload()

        :returns: string

    .. php:method:: __toString()

        :returns: string

    .. php:method:: getType()

        Gets the type of the payload

        The type of a payload is taken from its first frame

        :returns: int


================================================
FILE: doc/source/api/Payload/Payload.rst
================================================
------------------------
Wrench\\Payload\\Payload
------------------------

.. php:namespace: Wrench\\Payload

.. php:class:: Payload

    Payload class

    Represents a WebSocket protocol payload, which may be made up of multiple frames.

    .. php:attr:: frames

        protected array<Frame>

        A payload may consist of one or more frames

    .. php:method:: getCurrentFrame()

        Gets the current frame for the payload

        :returns: mixed

    .. php:method:: getReceivingFrame()

        Gets the frame into which data should be receieved

        :returns: Frame

    .. php:method:: getFrame()

        Get a frame object

        :returns: Frame

    .. php:method:: isComplete()

        Whether the payload is complete

        :returns: boolean

    .. php:method:: encode($data, $type = Protocol::TYPE_TEXT, $masked = false)

        Encodes a payload

        :type $data: string
        :param $data:
        :type $type: int
        :param $type:
        :type $masked: boolean
        :param $masked:
        :returns: Payload

    .. php:method:: getRemainingData()

        Gets the number of remaining bytes before this payload will be
        complete

        May return 0 (no more bytes required) or null (unknown number of bytes
        required).

        :returns: number|NULL

    .. php:method:: isWaitingForData()

        Whether this payload is waiting for more data

        :returns: boolean

    .. php:method:: sendToSocket(Socket $socket)

        :type $socket: Socket
        :param $socket:
        :returns: boolean

    .. php:method:: receiveData($data)

        Receive raw data into the payload

        :type $data: string
        :param $data:
        :returns: void

    .. php:method:: getPayload()

        :returns: string

    .. php:method:: __toString()

        :returns: string

    .. php:method:: getType()

        Gets the type of the payload

        The type of a payload is taken from its first frame

        :returns: int


================================================
FILE: doc/source/api/Payload/index.rst
================================================
:::::::::::::::
Wrench\\Payload
:::::::::::::::

.. php:namespace: Wrench\\Payload

.. toctree::

   HybiPayload
   Payload


================================================
FILE: doc/source/api/Protocol/Hybi10Protocol.rst
================================================
--------------------------------
Wrench\\Protocol\\Hybi10Protocol
--------------------------------

.. php:namespace: Wrench\\Protocol

.. php:class:: Hybi10Protocol

    http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10

    .. php:const:: SCHEME_WEBSOCKET

        Relevant schemes

    .. php:const:: HEADER_HOST

        HTTP headers

    .. php:const:: HTTP_SWITCHING_PROTOCOLS

        HTTP error statuses

    .. php:const:: CLOSE_NORMAL

        Close statuses

    .. php:const:: TYPE_CONTINUATION

        Frame types

        %x0 denotes a continuation frame
         %x1 denotes a text frame
         %x2 denotes a binary frame
         %x3-7 are reserved for further non-control frames
         %x8 denotes a connection close
         %x9 denotes a ping
         %xA denotes a pong
         %xB-F are reserved for further control frames

    .. php:const:: MAGIC_GUID

        Magic GUID

        Used in the WebSocket accept header

    .. php:const:: UPGRADE_VALUE

        The request MUST contain an |Upgrade| header field whose value
          MUST include the "websocket" keyword.

    .. php:const:: CONNECTION_VALUE

        The request MUST contain a |Connection| header field whose value
          MUST include the "Upgrade" token.

    .. php:const:: REQUEST_LINE_FORMAT

        Request line format

    .. php:const:: REQUEST_LINE_REGEX

        Request line regex

        Used for parsing requested path

    .. php:const:: RESPONSE_LINE_FORMAT

        Response line format

    .. php:const:: HEADER_LINE_FORMAT

        Header line format

    .. php:attr:: schemes

        protected array<string>

        Valid schemes

    .. php:attr:: closeReasons

        array<int

        Close status codes

    .. php:attr:: frameTypes

        array<string

        Frame types

    .. php:attr:: httpResponses

        array<int

        HTTP errors

    .. php:method:: getVersion()

    .. php:method:: acceptsVersion($version)

        This is our most recent protocol class

        :param $version:

    .. php:method:: getPayload()

    .. php:method:: generateKey()

        Generates a key suitable for use in the protocol

        This base implementation returns a 16-byte (128 bit) random key as a
        binary string.

        :returns: string

    .. php:method:: getRequestHandshake($uri, $key, $origin, $headers = array())

        Gets request handshake string

        The leading line from the client follows the Request-Line format.
        The leading line from the server follows the Status-Line format.  The
        Request-Line and Status-Line productions are defined in [RFC2616].

        An unordered set of header fields comes after the leading line in both
        cases.  The meaning of these header fields is specified in Section 4 of
        this document.  Additional header fields may also be present, such as
        cookies [RFC6265].  The format and parsing of headers is as defined in
        [RFC2616].

        :type $uri: string
        :param $uri: WebSocket URI, e.g. ws://example.org:8000/chat
        :type $key: string
        :param $key: 16 byte binary string key
        :type $origin: string
        :param $origin: Origin of the request
        :param $headers:
        :returns: string

    .. php:method:: getResponseHandshake($key, $headers = array())

        Gets a handshake response body

        :type $key: string
        :param $key:
        :type $headers: array
        :param $headers:

    .. php:method:: getResponseError($e, $headers = array())

        Gets a response to an error in the handshake

        :type $e: int|Exception
        :param $e: Exception or HTTP error
        :type $headers: array
        :param $headers:

    .. php:method:: getHttpResponse($status, $headers = array())

        Gets an HTTP response

        :type $status: int
        :param $status:
        :type $headers: array
        :param $headers:

    .. php:method:: validateResponseHandshake($response, $key)

        :type $response: unknown_type
        :param $response:
        :type $key: unknown_type
        :param $key:
        :returns: boolean

    .. php:method:: getEncodedHash($key)

        Gets an encoded hash for a key

        :type $key: string
        :param $key:
        :returns: string

    .. php:method:: validateRequestHandshake($request)

        Validates a request handshake

        :type $request: string
        :param $request:

    .. php:method:: getCloseFrame($e)

        Gets a suitable WebSocket close frame

        :type $e: Exception|int
        :param $e:

    .. php:method:: validateUri($uri)

        Validates a WebSocket URI

        :type $uri: string
        :param $uri:
        :returns: array(string $scheme, string $host, int $port, string $path)

    .. php:method:: validateSocketUri($uri)

        Validates a socket URI

        :type $uri: string
        :param $uri:
        :returns: array(string $scheme, string $host, string $port)

    .. php:method:: validateOriginUri($origin)

        Validates an origin URI

        :type $origin: string
        :param $origin:
        :returns: string

    .. php:method:: validateRequestLine($line)

        Validates a request line

        :type $line: string
        :param $line:

    .. php:method:: getAcceptValue($encoded_key)

        Gets the expected accept value for a handshake response

        Note that the protocol calls for the base64 encoded value to be hashed,
        not the original 16 byte random key.

        :param $encoded_key:

    .. php:method:: getHeaders($response, $request_line = null)

        Gets the headers from a full response

        :type $response: string
        :param $response:
        :param $request_line:
        :returns: array()

    .. php:method:: getRequestHeaders($response)

        Gets request headers

        :type $response: string
        :param $response:
        :returns: array<string, array<string>> The request line, and an array of headers

    .. php:method:: validateScheme($scheme)

        Validates a scheme

        :type $scheme: string
        :param $scheme:
        :returns: string Underlying scheme

    .. php:method:: getDefaultRequestHeaders($host, $key, $origin)

        Gets the default request headers

        :type $host: string
        :param $host:
        :type $key: string
        :param $key:
        :type $origin: string
        :param $origin:
        :returns: multitype:unknown string NULL

    .. php:method:: getSuccessResponseHeaders($key)

        Gets the default response headers

        :type $key: string
        :param $key:

    .. php:method:: getPort($scheme)

        Gets the default port for a scheme

        By default, the WebSocket Protocol uses port 80 for regular WebSocket
        connections and port 443 for WebSocket connections tunneled over Transport
        Layer Security

        :param $scheme:
        :returns: int


================================================
FILE: doc/source/api/Protocol/HybiProtocol.rst
================================================
------------------------------
Wrench\\Protocol\\HybiProtocol
------------------------------

.. php:namespace: Wrench\\Protocol

.. php:class:: HybiProtocol

    .. php:const:: SCHEME_WEBSOCKET

        Relevant schemes

    .. php:const:: HEADER_HOST

        HTTP headers

    .. php:const:: HTTP_SWITCHING_PROTOCOLS

        HTTP error statuses

    .. php:const:: CLOSE_NORMAL

        Close statuses

    .. php:const:: TYPE_CONTINUATION

        Frame types

        %x0 denotes a continuation frame
         %x1 denotes a text frame
         %x2 denotes a binary frame
         %x3-7 are reserved for further non-control frames
         %x8 denotes a connection close
         %x9 denotes a ping
         %xA denotes a pong
         %xB-F are reserved for further control frames

    .. php:const:: MAGIC_GUID

        Magic GUID

        Used in the WebSocket accept header

    .. php:const:: UPGRADE_VALUE

        The request MUST contain an |Upgrade| header field whose value
          MUST include the "websocket" keyword.

    .. php:const:: CONNECTION_VALUE

        The request MUST contain a |Connection| header field whose value
          MUST include the "Upgrade" token.

    .. php:const:: REQUEST_LINE_FORMAT

        Request line format

    .. php:const:: REQUEST_LINE_REGEX

        Request line regex

        Used for parsing requested path

    .. php:const:: RESPONSE_LINE_FORMAT

        Response line format

    .. php:const:: HEADER_LINE_FORMAT

        Header line format

    .. php:attr:: schemes

        protected array<string>

        Valid schemes

    .. php:attr:: closeReasons

        array<int

        Close status codes

    .. php:attr:: frameTypes

        array<string

        Frame types

    .. php:attr:: httpResponses

        array<int

        HTTP errors

    .. php:method:: getPayload()

    .. php:method:: getVersion()

        Gets a version number

    .. php:method:: acceptsVersion($version)

        Subclasses should implement this method and return a boolean to the given
        version string, as to whether they would like to accept requests from
        user agents that specify that version.

        :param $version:
        :returns: boolean

    .. php:method:: generateKey()

        Generates a key suitable for use in the protocol

        This base implementation returns a 16-byte (128 bit) random key as a
        binary string.

        :returns: string

    .. php:method:: getRequestHandshake($uri, $key, $origin, $headers = array())

        Gets request handshake string

        The leading line from the client follows the Request-Line format.
        The leading line from the server follows the Status-Line format.  The
        Request-Line and Status-Line productions are defined in [RFC2616].

        An unordered set of header fields comes after the leading line in both
        cases.  The meaning of these header fields is specified in Section 4 of
        this document.  Additional header fields may also be present, such as
        cookies [RFC6265].  The format and parsing of headers is as defined in
        [RFC2616].

        :type $uri: string
        :param $uri: WebSocket URI, e.g. ws://example.org:8000/chat
        :type $key: string
        :param $key: 16 byte binary string key
        :type $origin: string
        :param $origin: Origin of the request
        :param $headers:
        :returns: string

    .. php:method:: getResponseHandshake($key, $headers = array())

        Gets a handshake response body

        :type $key: string
        :param $key:
        :type $headers: array
        :param $headers:

    .. php:method:: getResponseError($e, $headers = array())

        Gets a response to an error in the handshake

        :type $e: int|Exception
        :param $e: Exception or HTTP error
        :type $headers: array
        :param $headers:

    .. php:method:: getHttpResponse($status, $headers = array())

        Gets an HTTP response

        :type $status: int
        :param $status:
        :type $headers: array
        :param $headers:

    .. php:method:: validateResponseHandshake($response, $key)

        :type $response: unknown_type
        :param $response:
        :type $key: unknown_type
        :param $key:
        :returns: boolean

    .. php:method:: getEncodedHash($key)

        Gets an encoded hash for a key

        :type $key: string
        :param $key:
        :returns: string

    .. php:method:: validateRequestHandshake($request)

        Validates a request handshake

        :type $request: string
        :param $request:

    .. php:method:: getCloseFrame($e)

        Gets a suitable WebSocket close frame

        :type $e: Exception|int
        :param $e:

    .. php:method:: validateUri($uri)

        Validates a WebSocket URI

        :type $uri: string
        :param $uri:
        :returns: array(string $scheme, string $host, int $port, string $path)

    .. php:method:: validateSocketUri($uri)

        Validates a socket URI

        :type $uri: string
        :param $uri:
        :returns: array(string $scheme, string $host, string $port)

    .. php:method:: validateOriginUri($origin)

        Validates an origin URI

        :type $origin: string
        :param $origin:
        :returns: string

    .. php:method:: validateRequestLine($line)

        Validates a request line

        :type $line: string
        :param $line:

    .. php:method:: getAcceptValue($encoded_key)

        Gets the expected accept value for a handshake response

        Note that the protocol calls for the base64 encoded value to be hashed,
        not the original 16 byte random key.

        :param $encoded_key:

    .. php:method:: getHeaders($response, $request_line = null)

        Gets the headers from a full response

        :type $response: string
        :param $response:
        :param $request_line:
        :returns: array()

    .. php:method:: getRequestHeaders($response)

        Gets request headers

        :type $response: string
        :param $response:
        :returns: array<string, array<string>> The request line, and an array of headers

    .. php:method:: validateScheme($scheme)

        Validates a scheme

        :type $scheme: string
        :param $scheme:
        :returns: string Underlying scheme

    .. php:method:: getDefaultRequestHeaders($host, $key, $origin)

        Gets the default request headers

        :type $host: string
        :param $host:
        :type $key: string
        :param $key:
        :type $origin: string
        :param $origin:
        :returns: multitype:unknown string NULL

    .. php:method:: getSuccessResponseHeaders($key)

        Gets the default response headers

        :type $key: string
        :param $key:

    .. php:method:: getPort($scheme)

        Gets the default port for a scheme

        By default, the WebSocket Protocol uses port 80 for regular WebSocket
        connections and port 443 for WebSocket connections tunneled over Transport
        Layer Security

        :param $scheme:
        :returns: int


================================================
FILE: doc/source/api/Protocol/Protocol.rst
================================================
--------------------------
Wrench\\Protocol\\Protocol
--------------------------

.. php:namespace: Wrench\\Protocol

.. php:class:: Protocol

    Definitions and implementation helpers for the Wrenchs protocol

    Based on RFC 6455: http://tools.ietf.org/html/rfc6455

    .. php:const:: SCHEME_WEBSOCKET

        Relevant schemes

    .. php:const:: HEADER_HOST

        HTTP headers

    .. php:const:: HTTP_SWITCHING_PROTOCOLS

        HTTP error statuses

    .. php:const:: CLOSE_NORMAL

        Close statuses

    .. php:const:: TYPE_CONTINUATION

        Frame types

        %x0 denotes a continuation frame
         %x1 denotes a text frame
         %x2 denotes a binary frame
         %x3-7 are reserved for further non-control frames
         %x8 denotes a connection close
         %x9 denotes a ping
         %xA denotes a pong
         %xB-F are reserved for further control frames

    .. php:const:: MAGIC_GUID

        Magic GUID

        Used in the WebSocket accept header

    .. php:const:: UPGRADE_VALUE

        The request MUST contain an |Upgrade| header field whose value
          MUST include the "websocket" keyword.

    .. php:const:: CONNECTION_VALUE

        The request MUST contain a |Connection| header field whose value
          MUST include the "Upgrade" token.

    .. php:const:: REQUEST_LINE_FORMAT

        Request line format

    .. php:const:: REQUEST_LINE_REGEX

        Request line regex

        Used for parsing requested path

    .. php:const:: RESPONSE_LINE_FORMAT

        Response line format

    .. php:const:: HEADER_LINE_FORMAT

        Header line format

    .. php:attr:: schemes

        protected array<string>

        Valid schemes

    .. php:attr:: closeReasons

        array<int

        Close status codes

    .. php:attr:: frameTypes

        array<string

        Frame types

    .. php:attr:: httpResponses

        array<int

        HTTP errors

    .. php:method:: getVersion()

        Gets a version number

    .. php:method:: acceptsVersion($version)

        Subclasses should implement this method and return a boolean to the given
        version string, as to whether they would like to accept requests from
        user agents that specify that version.

        :param $version:
        :returns: boolean

    .. php:method:: getPayload()

        Gets a payload instance, suitable for use in decoding/encoding protocol
        frames

        :returns: Payload

    .. php:method:: generateKey()

        Generates a key suitable for use in the protocol

        This base implementation returns a 16-byte (128 bit) random key as a
        binary string.

        :returns: string

    .. php:method:: getRequestHandshake($uri, $key, $origin, $headers = array())

        Gets request handshake string

        The leading line from the client follows the Request-Line format.
        The leading line from the server follows the Status-Line format.  The
        Request-Line and Status-Line productions are defined in [RFC2616].

        An unordered set of header fields comes after the leading line in both
        cases.  The meaning of these header fields is specified in Section 4 of
        this document.  Additional header fields may also be present, such as
        cookies [RFC6265].  The format and parsing of headers is as defined in
        [RFC2616].

        :type $uri: string
        :param $uri: WebSocket URI, e.g. ws://example.org:8000/chat
        :type $key: string
        :param $key: 16 byte binary string key
        :type $origin: string
        :param $origin: Origin of the request
        :param $headers:
        :returns: string

    .. php:method:: getResponseHandshake($key, $headers = array())

        Gets a handshake response body

        :type $key: string
        :param $key:
        :type $headers: array
        :param $headers:

    .. php:method:: getResponseError($e, $headers = array())

        Gets a response to an error in the handshake

        :type $e: int|Exception
        :param $e: Exception or HTTP error
        :type $headers: array
        :param $headers:

    .. php:method:: getHttpResponse($status, $headers = array())

        Gets an HTTP response

        :type $status: int
        :param $status:
        :type $headers: array
        :param $headers:

    .. php:method:: validateResponseHandshake($response, $key)

        :type $response: unknown_type
        :param $response:
        :type $key: unknown_type
        :param $key:
        :returns: boolean

    .. php:method:: getEncodedHash($key)

        Gets an encoded hash for a key

        :type $key: string
        :param $key:
        :returns: string

    .. php:method:: validateRequestHandshake($request)

        Validates a request handshake

        :type $request: string
        :param $request:

    .. php:method:: getCloseFrame($e)

        Gets a suitable WebSocket close frame

        :type $e: Exception|int
        :param $e:

    .. php:method:: validateUri($uri)

        Validates a WebSocket URI

        :type $uri: string
        :param $uri:
        :returns: array(string $scheme, string $host, int $port, string $path)

    .. php:method:: validateSocketUri($uri)

        Validates a socket URI

        :type $uri: string
        :param $uri:
        :returns: array(string $scheme, string $host, string $port)

    .. php:method:: validateOriginUri($origin)

        Validates an origin URI

        :type $origin: string
        :param $origin:
        :returns: string

    .. php:method:: validateRequestLine($line)

        Validates a request line

        :type $line: string
        :param $line:

    .. php:method:: getAcceptValue($encoded_key)

        Gets the expected accept value for a handshake response

        Note that the protocol calls for the base64 encoded value to be hashed,
        not the original 16 byte random key.

        :param $encoded_key:

    .. php:method:: getHeaders($response, $request_line = null)

        Gets the headers from a full response

        :type $response: string
        :param $response:
        :param $request_line:
        :returns: array()

    .. php:method:: getRequestHeaders($response)

        Gets request headers

        :type $response: string
        :param $response:
        :returns: array<string, array<string>> The request line, and an array of headers

    .. php:method:: validateScheme($scheme)

        Validates a scheme

        :type $scheme: string
        :param $scheme:
        :returns: string Underlying scheme

    .. php:method:: getDefaultRequestHeaders($host, $key, $origin)

        Gets the default request headers

        :type $host: string
        :param $host:
        :type $key: string
        :param $key:
        :type $origin: string
        :param $origin:
        :returns: multitype:unknown string NULL

    .. php:method:: getSuccessResponseHeaders($key)

        Gets the default response headers

        :type $key: string
        :param $key:

    .. php:method:: getPort($scheme)

        Gets the default port for a scheme

        By default, the WebSocket Protocol uses port 80 for regular WebSocket
        connections and port 443 for WebSocket connections tunneled over Transport
        Layer Security

        :param $scheme:
        :returns: int


================================================
FILE: doc/source/api/Protocol/Rfc6455Protocol.rst
================================================
---------------------------------
Wrench\\Protocol\\Rfc6455Protocol
---------------------------------

.. php:namespace: Wrench\\Protocol

.. php:class:: Rfc6455Protocol

    This is the version of websockets used by Chrome versions 17 through 19.

    .. php:const:: SCHEME_WEBSOCKET

        Relevant schemes

    .. php:const:: HEADER_HOST

        HTTP headers

    .. php:const:: HTTP_SWITCHING_PROTOCOLS

        HTTP error statuses

    .. php:const:: CLOSE_NORMAL

        Close statuses

    .. php:const:: TYPE_CONTINUATION

        Frame types

        %x0 denotes a continuation frame
         %x1 denotes a text frame
         %x2 denotes a binary frame
         %x3-7 are reserved for further non-control frames
         %x8 denotes a connection close
         %x9 denotes a ping
         %xA denotes a pong
         %xB-F are reserved for further control frames

    .. php:const:: MAGIC_GUID

        Magic GUID

        Used in the WebSocket accept header

    .. php:const:: UPGRADE_VALUE

        The request MUST contain an |Upgrade| header field whose value
          MUST include the "websocket" keyword.

    .. php:const:: CONNECTION_VALUE

        The request MUST contain a |Connection| header field whose value
          MUST include the "Upgrade" token.

    .. php:const:: REQUEST_LINE_FORMAT

        Request line format

    .. php:const:: REQUEST_LINE_REGEX

        Request line regex

        Used for parsing requested path

    .. php:const:: RESPONSE_LINE_FORMAT

        Response line format

    .. php:const:: HEADER_LINE_FORMAT

        Header line format

    .. php:attr:: schemes

        protected array<string>

        Valid schemes

    .. php:attr:: closeReasons

        array<int

        Close status codes

    .. php:attr:: frameTypes

        array<string

        Frame types

    .. php:attr:: httpResponses

        array<int

        HTTP errors

    .. php:method:: getVersion()

    .. php:method:: acceptsVersion($version)

        This is our most recent protocol class

        :param $version:

    .. php:method:: getPayload()

    .. php:method:: generateKey()

        Generates a key suitable for use in the protocol

        This base implementation returns a 16-byte (128 bit) random key as a
        binary string.

        :returns: string

    .. php:method:: getRequestHandshake($uri, $key, $origin, $headers = array())

        Gets request handshake string

        The leading line from the client follows the Request-Line format.
        The leading line from the server follows the Status-Line format.  The
        Request-Line and Status-Line productions are defined in [RFC2616].

        An unordered set of header fields comes after the leading line in both
        cases.  The meaning of these header fields is specified in Section 4 of
        this document.  Additional header fields may also be present, such as
        cookies [RFC6265].  The format and parsing of headers is as defined in
        [RFC2616].

        :type $uri: string
        :param $uri: WebSocket URI, e.g. ws://example.org:8000/chat
        :type $key: string
        :param $key: 16 byte binary string key
        :type $origin: string
        :param $origin: Origin of the request
        :param $headers:
        :returns: string

    .. php:method:: getResponseHandshake($key, $headers = array())

        Gets a handshake response body

        :type $key: string
        :param $key:
        :type $headers: array
        :param $headers:

    .. php:method:: getResponseError($e, $headers = array())

        Gets a response to an error in the handshake

        :type $e: int|Exception
        :param $e: Exception or HTTP error
        :type $headers: array
        :param $headers:

    .. php:method:: getHttpResponse($status, $headers = array())

        Gets an HTTP response

        :type $status: int
        :param $status:
        :type $headers: array
        :param $headers:

    .. php:method:: validateResponseHandshake($response, $key)

        :type $response: unknown_type
        :param $response:
        :type $key: unknown_type
        :param $key:
        :returns: boolean

    .. php:method:: getEncodedHash($key)

        Gets an encoded hash for a key

        :type $key: string
        :param $key:
        :returns: string

    .. php:method:: validateRequestHandshake($request)

        Validates a request handshake

        :type $request: string
        :param $request:

    .. php:method:: getCloseFrame($e)

        Gets a suitable WebSocket close frame

        :type $e: Exception|int
        :param $e:

    .. php:method:: validateUri($uri)

        Validates a WebSocket URI

        :type $uri: string
        :param $uri:
        :returns: array(string $scheme, string $host, int $port, string $path)

    .. php:method:: validateSocketUri($uri)

        Validates a socket URI

        :type $uri: string
        :param $uri:
        :returns: array(string $scheme, string $host, string $port)

    .. php:method:: validateOriginUri($origin)

        Validates an origin URI

        :type $origin: string
        :param $origin:
        :returns: string

    .. php:method:: validateRequestLine($line)

        Validates a request line

        :type $line: string
        :param $line:

    .. php:method:: getAcceptValue($encoded_key)

        Gets the expected accept value for a handshake response

        Note that the protocol calls for the base64 encoded value to be hashed,
        not the original 16 byte random key.

        :param $encoded_key:

    .. php:method:: getHeaders($response, $request_line = null)

        Gets the headers from a full response

        :type $response: string
        :param $response:
        :param $request_line:
        :returns: array()

    .. php:method:: getRequestHeaders($response)

        Gets request headers

        :type $response: string
        :param $response:
        :returns: array<string, array<string>> The request line, and an array of headers

    .. php:method:: validateScheme($scheme)

        Validates a scheme

        :type $scheme: string
        :param $scheme:
        :returns: string Underlying scheme

    .. php:method:: getDefaultRequestHeaders($host, $key, $origin)

        Gets the default request headers

        :type $host: string
        :param $host:
        :type $key: string
        :param $key:
        :type $origin: string
        :param $origin:
        :returns: multitype:unknown string NULL

    .. php:method:: getSuccessResponseHeaders($key)

        Gets the default response headers

        :type $key: string
        :param $key:

    .. php:method:: getPort($scheme)

        Gets the default port for a scheme

        By default, the WebSocket Protocol uses port 80 for regular WebSocket
        connections and port 443 for WebSocket connections tunneled over Transport
        Layer Security

        :param $scheme:
        :returns: int


================================================
FILE: doc/source/api/Protocol/index.rst
================================================
::::::::::::::::
Wrench\\Protocol
::::::::::::::::

.. php:namespace: Wrench\\Protocol

.. toctree::

   Hybi10Protocol
   HybiProtocol
   Protocol
   Rfc6455Protocol


================================================
FILE: doc/source/api/Resource.rst
================================================
----------------
Wrench\\Resource
----------------

.. php:namespace: Wrench

.. php:class:: Resource

    Resource interface

    .. php:method:: getResourceId()

    .. php:method:: getResource()


================================================
FILE: doc/source/api/Server.rst
================================================
--------------
Wrench\\Server
--------------

.. php:namespace: Wrench

.. php:class:: Server

    WebSocket server

    The server extends socket, which provides the master socket resource. This resource is listened to, and an array of clients managed.

    .. php:const:: EVENT_SOCKET_CONNECT

        Events

    .. php:attr:: uri

        protected string

        The URI of the server

    .. php:attr:: options

        protected array

        Options

    .. php:attr:: logger

        protected Closure

        A logging callback

        The default callback simply prints to stdout. You can pass your own logger
        in the options array. It should take a string message and string priority
        as parameters.

    .. php:attr:: listeners

        protected array<string

        Event listeners

        Add listeners using the addListener() method.

    .. php:attr:: connectionManager

        protected ConnectionManager

        Connection manager

    .. php:attr:: applications

        protected array<string

        Applications

    .. php:attr:: protocol

        protected Protocol

    .. php:method:: __construct($uri, $options = array())

        Constructor

        :type $uri: string
        :param $uri: Websocket URI, e.g. ws://localhost:8000/, path will be ignored
        :type $options: array
        :param $options: (optional) See configure

    .. php:method:: configure($options)

        Configure options

        Options include
        - socket_class      => The socket class to use, defaults to ServerSocket
        - socket_options    => An array of socket options
        - logger            => Closure($message, $priority = 'info'), used for
        logging

        :type $options: array
        :param $options:
        :returns: void

    .. php:method:: configureLogger()

        Configures the logger

        :returns: void

    .. php:method:: configureConnectionManager()

        Configures the connection manager

        :returns: void

    .. php:method:: getConnectionManager()

        Gets the connection manager

        :returns: \Wrench\ConnectionManager

    .. php:method:: getUri()

        :returns: string

    .. php:method:: setLogger($logger)

        Sets a logger

        :type $logger: Closure
        :param $logger:
        :returns: void

    .. php:method:: run()

        Main server loop

        :returns: void This method does not return!

    .. php:method:: log($message, $priority = 'info')

        Logs a message to the server log

        The default logger simply prints the message to stdout. You can provide a
        logging closure. This is useful, for instance, if you've daemonized and
        closed STDOUT.

        :type $message: string
        :param $message: Message to display.
        :param $priority:
        :returns: void

    .. php:method:: notify($event, $arguments = array())

        Notifies listeners of an event

        :type $event: string
        :param $event:
        :type $arguments: array
        :param $arguments: Event arguments
        :returns: void

    .. php:method:: addListener($event, $callback)

        Adds a listener

        Provide an event (see the Server::EVENT_* constants) and a callback
        closure. Some arguments may be provided to your callback, such as the
        connection the caused the event.

        :type $event: string
        :param $event:
        :type $callback: Closure
        :param $callback:
        :returns: void

    .. php:method:: getApplication($key)

        Returns a server application.

        :type $key: string
        :param $key: Name of application.
        :returns: Application The application object.

    .. php:method:: registerApplication($key, $application)

        Adds a new application object to the application storage.

        :type $key: string
        :param $key: Name of application.
        :type $application: object
        :param $application: The application object
        :returns: void

    .. php:method:: configureProtocol()

        Configures the protocol option


================================================
FILE: doc/source/api/Socket/ClientSocket.rst
================================================
----------------------------
Wrench\\Socket\\ClientSocket
----------------------------

.. php:namespace: Wrench\\Socket

.. php:class:: ClientSocket

    Options:
     - timeout_connect      => int, seconds, default 2

    .. php:const:: TIMEOUT_CONNECT

        Default connection timeout

    .. php:const:: TIMEOUT_SOCKET

        Default timeout for socket operations (reads, writes)

    .. php:const:: DEFAULT_RECEIVE_LENGTH

    .. php:const:: NAME_PART_IP

        Socket name parts

    .. php:attr:: scheme

        protected

    .. php:attr:: host

        protected

    .. php:attr:: port

        protected

    .. php:attr:: socket

        protected resource

    .. php:attr:: context

        protected

        Stream context

    .. php:attr:: connected

        protected boolean

        Whether the socket is connected to a server

        Note, the connection may not be ready to use, but the socket is connected
        at least. See $handshaked, and other properties in subclasses.

    .. php:attr:: firstRead

        protected boolean

        Whether the current read is the first one to the socket

    .. php:attr:: name

        protected string

        The socket name according to stream_socket_get_name

    .. php:attr:: options

        protected array

    .. php:attr:: protocol

        protected Protocol

    .. php:method:: configure($options)

        :param $options:

    .. php:method:: connect()

        Connects to the given socket

    .. php:method:: reconnect()

    .. php:method:: getSocketStreamContextOptions()

    .. php:method:: getSslStreamContextOptions()

    .. php:method:: __construct($uri, $options = array())

        URI Socket constructor

        :type $uri: string
        :param $uri: WebSocket URI, e.g. ws://example.org:8000/chat
        :param $options:

    .. php:method:: getUri()

        Gets the canonical/normalized URI for this socket

        :returns: string

    .. php:method:: getName()

    .. php:method:: getHost()

        Gets the host name

    .. php:method:: getPort()

    .. php:method:: getStreamContext($listen = false)

        Gets a stream context

        :param $listen:

    .. php:method:: getNamePart($name, $part)

        Gets part of the name of the socket

        PHP seems to return IPV6 address/port combos like this:
        ::1:1234, where ::1 is the address and 1234 the port So, the part number
        here is either the last : delimited section (the port)
        or all the other sections (the whole initial part, the address).

        :type $name: string
        :param $name: (from $this->getName() usually)
        :param $part:
        :returns: string

    .. php:method:: getIp()

        Gets the IP address of the socket

        :returns: string

    .. php:method:: getLastError()

        Get the last error that occurred on the socket

        :returns: int|string

    .. php:method:: isConnected()

        Whether the socket is currently connected

        :returns: boolean

    .. php:method:: disconnect()

        Disconnect the socket

        :returns: void

    .. php:method:: getResource()

    .. php:method:: getResourceId()

    .. php:method:: send($data)

        :type $data: unknown_type
        :param $data:
        :returns: boolean|int The number of bytes sent or false on error

    .. php:method:: receive($length = self::DEFAULT_RECEIVE_LENGTH)

        Recieve data from the socket

        :type $length: int
        :param $length:
        :returns: string

    .. php:method:: configureProtocol()

        Configures the protocol option


================================================
FILE: doc/source/api/Socket/ServerClientSocket.rst
================================================
----------------------------------
Wrench\\Socket\\ServerClientSocket
----------------------------------

.. php:namespace: Wrench\\Socket

.. php:class:: ServerClientSocket

    .. php:const:: TIMEOUT_SOCKET

        Default timeout for socket operations (reads, writes)

    .. php:const:: DEFAULT_RECEIVE_LENGTH

    .. php:const:: NAME_PART_IP

        Socket name parts

    .. php:attr:: socket

        protected resource

    .. php:attr:: context

        protected

        Stream context

    .. php:attr:: connected

        protected boolean

        Whether the socket is connected to a server

        Note, the connection may not be ready to use, but the socket is connected
        at least. See $handshaked, and other properties in subclasses.

    .. php:attr:: firstRead

        protected boolean

        Whether the current read is the first one to the socket

    .. php:attr:: name

        protected string

        The socket name according to stream_socket_get_name

    .. php:attr:: options

        protected array

    .. php:attr:: protocol

        protected Protocol

    .. php:method:: __construct($accepted_socket, $options = array())

        Constructor

        A server client socket is accepted from a listening socket, so there's no
        need to call ->connect() or whatnot.

        :type $accepted_socket: resource
        :param $accepted_socket:
        :type $options: array
        :param $options:

    .. php:method:: configure($options)

        Configure options

        Options include
        - timeout_connect      => int, seconds, default 2
        - timeout_socket       => int, seconds, default 5

        :type $options: array
        :param $options:
        :returns: void

    .. php:method:: getName()

        Gets the name of the socket

    .. php:method:: getNamePart($name, $part)

        Gets part of the name of the socket

        PHP seems to return IPV6 address/port combos like this:
        ::1:1234, where ::1 is the address and 1234 the port So, the part number
        here is either the last : delimited section (the port)
        or all the other sections (the whole initial part, the address).

        :type $name: string
        :param $name: (from $this->getName() usually)
        :param $part:
        :returns: string

    .. php:method:: getIp()

        Gets the IP address of the socket

        :returns: string

    .. php:method:: getPort()

        Gets the port of the socket

        :returns: int

    .. php:method:: getLastError()

        Get the last error that occurred on the socket

        :returns: int|string

    .. php:method:: isConnected()

        Whether the socket is currently connected

        :returns: boolean

    .. php:method:: disconnect()

        Disconnect the socket

        :returns: void

    .. php:method:: getResource()

    .. php:method:: getResourceId()

    .. php:method:: send($data)

        :type $data: unknown_type
        :param $data:
        :returns: boolean|int The number of bytes sent or false on error

    .. php:method:: receive($length = self::DEFAULT_RECEIVE_LENGTH)

        Recieve data from the socket

        :type $length: int
        :param $length:
        :returns: string

    .. php:method:: configureProtocol()

        Configures the protocol option


================================================
FILE: doc/source/api/Socket/ServerSocket.rst
================================================
----------------------------
Wrench\\Socket\\ServerSocket
----------------------------

.. php:namespace: Wrench\\Socket

.. php:class:: ServerSocket

    Server socket

    Used for a server's "master" socket that binds to the configured interface and listens

    .. php:const:: TIMEOUT_SOCKET

        Default timeout for socket operations (reads, writes)

    .. php:const:: DEFAULT_RECEIVE_LENGTH

    .. php:const:: NAME_PART_IP

        Socket name parts

    .. php:attr:: listening

        protected boolean

        Whether the socket is listening

    .. php:attr:: scheme

        protected

    .. php:attr:: host

        protected

    .. php:attr:: port

        protected

    .. php:attr:: socket

        protected resource

    .. php:attr:: context

        protected

        Stream context

    .. php:attr:: connected

        protected boolean

        Whether the socket is connected to a server

        Note, the connection may not be ready to use, but the socket is connected
        at least. See $handshaked, and other properties in subclasses.

    .. php:attr:: firstRead

        protected boolean

        Whether the current read is the first one to the socket

    .. php:attr:: name

        protected string

        The socket name according to stream_socket_get_name

    .. php:attr:: options

        protected array

    .. php:attr:: protocol

        protected Protocol

    .. php:method:: configure($options)

        :param $options:

    .. php:method:: listen()

        Listens

    .. php:method:: accept()

        Accepts a new connection on the socket

        :returns: resource

    .. php:method:: getSocketStreamContextOptions()

    .. php:method:: getSslStreamContextOptions()

    .. php:method:: __construct($uri, $options = array())

        URI Socket constructor

        :type $uri: string
        :param $uri: WebSocket URI, e.g. ws://example.org:8000/chat
        :param $options:

    .. php:method:: getUri()

        Gets the canonical/normalized URI for this socket

        :returns: string

    .. php:method:: getName()

    .. php:method:: getHost()

        Gets the host name

    .. php:method:: getPort()

    .. php:method:: getStreamContext($listen = false)

        Gets a stream context

        :param $listen:

    .. php:method:: getNamePart($name, $part)

        Gets part of the name of the socket

        PHP seems to return IPV6 address/port combos like this:
        ::1:1234, where ::1 is the address and 1234 the port So, the part number
        here is either the last : delimited section (the port)
        or all the other sections (the whole initial part, the address).

        :type $name: string
        :param $name: (from $this->getName() usually)
        :param $part:
        :returns: string

    .. php:method:: getIp()

        Gets the IP address of the socket

        :returns: string

    .. php:method:: getLastError()

        Get the last error that occurred on the socket

        :returns: int|string

    .. php:method:: isConnected()

        Whether the socket is currently connected

        :returns: boolean

    .. php:method:: disconnect()

        Disconnect the socket

        :returns: void

    .. php:method:: getResource()

    .. php:method:: getResourceId()

    .. php:method:: send($data)

        :type $data: unknown_type
        :param $data:
        :returns: boolean|int The number of bytes sent or false on error

    .. php:method:: receive($length = self::DEFAULT_RECEIVE_LENGTH)

        Recieve data from the socket

        :type $length: int
        :param $length:
        :returns: string

    .. php:method:: configureProtocol()

        Configures the protocol option


================================================
FILE: doc/source/api/Socket/Socket.rst
================================================
----------------------
Wrench\\Socket\\Socket
----------------------

.. php:namespace: Wrench\\Socket

.. php:class:: Socket

    Socket class

    Implements low level logic for connecting, serving, reading to, and writing from WebSocket connections using PHP's streams.

    Unlike in previous versions of this library, a Socket instance now represents a single underlying socket resource. It's designed to be used by aggregation, rather than inheritence.

    .. php:const:: TIMEOUT_SOCKET

        Default timeout for socket operations (reads, writes)

    .. php:const:: DEFAULT_RECEIVE_LENGTH

    .. php:const:: NAME_PART_IP

        Socket name parts

    .. php:attr:: socket

        protected resource

    .. php:attr:: context

        protected

        Stream context

    .. php:attr:: connected

        protected boolean

        Whether the socket is connected to a server

        Note, the connection may not be ready to use, but the socket is connected
        at least. See $handshaked, and other properties in subclasses.

    .. php:attr:: firstRead

        protected boolean

        Whether the current read is the first one to the socket

    .. php:attr:: name

        protected string

        The socket name according to stream_socket_get_name

    .. php:attr:: options

        protected array

    .. php:attr:: protocol

        protected Protocol

    .. php:method:: configure($options)

        Configure options

        Options include
        - timeout_connect      => int, seconds, default 2
        - timeout_socket       => int, seconds, default 5

        :type $options: array
        :param $options:
        :returns: void

    .. php:method:: getName()

        Gets the name of the socket

    .. php:method:: getNamePart($name, $part)

        Gets part of the name of the socket

        PHP seems to return IPV6 address/port combos like this:
        ::1:1234, where ::1 is the address and 1234 the port So, the part number
        here is either the last : delimited section (the port)
        or all the other sections (the whole initial part, the address).

        :type $name: string
        :param $name: (from $this->getName() usually)
        :param $part:
        :returns: string

    .. php:method:: getIp()

        Gets the IP address of the socket

        :returns: string

    .. php:method:: getPort()

        Gets the port of the socket

        :returns: int

    .. php:method:: getLastError()

        Get the last error that occurred on the socket

        :returns: int|string

    .. php:method:: isConnected()

        Whether the socket is currently connected

        :returns: boolean

    .. php:method:: disconnect()

        Disconnect the socket

        :returns: void

    .. php:method:: getResource()

    .. php:method:: getResourceId()

    .. php:method:: send($data)

        :type $data: unknown_type
        :param $data:
        :returns: boolean|int The number of bytes sent or false on error

    .. php:method:: receive($length = self::DEFAULT_RECEIVE_LENGTH)

        Recieve data from the socket

        :type $length: int
        :param $length:
        :returns: string

    .. php:method:: __construct($options = array())

        Configurable constructor

        :param $options:

    .. php:method:: configureProtocol()

        Configures the protocol option


================================================
FILE: doc/source/api/Socket/UriSocket.rst
================================================
-------------------------
Wrench\\Socket\\UriSocket
-------------------------

.. php:namespace: Wrench\\Socket

.. php:class:: UriSocket

    .. php:const:: TIMEOUT_SOCKET

        Default timeout for socket operations (reads, writes)

    .. php:const:: DEFAULT_RECEIVE_LENGTH

    .. php:const:: NAME_PART_IP

        Socket name parts

    .. php:attr:: scheme

        protected

    .. php:attr:: host

        protected

    .. php:attr:: port

        protected

    .. php:attr:: socket

        protected resource

    .. php:attr:: context

        protected

        Stream context

    .. php:attr:: connected

        protected boolean

        Whether the socket is connected to a server

        Note, the connection may not be ready to use, but the socket is connected
        at least. See $handshaked, and other properties in subclasses.

    .. php:attr:: firstRead

        protected boolean

        Whether the current read is the first one to the socket

    .. php:attr:: name

        protected string

        The socket name according to stream_socket_get_name

    .. php:attr:: options

        protected array

    .. php:attr:: protocol

        protected Protocol

    .. php:method:: __construct($uri, $options = array())

        URI Socket constructor

        :type $uri: string
        :param $uri: WebSocket URI, e.g. ws://example.org:8000/chat
        :param $options:

    .. php:method:: getUri()

        Gets the canonical/normalized URI for this socket

        :returns: string

    .. php:method:: getName()

    .. php:method:: getHost()

        Gets the host name

    .. php:method:: getPort()

    .. php:method:: getStreamContext($listen = false)

        Gets a stream context

        :param $listen:

    .. php:method:: getSocketStreamContextOptions()

        Returns an array of socket stream context options

        See http://php.net/manual/en/context.socket.php

        :returns: array

    .. php:method:: getSslStreamContextOptions()

        Returns an array of ssl stream context options

        See http://php.net/manual/en/context.ssl.php

        :returns: array

    .. php:method:: configure($options)

        Configure options

        Options include
        - timeout_connect      => int, seconds, default 2
        - timeout_socket       => int, seconds, default 5

        :type $options: array
        :param $options:
        :returns: void

    .. php:method:: getNamePart($name, $part)

        Gets part of the name of the socket

        PHP seems to return IPV6 address/port combos like this:
        ::1:1234, where ::1 is the address and 1234 the port So, the part number
        here is either the last : delimited section (the port)
        or all the other sections (the whole initial part, the address).

        :type $name: string
        :param $name: (from $this->getName() usually)
        :param $part:
        :returns: string

    .. php:method:: getIp()

        Gets the IP address of the socket

        :returns: string

    .. php:method:: getLastError()

        Get the last error that occurred on the socket

        :returns: int|string

    .. php:method:: isConnected()

        Whether the socket is currently connected

        :returns: boolean

    .. php:method:: disconnect()

        Disconnect the socket

        :returns: void

    .. php:method:: getResource()

    .. php:method:: getResourceId()

    .. php:method:: send($data)

        :type $data: unknown_type
        :param $data:
        :returns: boolean|int The number of bytes sent or false on error

    .. php:method:: receive($length = self::DEFAULT_RECEIVE_LENGTH)

        Recieve data from the socket

        :type $length: int
        :param $length:
        :returns: string

    .. php:method:: configureProtocol()

        Configures the protocol option


================================================
FILE: doc/source/api/Socket/index.rst
================================================
::::::::::::::
Wrench\\Socket
::::::::::::::

.. php:namespace: Wrench\\Socket

.. toctree::

   ClientSocket
   ServerClientSocket
   ServerSocket
   Socket
   UriSocket


================================================
FILE: doc/source/api/Util/Configurable.rst
================================================
--------------------------
Wrench\\Util\\Configurable
--------------------------

.. php:namespace: Wrench\\Util

.. php:class:: Configurable

    Configurable base class

    .. php:attr:: options

        protected array

    .. php:attr:: protocol

        protected Protocol

    .. php:method:: __construct($options = array())

        Configurable constructor

        :param $options:

    .. php:method:: configure($options)

        Configures the options

        :type $options: array
        :param $options:

    .. php:method:: configureProtocol()

        Configures the protocol option


================================================
FILE: doc/source/api/Util/Ssl.rst
================================================
-----------------
Wrench\\Util\\Ssl
-----------------

.. php:namespace: Wrench\\Util

.. php:class:: Ssl

    .. php:method:: generatePemFile($pem_file, $pem_passphrase, $country_name, $state_or_province_name, $locality_name, $organization_name, $organizational_unit_name, $common_name, $email_address)

        Generates a new PEM File given the informations

        :type $pem_file: string
        :param $pem_file: the path of the PEM file to create
        :type $pem_passphrase: string
        :param $pem_passphrase: the passphrase to protect the PEM file or if you don't want to use a passphrase
        :type $country_name: string
        :param $country_name: the country code of the new PEM file. e.g.: EN
        :type $state_or_province_name: string
        :param $state_or_province_name: the state or province name of the new PEM file
        :type $locality_name: string
        :param $locality_name: the name of the locality
        :param $organization_name:
        :param $organizational_unit_name:
        :param $common_name:
        :type $email_address: string
        :param $email_address: the email address


================================================
FILE: doc/source/api/Util/index.rst
================================================
::::::::::::
Wrench\\Util
::::::::::::

.. php:namespace: Wrench\\Util

.. toctree::

   Configurable
   Ssl


================================================
FILE: doc/source/api/index.rst
================================================
`````````````````
API Documentation
`````````````````

.. php:namespace: Wrench

.. toctree::

   Application/index
   BasicServer
   Client
   Connection
   ConnectionManager
   Exception/index
   Frame/index
   Listener/index
   Payload/index
   Protocol/index
   Resource
   Server
   Socket/index
   Util/index


================================================
FILE: doc/source/authors.rst
================================================
-------
Authors
-------

The original maintainer and author was `@nicokaiser
<https://github.com/nicokaiser>`_. Plentiful improvements were contributed by
`@lemmingzshadow <https://github.com/lemmingzshadow>`_ and `@mazhack
<https://github.com/mazhack>`_. Parts of the Socket class were written by
Moritz Wutz. The server is licensed under the WTFPL, a free software compatible
license.



================================================
FILE: doc/source/conf.py
================================================
# -*- coding: utf-8 -*-
#
# Wrench documentation build configuration file, created by
# sphinx-quickstart on Thu Jul 26 13:09:51 2012.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.

import sys, os
import sphinx.highlighting, pygments.lexers

# Highlight PHP code without <?php
sphinx.highlighting.lexers['php'] = pygments.lexers.PhpLexer(startinline = True)

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))

# -- General configuration -----------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'

# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinxcontrib.phpdomain']

# Primary domain
primary_domain = 'php'

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# The suffix of source filenames.
source_suffix = '.rst'

# The encoding of source files.
#source_encoding = 'utf-8-sig'

# The master toctree document.
master_doc = 'index'

# General information about the project.
project = u'Wrench'
copyright = u'2012, Dominic Scheirlinck and Contributors'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '2.0'
# The full version, including alpha/beta/rc tags.
release = '2.0.0-beta'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None

# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = []

# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
default_role = 'php:class'

# Default highlight language
highlight_language = 'php'

# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True

# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True

# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'

# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []


# -- Options for HTML output ---------------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
html_theme = 'default'

# Theme options are theme-specific and customize the look and feel of a theme
# further.  For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}

# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []

# The name for this set of Sphinx documents.  If None, it defaults to
# "<project> v<release> documentation".
#html_title = None

# A shorter title for the navigation bar.  Default is the same as html_title.
#html_short_title = None

# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None

# The name of an image file (within the static path) to use as favicon of the
# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'

# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True

# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}

# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}

# If false, no module index is generated.
#html_domain_indices = True

# If false, no index is generated.
#html_use_index = True

# If true, the index is split into individual pages for each letter.
#html_split_index = False

# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True

# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True

# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True

# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it.  The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''

# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None

# Output file base name for HTML help builder.
htmlhelp_basename = 'Wrench'


# -- Options for LaTeX output --------------------------------------------------

latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',

# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',

# Additional stuff for the LaTeX preamble.
#'preamble': '',
}

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
  ('index', 'Wrench.tex', u'Wrench Documentation',
   u'Dominic Scheirlinck and Contributors', 'manual'),
]

# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None

# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False

# If true, show page references after internal links.
#latex_show_pagerefs = False

# If true, show URL addresses after external links.
#latex_show_urls = False

# Documents to append as an appendix to all manuals.
#latex_appendices = []

# If false, no module index is generated.
#latex_domain_indices = True


# -- Options for manual page output --------------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
    ('index', 'wrench', u'Wrench Documentation',
     [u'Dominic Scheirlinck and Contributors'], 1)
]

# If true, show URL addresses after external links.
#man_show_urls = False


# -- Options for Texinfo output ------------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
  ('index', 'Wrench', u'Wrench Documentation',
   u'Dominic Scheirlinck and Contributors', 'Wrench', 'PHP WebSockets library.',
   'Miscellaneous'),
]

# Documents to append as an appendix to all manuals.
#texinfo_appendices = []

# If false, no module index is generated.
#texinfo_domain_indices = True

# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'


================================================
FILE: doc/source/getting-started.rst
================================================
.. vim: set tw=78 sw=4 ts=4 :

***************
Getting Started
***************

-----------------
Starting a Server
-----------------

The first thing you'll want to do to serve WebSockets from PHP is start a
WebSockets server. Wrench provides a simple Server class that implements the
most recent version of the WebSockts protocol. Subclassing the Server class is
encouraged: see WebSocket\BasicServer for an example.

When you're ready for your server to start responding to requests, call
$server->run()::

    use Wrench\BasicServer;

    $server = new BasicServer('ws://localhost:8000', array(
        'allowed_origins' => array(
            'mysite.com',
            'mysite.dev.localdomain'
        )
    ));

    // Register your applications

    $server->run();

--------------------------
Registering an Application
--------------------------

The server on its own doesn't do anything until you write an Application for
it. The server calls methods on your applications once they are registered::

    $server->registerApplication('echo', new \Wrench\Examples\EchoApplication());
    $server->registerApplication('chat', new \My\ChatApplication());


================================================
FILE: doc/source/index.rst
================================================
.. vim: set tw=78 sw=2 ts=2 :

======
Wrench
======

Wrench is a WebSockets library for PHP 5.3+

.. toctree::
   :maxdepth: 3

   introduction
   installing
   getting-started
   performance
   api/index
   authors



================================================
FILE: doc/source/installing.rst
================================================
.. vim: set tw=78 sw=4 ts=4 :

*****************
Installing Wrench
*****************

The library is PSR-0 compatible, with a vendor name of **Wrench**. An
SplClassLoader is bundled for convenience. The simplest possible bootstrap
looks like this::

    require_once 'SplClassLoader.php';

    $classLoader = new \SplClassLoader('Wrench', __DIR__ . '/../path/to/wrench/lib');
    $classLoader->register();

--------
composer
--------

Wrench is available on Packagist as `wrench/wrench <http://packagist.org/packages/wrench/wrench>`_.

Here's what it looks like in your :file:`composer.json`

.. code-block:: json

    {
        ...
        "require": {
            "wrench/wrench": "dev-master"
        }
    }

---------
deps file
---------

Using Symfony2 with a traditional style deps file? You can configure Wrench
like this:

.. code-block:: ini

    [wrench]
        git=git://github.com/varspool/Wrench.git
        version=origin/master


================================================
FILE: doc/source/introduction.rst
================================================
.. vim: set tw=78 sw=4 ts=4 :

************
Introduction
************

Wrench is a simple websocket server and client package for PHP 5.3/5.4, using
streams.

-------------
php-websocket
-------------

Wrench was previously known as php-websocket. Why the name change? See
`Frequently Asked Questions about the PHP License
<http://php.net/license/index.php#fac-lic>`_.  Also, the namespace WebSocket
is too generic; it denotes a common functionality, and may already be in use
by application code. The BC break of a new `major version
<http://semver.org/>`_ was a good time to introduce this move to best
practices.



================================================
FILE: doc/source/performance.rst
================================================
.. vim: set tw=78 sw=4 ts=4 :

***********
Performance
***********

Wrench uses a single-process server, without threads, and blocks while
processing data from any client. This means it has little hope of scaling in
production.

You might like to use some middleware between your PHP application code and
WebSocket clients in production. For example, you might use something like
`RabbitMQ's STOMP + WebSockets Plugin
<http://www.rabbitmq.com/blog/2012/05/14/introducing-rabbitmq-web-stomp/>`_. In
any case, if you're hoping to serve large numbers of clients, you should
probably look into one of the evented IO based servers.


================================================
FILE: doc/source/setup.py
================================================
#!/usr/bin/env python

from distutils.core import setup

setup(
        name='wrench-documentation',
        version='2.0.0',
        requires=[
            "sphinxcontrib.phpdomain"
        ]
     )


================================================
FILE: examples/StatusApplication.php
================================================
<?php
namespace Wrench\Application;

/**
 * Shiny WSS Status Application
 * Provides live server infos/messages to client/browser.
 *
 * @author Simon Samtleben <web@lemmingzshadow.net>
 */
class StatusApplication extends Application
{
    private $_clients           = array();
    private $_serverClients     = array();
    private $_serverInfo        = array();
    private $_serverClientCount = 0;


    public function onConnect($client)
    {
        $id = $client->getClientId();
        $this->_clients[$id] = $client;
        $this->_sendServerinfo($client);
    }

    public function onDisconnect($client)
    {
        $id = $client->getClientId();
        unset($this->_clients[$id]);
    }

    public function onData($data, $client)
    {
        // currently not in use...
    }

    public function setServerInfo($serverInfo)
    {
        if (is_array($serverInfo)) {
            $this->_serverInfo = $serverInfo;
            return true;
        }

        return false;
    }


    public function clientConnected($ip, $port)
    {
        $this->_serverClients[$port] = $ip;
        $this->_serverClientCount++;
        $this->statusMsg('Client connected: ' . $ip . ':' . $port);

        $data = array(
            'ip' => $ip,
            'port' => $port,
            'clientCount' => $this->_serverClientCount,
        );

        $encodedData = $this->_encodeData('clientConnected', $data);

        $this->_sendAll($encodedData);
    }

    public function clientDisconnected($ip, $port)
    {
        if (!isset($this->_serverClients[$port])) {
            return false;
        }

        unset($this->_serverClients[$port]);

        $this->_serverClientCount--;
        $this->statusMsg('Client disconnected: ' . $ip . ':' . $port);

        $data = array(
            'port' => $port,
            'clientCount' => $this->_serverClientCount,
        );

        $encodedData = $this->_encodeData('clientDisconnected', $data);

        $this->_sendAll($encodedData);
    }

    public function clientActivity($port)
    {
        $encodedData = $this->_encodeData('clientActivity', $port);
        $this->_sendAll($encodedData);
    }

    public function statusMsg($text, $type = 'info')
    {
        $data = array(
            'type' => $type,
            'text' => '[' . strftime('%m-%d %H:%M', time()) . '] ' . $text,
        );

        $encodedData = $this->_encodeData('statusMsg', $data);

        $this->_sendAll($encodedData);
    }

    private function _sendServerinfo($client)
    {
        if (count($this->_clients) < 1) {
            return false;
        }

        $currentServerInfo                = $this->_serverInfo;
        $currentServerInfo['clientCount'] = count($this->_serverClients);
        $currentServerInfo['clients']     = $this->_serverClients;
        $encodedData                      = $this->_encodeData('serverInfo', $currentServerInfo);

        $client->send($encodedData);
    }

    private function _sendAll($encodedData)
    {
        if (count($this->_clients) < 1) {
            return false;
        }

        foreach ($this->_clients as $sendto) {
            $sendto->send($encodedData);
        }
    }
}

================================================
FILE: examples/coffeescript/coffee/client.coffee
================================================
$(document).ready ->
  log = (msg) -> $('#log').append("#{msg}<br />")
  serverUrl = 'ws://127.0.0.1:8000/demo'
  if window.MozWebSocket
    socket = new MozWebSocket serverUrl
  else if window.WebSocket
    socket = new WebSocket serverUrl
  socket.binaryType = 'blob'

  socket.onopen = (msg) ->
    $('#status').removeClass().addClass('online').html('connected')

  socket.onmessage = (msg) ->
    response = JSON.parse(msg.data)
    log("Action: #{response.action}")
    log("Data: #{response.data}")

  socket.onclose = (msg) ->
    $('#status').removeClass().addClass('offline').html('disconnected')

  $('#status').click ->
    socket.close()

  $('#send').click ->
    payload = new Object()
    payload.action = $('#action').val()
    payload.data = $('#data').val()
    socket.send(JSON.stringify(payload))

  $('#sendfile').click ->
    data = document.binaryFrame.file.files[0]
    if data
      payload = new Object()
      payload.action = 'setFilename'
      payload.data = $('#file').val()
      socket.send JSON.stringify payload
      socket.send(data)
    return false

================================================
FILE: examples/coffeescript/coffee/status.coffee
================================================
$(document).ready ->
  log = (msg) -> $('#log').prepend("#{msg}<br />")
  serverUrl = 'ws://localhost:8000/status'
  if window.MozWebSocket
    socket = new MozWebSocket serverUrl
  else if window.WebSocket
    socket = new WebSocket serverUrl

  socket.onopen = (msg) ->
    $('#status').removeClass().addClass('online').html('connected')

  socket.onmessage = (msg) ->
    response = JSON.parse(msg.data)
    switch response.action
      when "statusMsg"      then statusMsg response.data
      when "clientConnected"    then clientConnected response.data
      when "clientDisconnected"  then clientDisconnected response.data
      when "clientActivity"    then clientActivity response.data
      when "serverInfo"      then refreshServerinfo response.data

  socket.onclose = (msg) ->
    $('#status').removeClass().addClass('offline').html('disconnected')

  $('#status').click ->
    socket.close()

  statusMsg = (msgData) ->
    switch msgData.type
      when "info" then log msgData.text
      when "warning" then log "<span class=\"warning\">#{msgData.text}</span>"

  clientConnected = (data) ->
    $('#clientListSelect').append(new Option("#{data.ip}:#{data.port}", data.port))
    $('#clientCount').text(data.clientCount)

  clientDisconnected = (data) ->
    $("#clientListSelect option[value='#{data.port}']").remove()
    $('#clientCount').text(data.clientCount)

  refreshServerinfo = (serverinfo) ->
    $('#clientCount').text(serverinfo.clientCount)
    $('#maxClients').text(serverinfo.maxClients)
    $('#maxConnections').text(serverinfo.maxConnectionsPerIp)
    $('#maxRequetsPerMinute').text(serverinfo.maxRequetsPerMinute)
    for port, ip of serverinfo.clients
      $('#clientListSelect').append(new Option(ip + ':' + port, port));

  clientActivity = (port) ->
    $("#clientListSelect option[value='#{port}']").css("color", "red").animate({opacity: 100}, 600, ->
      $(this).css("color", "black")
    )

================================================
FILE: examples/coffeescript/css/client.css
================================================
body {
	background: #f1f1f1;
	padding-top: 65px;
	text-align: center;
	font-family: Arial, Helvetica, sans-serif;
	text-align: center;
	font-size: 16px;
	line-height: 25px;
	color: #444;
}

a,
a:hover { 
	color: #169;
}

p {
	margin: 0;
	padding: 0 0 21px 0; 
}

#container {
	text-align: left;
	width: 580px;
	background: #fff;
	position: relative;
	margin: 0 auto;
	padding: 40px;
	border: 1px solid #ddd;
	border-radius: 10px;
		-moz-border-radius: 10px;
}

h1 {
	font-size: 30px;
	color: #333;
	font-weight: normal;
	margin: 0 0 20px 0;
	padding: 0;
	display: inline-block;
}
h2 {
	font-size: 16px;
	font-weight: bold;
	margin: 8px 0 0 0;
}

#log {
	margin: 6px 0 0 0;
	padding: 5px;
	border: 1px solid #ccc;
	height: 200px;
	overflow: auto;
}

#send {
	margin: 0 0 10px 0;
}

#status {
	float: right;
	padding: 0 10px;
	cursor: pointer;
	border-radius: 5px;
		-moz-border-radius: 5px;
}
.offline {
	background: #ddd;
	color: #000;
}
.online {
	background: #093;
	color: #fff;
}
.error {
	background: #930;
	color: #fff;
}
.connecting {
	background: #fc0;
	color: #000;
}

#action,
#data {
	display: inline-block;
	width: 200px;
	margin: 0 0 5px 0;
}
#file {
	display: inline-block;
	width: 410px;
	margin: 0 0 5px 0;
}

.bold {
	font-weight: bold;
}

================================================
FILE: examples/coffeescript/css/status.css
================================================
body {
	background: #f1f1f1;
	padding-top: 65px;
	text-align: center;
	font-family: Arial, Helvetica, sans-serif;
	text-align: center;
	font-size: 16px;
	line-height: 25px;
	color: #444;
}

a,
a:hover { 
	color: #169;
}
p {
	margin: 0;
	padding: 0;
}
#container {
	text-align: left;
	width: 900px;
	background: #fff;
	position: relative;
	margin: 0 auto;
	padding: 40px;
	border: 1px solid #ddd;
	border-radius: 10px;
		-moz-border-radius: 10px;
}

h1 {
	font-size: 30px;
	color: #333;
	font-weight: normal;
	margin: 0 0 20px 0;
	padding: 0;
	display: inline-block;
}
h2 {
	font-size: 16px;
	font-weight: bold;
	margin: 0;
}
#log {
	margin: 6px 0 0 0;
	padding: 5px;
	border: 1px solid #ccc;
	height: 200px;
	overflow: auto;
}

#send {
	margin: 0 0 10px 0;
}

#status {
	float: right;
	padding: 0 10px;
	cursor: pointer;
	border-radius: 5px;
		-moz-border-radius: 5px;
}
.offline {
	background: #ddd;
	color: #000;
}
.online {
	background: #093;
	color: #fff;
}
.error {
	background: #930;
	color: #fff;
}
.connecting {
	background: #fc0;
	color: #000;
}

#action,
#data {
	display: block;
	width: 400px;
	margin: 0 0 5px 0;
}

.bold {
	font-weight: bold;
}
#clientList {
	float: left;
	width: 300px;
}
#clientListSelect {
	width: 200px;
	height: 120px;
}

#serverInfo {
	float: left;
}

#console {
	margin-top: 20px;
}
#console .warning {
	color: #f00;
}

.clearer {
	clear: both;
}

================================================
FILE: examples/coffeescript/index.html
================================================
<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="css/client.css">

    <script src="js/jquery.min.js"></script>
    <script src="js/json2.js"></script>
    <script src="lib/coffeescript/jsmaker.php?f=client.coffee"></script>

    <meta charset=utf-8/>

    <title>Shiny WSS Demo Application</title>
</head>
<body>
<div id="container">
    <h1>Shiny WSS Demo Application</h1>
    <span id="status" class="offline">offline</span>

    <h2>Send Text Frame</h2>
    <input id="action" placeholder="action" type="text"/>
    <input id="data" placeholder="data" type="text"/>
    <button id="send">Send Text</button>

    <h2>Send Binary Frame</h2>

    <form name="binaryFrame" action="#">
        <input type="file" name="file" id="file">
        <button id="sendfile">Send Binary</button>
    </form>

    <h2>Server-Response</h2>

    <div id="log"></div>
</div>
</body>
</html>​

================================================
FILE: examples/coffeescript/status.html
================================================
<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="css/status.css">

    <script src="js/jquery.min.js"></script>
    <script src="js/json2.js"></script>
    <script src="lib/coffeescript/jsmaker.php?f=status.coffee"></script>

    <meta charset=utf-8/>

    <title>Shiny WSS Status</title>
</head>
<body>
<div id="container">
    <h1>Shiny WSS Status</h1>
    <span id="status" class="offline">disconnected</span>

    <div id="main">
        <div id="clientList">
            <h2>Clients:</h2>
            <select id="clientListSelect" multiple="multiple"></select>
        </div>

        <div id="serverInfo">
            <h2>Server Info:</h2>

            <p>Connected Clients: <span id="clientCount"></span></p>

            <p>Limit Clients: <span id="maxClients"></span></p>

            <p>Limit Connections/IP: <span id="maxConnections"></span></p>

            <p>Limit Requetes/Min: <span id="maxRequetsPerMinute"></span></p>
        </div>

        <div class="clearer"></div>

        <div id="console">
            <h2>Server Messages:</h2>

            <div id="log"></div>
        </div>
    </div>
</div>
</body>
</html>​

================================================
FILE: examples/server.pem
================================================
-----BEGIN CERTIFICATE-----
MIICsDCCAhmgAwIBAgIBADANBgkqhkiG9w0BAQQFADB1MQswCQYDVQQGEwJERTEN
MAsGA1UECAwEbm9uZTENMAsGA1UEBwwEbm9uZTENMAsGA1UECgwEbm9uZTENMAsG
A1UECwwEbm9uZTEPMA0GA1UEAwwGZm9vLmxoMRkwFwYJKoZIhvcNAQkBFgpiYXpA
Zm9vLmxoMB4XDTEyMDQwNzA5MzEwNVoXDTEzMDQwNzA5MzEwNVowdTELMAkGA1UE
BhMCREUxDTALBgNVBAgMBG5vbmUxDTALBgNVBAcMBG5vbmUxDTALBgNVBAoMBG5v
bmUxDTALBgNVBAsMBG5vbmUxDzANBgNVBAMMBmZvby5saDEZMBcGCSqGSIb3DQEJ
ARYKYmF6QGZvby5saDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA7CDQtHvJ
RE+sy2f3zKyGrMpffcf7fvbaEwT3tEpFpOJOp5qaq6JRc961O6v72++tr8iRVlfO
MGYV5JavKBe0PLzR+tHa/+eigcvjujFsPZqTP+8zkmkOKQIsKjmtpQBKYGgqcDDR
Jv7xYASVBl3/6LuIaD1hjk+r6DH7uqmcA2cCAwEAAaNQME4wHQYDVR0OBBYEFNH0
dPlR4RSosYd26yWaIvCeGN4kMB8GA1UdIwQYMBaAFNH0dPlR4RSosYd26yWaIvCe
GN4kMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAGeqrcS9tZ7kTYrEe
sT+iPtnqky8Sxu3znxkyjWKymDvELtc4gO17JaoFsQ+7PQBf22EzSgzuqlpk2gGa
pNaMwoS2o/q/Htm7KuGVP0yNEVCYAKNwutFynrn+pd87Pr/+Oq4ighvM8wEzLPl1
OKSgTOSRdr80EdoSzgBKDD8gyuw=
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,DE4E623117398BE5

2FRyRzTeOSijgSCcvnBChbJJHMHkhAlB8Sxbo4fxeAIKyTGx9lyVZTtGN/XVWviK
XDh/7rL5qZz0zJcHshMg1pypNsJ+dSfF3KigpXxHm3Fpb5GnCDj3UKVFxOWPwu2K
ro9RyUdEdOwou2o1TnYnimgEmF7pb1CJFtR/sN1lZ+J/XUh8wfbn2Obce9GCtXGB
P+nVJECELVqX9KgquT49PKpIvf9gLq0Npns5P1lMenR4KGUlCGhFqgnuevPBaHaQ
yRDQfl/qnCehiA59KpCBPyNBPn2hsfpsN+AcnTkt6zd8wWjQA4SlyI1koSxG6FE7
OjPYsAhpQRi5qVWDyp0jkZqnU42aCGe7CqXXsdOfZv1m0wWACAvxJzV5uWljk/aD
7+k/WcTHHsNF05FYD2eQOReQ75UnOvKF7EmDO0iSJ6NaH9kHg7bvCxPD2oQGMqU8
ISeHhnI7URcyUBJZnEBCC2eJW6R2m/mI78P1KpOoCg4YbdB/ByGCyqDl134cv243
Knja0TV5mmTkdXWnUdSAQX0RJpohfOGomYFeeN7TqoqZxQUfFGHNgQP3oNoEzYay
mMfvBk80TRuRD1UpEsg8f+4xw+F6L82rRnfLgNr7FKJYDSTpVsJ3L+xsmyP0hjNw
b10iH/iOd2RprzOZ4YS+LdLLhOBJ97BciBTm71j1h0yLQuGWVLdsrisiyb22luZp
jU5mF0+wLIxCVl+k/Ibk3UYbBlvGblJzVEOnR2BOf3P3C6Skvr2JvDP/74Si/ybI
idm+Igm+TnUQ2PIntjV0wkiJIEQY5XyDwt58TR99w2Y=
-----END RSA PRIVATE KEY-----


================================================
FILE: examples/server.php
================================================
#!/usr/bin/env php
<?php

/* This program is free software. It comes without any warranty, to
 * the extent permitted by applicable law. You can redistribute it
 * and/or modify it under the terms of the Do What The Fuck You Want
 * To Public License, Version 2, as published by Sam Hocevar. See
 * http://sam.zoy.org/wtfpl/COPYING for more details. */

ini_set('display_errors', 1);
error_reporting(E_ALL);

require(__DIR__ . '/../lib/SplClassLoader.php');

$classLoader = new SplClassLoader('Wrench', __DIR__ . '/../lib');
$classLoader->register();

$server = new \Wrench\Server('ws://localhost:8000/', array(
    'allowed_origins'            => array(
        'mysite.localhost'
    ),
// Optional defaults:
//     'check_origin'               => true,
//     'connection_manager_class'   => 'Wrench\ConnectionManager',
//     'connection_manager_options' => array(
//         'timeout_select'           => 0,
//         'timeout_select_microsec'  => 200000,
//         'socket_master_class'      => 'Wrench\Socket\ServerSocket',
//         'socket_master_options'    => array(
//             'backlog'                => 50,
//             'ssl_cert_file'          => null,
//             'ssl_passphrase'         => null,
//             'ssl_allow_self_signed'  => false,
//             'timeout_accept'         => 5,
//             'timeout_socket'         => 5,
//         ),
//         'connection_class'         => 'Wrench\Connection',
//         'connection_options'       => array(
//             'socket_class'           => 'Wrench\Socket\ServerClientSocket',
//             'socket_options'         => array(),
//             'connection_id_secret'   => 'asu5gj656h64Da(0crt8pud%^WAYWW$u76dwb',
//             'connection_id_algo'     => 'sha512'
//         )
//     )
));

$server->registerApplication('echo', new \Wrench\Application\EchoApplication());
$server->run();


================================================
FILE: examples/server_ssl.php
================================================
<?php
/* This program is free software. It comes without any warranty, to
 * the extent permitted by applicable law. You can redistribute it
 * and/or modify it under the terms of the Do What The Fuck You Want
 * To Public License, Version 2, as published by Sam Hocevar. See
 * http://sam.zoy.org/wtfpl/COPYING for more details. */

ini_set('display_errors', 1);
error_reporting(E_ALL);

require(__DIR__ . '/../lib/SplClassLoader.php');

$classLoader = new SplClassLoader('Wrench', __DIR__ . '/../lib');
$classLoader->register();

// Generate PEM file
$pemFile                = dirname(__FILE__) . '/generated.pem';
$pemPassphrase          = null;
$countryName            = "DE";
$stateOrProvinceName    = "none";
$localityName           = "none";
$organizationName       = "none";
$organizationalUnitName = "none";
$commonName             = "foo.lh";
$emailAddress           = "baz@foo.lh";

\Wrench\Socket::generatePEMFile(
    $pemFile,
    $pemPassphrase,
    $countryName,
    $stateOrProvinceName,
    $localityName,
    $organizationName,
    $organizationalUnitName,
    $commonName,
    $emailAddress
);

// User can use tls in place of ssl
$server = new \Wrench\Server('127.0.0.1', 8000, 'ssl', $pemFile, $pemPassphrase);

// server settings:
$server->setMaxClients(100);
$server->setCheckOrigin(true);
$server->setAllowedOrigin('foo.lh');
$server->setMaxConnectionsPerIp(100);
$server->setMaxRequestsPerMinute(2000);

// Hint: Status application should not be removed as it displays usefull server informations:
$server->registerApplication('status', \Wrench\Application\StatusApplication::getInstance());
$server->registerApplication('demo', \Wrench\Application\DemoApplication::getInstance());

$server->run();

================================================
FILE: lib/SplClassLoader.php
================================================
<?php

/**
 * SplClassLoader implementation that implements the technical interoperability
 * standards for PHP 5.3 namespaces and class names.
 *
 * http://groups.google.com/group/php-standards/web/final-proposal
 *
 *     // Example which loads classes for the Doctrine Common package in the
 *     // Doctrine\Common namespace.
 *     $classLoader = new SplClassLoader('Doctrine\Common', '/path/to/doctrine');
 *     $classLoader->register();
 *
 * @author Jonathan H. Wage <jonwage@gmail.com>
 * @author Roman S. Borschel <roman@code-factory.org>
 * @author Matthew Weier O'Phinney <matthew@zend.com>
 * @author Kris Wallsmith <kris.wallsmith@gmail.com>
 * @author Fabien Potencier <fabien.potencier@symfony-project.org>
 */
class SplClassLoader
{
    private $_fileExtension = '.php';
    private $_namespace;
    private $_includePath;
    private $_namespaceSeparator = '\\';

    /**
     * Creates a new <tt>SplClassLoader</tt> that loads classes of the
     * specified namespace.
     * 
     * @param string $ns The namespace to use.
     */
    public function __construct($ns = null, $includePath = null)
    {
        $this->_namespace = $ns;
        $this->_includePath = $includePath;
    }

    /**
     * Sets the namespace separator used by classes in the namespace of this class loader.
     * 
     * @param string $sep The separator to use.
     */
    public function setNamespaceSeparator($sep)
    {
        $this->_namespaceSeparator = $sep;
    }

    /**
     * Gets the namespace seperator used by classes in the namespace of this class loader.
     *
     * @return void
     */
    public function getNamespaceSeparator()
    {
        return $this->_namespaceSeparator;
    }

    /**
     * Sets the base include path for all class files in the namespace of this class loader.
     * 
     * @param string $includePath
     */
    public function setIncludePath($includePath)
    {
        $this->_includePath = $includePath;
    }

    /**
     * Gets the base include path for all class files in the namespace of this class loader.
     *
     * @return string $includePath
     */
    public function getIncludePath()
    {
        return $this->_includePath;
    }

    /**
     * Sets the file extension of class files in the namespace of this class loader.
     * 
     * @param string $fileExtension
     */
    public function setFileExtension($fileExtension)
    {
        $this->_fileExtension = $fileExtension;
    }

    /**
     * Gets the file extension of class files in the namespace of this class loader.
     *
     * @return string $fileExtension
     */
    public function getFileExtension()
    {
        return $this->_fileExtension;
    }

    /**
     * Installs this class loader on the SPL autoload stack.
     */
    public function register()
    {
        spl_autoload_register(array($this, 'loadClass'));
    }

    /**
     * Uninstalls this class loader from the SPL autoloader stack.
     */
    public function unregister()
    {
        spl_autoload_unregister(array($this, 'loadClass'));
    }

    /**
     * Loads the given class or interface.
     *
     * @param string $className The name of the class to load.
     * @return void
     */
    public function loadClass($className)
    {
        if (null === $this->_namespace || $this->_namespace.$this->_namespaceSeparator === substr($className, 0, strlen($this->_namespace.$this->_namespaceSeparator))) {
            $fileName = '';
            $namespace = '';
            if (false !== ($lastNsPos = strripos($className, $this->_namespaceSeparator))) {
                $namespace = substr($className, 0, $lastNsPos);
                $className = substr($className, $lastNsPos + 1);
                $fileName = str_replace($this->_namespaceSeparator, DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
            }
            $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . $this->_fileExtension;

            require ($this->_includePath !== null ? $this->_includePath . DIRECTORY_SEPARATOR : '') . $fileName;
        }
    }
}

================================================
FILE: lib/Wrench/Application/Application.php
================================================
<?php

namespace Wrench\Application;

/**
 * Wrench Server Application
 */
abstract class Application
{
    /**
     * Optional: handle a connection
     */
    // abstract public function onConnect($connection);

    /**
     * Optional: handle a disconnection
     *
     * @param
     */
	// abstract public function onDisconnect($connection);

    /**
     * Optional: allow the application to perform any tasks which will result in a push to clients
     */ 
    // abstract public function onUpdate();

    /**
     * Handle data received from a client
     *
     * @param Payload $payload A payload object, that supports __toString()
     * @param Connection $connection
     */
	abstract public function onData($payload, $connection);
}


================================================
FILE: lib/Wrench/Application/EchoApplication.php
================================================
<?php

namespace Wrench\Application;

use Wrench\Application\Application;
use Wrench\Application\NamedApplication;

/**
 * Example application for Wrench: echo server
 */
class EchoApplication extends Application
{
    /**
     * @see Wrench\Application.Application::onData()
     */
    public function onData($data, $client)
    {
        $client->send($data);
    }
}

================================================
FILE: lib/Wrench/Application/ServerTimeApplication.php
================================================
<?php

namespace Wrench\Application;

use Wrench\Application\Application;
use Wrench\Application\NamedApplication;

/**
 * Example application demonstrating how to use Application::onUpdate
 *
 * Pushes the server time to all clients every update tick.
 */
class ServerTimeApplication extends Application
{
    protected $clients = array();
    protected $lastTimestamp = null;

    /**
     * @see Wrench\Application.Application::onConnect()
     */
    public function onConnect($client)
    {
        $this->clients[] = $client;
    }

    /**
     * @see Wrench\Application.Application::onUpdate()
     */
    public function onUpdate()
    {
        // limit updates to once per second
        if(time() > $this->lastTimestamp) {
            $this->lastTimestamp = time();

            foreach ($this->clients as $sendto) {
                $sendto->send(date('d-m-Y H:i:s'));
            }
        }
    }
}


================================================
FILE: lib/Wrench/BasicServer.php
================================================
<?php

namespace Wrench;

use Wrench\Server;

class BasicServer extends Server
{
    protected $rateLimiter;
    protected $originPolicy;

    /**
     * Constructor
     *
     * @param string $uri
     * @param array $options
     */
    public function __construct($uri, array $options = array())
    {
        parent::__construct($uri, $options);

        $this->configureRateLimiter();
        $this->configureOriginPolicy();
    }

    /**
     * @see Wrench.Server::configure()
     */
    protected function configure(array $options)
    {
        $options = array_merge(array(
            'check_origin'        => true,
            'allowed_origins'     => array(),
            'origin_policy_class' => 'Wrench\Listener\OriginPolicy',
            'rate_limiter_class'  => 'Wrench\Listener\RateLimiter'
        ), $options);

        parent::configure($options);
    }

    protected function configureRateLimiter()
    {
        $class = $this->options['rate_limiter_class'];
        $this->rateLimiter = new $class();
        $this->rateLimiter->listen($this);
    }

    /**
     * Configures the origin policy
     */
    protected function configureOriginPolicy()
    {
        $class = $this->options['origin_policy_class'];
        $this->originPolicy = new $class($this->options['allowed_origins']);

        if ($this->options['check_origin']) {
            $this->originPolicy->listen($this);
        }
    }

    /**
     * Adds an allowed origin
     *
     * @param array $origin
     */
    public function addAllowedOrigin($origin)
    {
        $this->originPolicy->addAllowedOrigin($origin);
    }
}

================================================
FILE: lib/Wrench/Client.php
================================================
<?php

namespace Wrench;

use Wrench\Payload\Payload;

use Wrench\Payload\PayloadHandler;

use Wrench\Util\Configurable;

use Wrench\Socket\ClientSocket;
use Wrench\Protocol\Protocol;
use Wrench\Protocol\Rfc6455Protocol;

use \InvalidArgumentException;
use \RuntimeException;

/**
 * Client class
 *
 * Represents a Wrench client
 */
class Client extends Configurable
{
    /**
     * @var int bytes
     */
    const MAX_HANDSHAKE_RESPONSE = '1500';

    /**
     * @var string
     */
    protected $uri;

    /**
     * @var string
     */
    protected $origin;

    /**
     * @var ClientSocket
     */
    protected $socket;

    /**
     * Request headers
     *
     * @var array
     */
    protected $headers = array();

    /**
     * Whether the client is connected
     *
     * @var boolean
     */
    protected $connected = false;

    /**
     * @var PayloadHandler
     */
    protected $payloadHandler = null;

    /**
     * Complete received payloads
     *
     * @var array<Payload>
     */
    protected $received = array();

    /**
     * Constructor
     *
     * @param string $uri
     * @param string $origin  The origin to include in the handshake (required
     *                          in later versions of the protocol)
     * @param array  $options (optional) Array of options
     *                         - socket   => Socket instance (otherwise created)
     *                         - protocol => Protocol
     */
    public function __construct($uri, $origin, array $options = array())
    {
        parent::__construct($options);

        $uri = (string)$uri;
        if (!$uri) {
            throw new InvalidArgumentException('No URI specified');
        }
        $this->uri = $uri;

        $origin = (string)$origin;
        if (!$origin) {
            throw new InvalidArgumentException('No origin specified');
        }
        $this->origin = $origin;

        $this->protocol->validateUri($this->uri);
        $this->protocol->validateOriginUri($this->origin);

        $this->configureSocket();
        $this->configurePayloadHandler();
    }

    /**
     * Configure options
     *
     * @param array $options
     * @return void
     */
    protected function configure(array $options)
    {
        $options = array_merge(array(
            'socket_class'     => 'Wrench\\Socket\\ClientSocket',
            'on_data_callback' => null
        ), $options);

        parent::configure($options);
    }

    /**
     * Configures the client socket
     */
    protected function configureSocket()
    {
        $class = $this->options['socket_class'];
        $this->socket = new $class($this->uri);
    }

    /**
     * Configures the payload handler
     */
    protected function configurePayloadHandler()
    {
        $this->payloadHandler = new PayloadHandler(array($this, 'onData'), $this->options);
    }

    /**
     * Payload receiver
     *
     * Public because called from our PayloadHandler. Don't call us, we'll call
     * you (via the on_data_callback option).
     *
     * @param Payload $payload
     */
    public function onData(Payload $payload)
    {
        $this->received[] = $payload;
        if (($callback = $this->options['on_data_callback'])) {
            call_user_func($callback, $payload);
        }
    }

    /**
     * Adds a request header to be included in the initial handshake
     *
     * For example, to include a Cookie header
     *
     * @param string $name
     * @param string $value
     * @return void
     */
    public function addRequestHeader($name, $value)
    {
        $this->headers[$name] = $value;
    }

    /**
     * Sends data to the socket
     *
     * @param string $data
     * @param string $type Payload type
     * @param boolean $masked
     * @return boolean Success
     */
    public function sendData($data, $type = Protocol::TYPE_TEXT, $masked = true)
    {
        if (is_string($type) && isset(Protocol::$frameTypes[$type])) {
            $type = Protocol::$frameTypes[$type];
        }

        $payload = $this->protocol->getPayload();

        $payload->encode(
            $data,
            $type,
            $masked
        );

        return $payload->sendToSocket($this->socket);
    }

    /**
     * Receives data sent by the server
     *
     * @param callable $callback
     * @return array<Payload> Payload received since the last call to receive()
     */
    public function receive()
    {
        if (!$this->isConnected()) {
            return false;
        }

        $data = $this->socket->receive();

        if (!$data) {
            return $data;
        }

        $old = $this->received;
        $this->payloadHandler->handle($data);
        return array_diff($this->received, $old);
    }

    /**
     * Connect to the Wrench server
     *
     * @return boolean Whether a new connection was made
     */
    public function connect()
    {
        if ($this->isConnected()) {
            return false;
        }

        $this->socket->connect();

        $key       = $this->protocol->generateKey();
        $handshake = $this->protocol->getRequestHandshake(
            $this->uri,
            $key,
            $this->origin,
            $this->headers
        );

        $this->socket->send($handshake);
        $response = $this->socket->receive(self::MAX_HANDSHAKE_RESPONSE);
        return ($this->connected =
                    $this->protocol->validateResponseHandshake($response, $key));
    }

    /**
     * Whether the client is currently connected
     *
     * @return boolean
     */
    public function isConnected()
    {
        return $this->connected;
    }

    /**
     * @todo Bug: what if connect has been called twice. The first socket never
     *        gets closed.
     */
    public function disconnect()
    {
        if ($this->socket) {
            $this->socket->disconnect();
        }
        $this->connected = false;
    }
}


================================================
FILE: lib/Wrench/Connection.php
================================================
<?php

namespace Wrench;

use Wrench\Payload\PayloadHandler;

use Wrench\Protocol\Protocol;

use Wrench\Payload\Payload;

use Wrench\Util\Configurable;
use Wrench\Socket\ServerClientSocket;
use Wrench\Server;
use Wrench\Exception as WrenchException;
use Wrench\Exception\CloseException;
use Wrench\Exception\ConnectionException;
use Wrench\Exception\HandshakeException;
use Wrench\Exception\BadRequestException;

use \Exception;
use \RuntimeException;

/**
 * Represents a client connection on the server side
 *
 * i.e. the `Server` manages a bunch of `Connection`s
 */
class Connection extends Configurable
{
    /**
     * The connection manager
     *
     * @var Wrench\ConnectionManager
     */
    protected $manager;

    /**
     * Socket object
     *
     * Wraps the client connection resource
     *
     * @var ServerClientSocket
     */
    protected $socket;

    /**
     * Whether the connection has successfully handshaken
     *
     * @var boolean
     */
    protected $handshaked = false;

    /**
     * The application this connection belongs to
     *
     * @var Application
     */
    protected $application = null;

    /**
     * The IP address of the client
     *
     * @var string
     */
    protected $ip;

    /**
     * The port of the client
     *
     * @var int
     */
    protected $port;

    /**
     * Connection ID
     *
     * @var string|null
     */
    protected $id = null;

    /**
     * @var PayloadHandler
     */
    protected $payloadHandler;

    /**
     * Constructor
     *
     * @param Server $server
     * @param ServerClientSocket $socket
     * @param array $options
     * @throws InvalidArgumentException
     */
    public function __construct(
        ConnectionManager $manager,
        ServerClientSocket $socket,
        array $options = array()
    ) {
        $this->manager = $manager;
        $this->socket = $socket;


        parent::__construct($options);

        $this->configureClientInformation();
        $this->configurePayloadHandler();

        $this->log('Connected');
    }

    /**
     * Gets the connection manager of this connection
     *
     * @return \Wrench\ConnectionManager
     */
    public function getConnectionManager()
    {
        return $this->manager;
    }

    /**
     * @see Wrench\Util.Configurable::configure()
     */
    protected function configure(array $options)
    {
        $options = array_merge(array(
            'connection_id_secret' => 'asu5gj656h64Da(0crt8pud%^WAYWW$u76dwb',
            'connection_id_algo'   => 'sha512',
        ), $options);

        parent::configure($options);
    }

    protected function configurePayloadHandler()
    {
        $this->payloadHandler = new PayloadHandler(
            array($this, 'handlePayload'),
            $this->options
        );
    }

    /**
     * @throws RuntimeException
     */
    protected function configureClientInformation()
    {
        $this->ip = $this->socket->getIp();
        $this->port = $this->socket->getPort();
        $this->configureClientId();
    }

    /**
     * Configures the client ID
     *
     * We hash the client ID to prevent leakage of information if another client
     * happens to get a hold of an ID. The secret *must* be lengthy, and must
     * be kept secret for this to work: otherwise it's trivial to search the space
     * of possible IP addresses/ports (well, if not trivial, at least very fast).
     */
    protected function configureClientId()
    {
        $message = sprintf(
            '%s:uri=%s&ip=%s&port=%s',
            $this->options['connection_id_secret'],
            rawurlencode($this->manager->getUri()),
            rawurlencode($this->ip),
            rawurlencode($this->port)
        );

        $algo = $this->options['connection_id_algo'];

        if (extension_loaded('gmp')) {
            $hash = hash($algo, $message, true);
            $hash = gmp_strval(gmp_init($hash, 16), 62);
        } else {
            // @codeCoverageIgnoreStart
            $hash = hash($algo, $message);
            // @codeCoverageIgnoreEnd
        }

        $this->id = $hash;
    }

    /**
     * Data receiver
     *
     * Called by the connection manager when the connection has received data
     *
     * @param string $data
     */
    public function onData($data)
    {
        if (!$this->handshaked) {
            return $this->handshake($data);
        }
        return $this->handle($data);
    }

    /**
     * Performs a websocket handshake
     *
     * @param string $data
     * @throws BadRequestException
     * @throws HandshakeException
     * @throws WrenchException
     */
    public function handshake($data)
    {
        try {
            list($path, $origin, $key, $extensions)
                = $this->protocol->validateRequestHandshake($data);

            $this->application = $this->manager->getApplicationForPath($path);
            if (!$this->application) {
                throw new BadRequestException('Invalid application');
            }

            $this->manager->getServer()->notify(
                Server::EVENT_HANDSHAKE_REQUEST,
                array($this, $path, $origin, $key, $extensions)
            );

            $response = $this->protocol->getResponseHandshake($key);

            if (!$this->socket->isConnected()) {
                throw new HandshakeException('Socket is not connected');
            }

            if ($this->socket->send($response) === false) {
                throw new HandshakeException('Could not send handshake response');
            }

            $this->handshaked = true;

            $this->log(sprintf(
                'Handshake successful: %s:%d (%s) connected to %s',
                $this->getIp(),
                $this->getPort(),
                $this->getId(),
                $path
            ), 'info');

            $this->manager->getServer()->notify(
                Server::EVENT_HANDSHAKE_SUCCESSFUL,
                array($this)
            );

            if (method_exists($this->application, 'onConnect')) {
                $this->application->onConnect($this);
            }
        } catch (WrenchException $e) {
            $this->log('Handshake failed: ' . $e, 'err');
            $this->close($e);
        }
    }

    /**
     * Returns a string export of the given binary data
     *
     * @param string $data
     * @return string
     */
    protected function export($data)
    {
        $export = '';
        foreach (str_split($data) as $chr) {
            $export .= '\\x' . ord($chr);
        }
    }

    /**
     * Handle data received from the client
     *
     * The data passed in may belong to several different frames across one or
     * more protocols. It may not even contain a single complete frame. This method
     * manages slotting the data into separate payload objects.
     *
     * @todo An endpoint MUST be capable of handling control frames in the
     *        middle of a fragmented message.
     * @param string $data
     * @return void
     */
    public function handle($data)
    {
        $this->payloadHandler->handle($data);
    }

    /**
     * Handle a complete payload received from the client
     *
     * Public because called from our PayloadHandler
     *
     * @param string $payload
     */
    public function handlePayload(Payload $payload)
    {
        $app = $this->getClientApplication();

        $this->log('Handling payload: ' . $payload->getPayload(), 'debug');

        switch ($type = $payload->getType()) {
            case Protocol::TYPE_TEXT:
                if (method_exists($app, 'onData')) {
                    $app->onData($payload, $this);
                }
                return;

            case Protocol::TYPE_BINARY:
                if(method_exists($app, 'onBinaryData')) {
                    $app->onBinaryData($payload, $this);
                } else {
                    $this->close(1003);
                }
            break;

            case Protocol::TYPE_PING:
                $this->log('Ping received', 'notice');
                $this->send($payload->getPayload(), Protocol::TYPE_PONG);
                $this->log('Pong!', 'debug');
            break;

            /**
             * A Pong frame MAY be sent unsolicited.  This serves as a
             * unidirectional heartbeat.  A response to an unsolicited Pong
             * frame is not expected.
             */
            case Protocol::TYPE_PONG:
                $this->log('Received unsolicited pong', 'info');
            break;

            case Protocol::TYPE_CLOSE:
                $this->log('Close frame received', 'notice');
                $this->close();
                $this->log('Disconnected', 'info');
            break;

            default:
                throw new ConnectionException('Unhandled payload type');
        }
    }

    /**
     * Sends the payload to the connection
     *
     * @param string $payload
     * @param string $type
     * @throws HandshakeException
     * @throws ConnectionException
     * @return boolean
     */
    public function send($data, $type = Protocol::TYPE_TEXT)
    {
        if (!$this->handshaked) {
            throw new HandshakeException('Connection is not handshaked');
        }

        $payload = $this->protocol->getPayload();

        // Servers don't send masked payloads
        $payload->encode($data, $type, false);

        if (!$payload->sendToSocket($this->socket)) {
            $this->log('Could not send payload to client', 'warn');
            throw new ConnectionException('Could not send data to connection: ' . $this->socket->getLastError());
        }

        return true;
    }

    /**
     * Processes data on the socket
     *
     * @throws CloseException
     */
    public function process()
    {
        $data = $this->socket->receive();
        $bytes = strlen($data);

        if ($bytes === 0 || $data === false) {
            throw new CloseException('Error reading data from socket: ' . $this->socket->getLastError());
        }

        $this->onData($data);
    }

    /**
     * Closes the connection according to the WebSocket protocol
     *
     * If an endpoint receives a Close frame and that endpoint did not
     * previously send a Close frame, the endpoint MUST send a Close frame
     * in response.  It SHOULD do so as soon as is practical.  An endpoint
     * MAY delay sending a close frame until its current message is sent
     * (for instance, if the majority of a fragmented message is already
     * sent, an endpoint MAY send the remaining fragments before sending a
     * Close frame).  However, there is no guarantee that the endpoint which
     * has already sent a Close frame will continue to process data.

     * After both sending and receiving a close message, an endpoint
     * considers the WebSocket connection closed, and MUST close the
     * underlying TCP connection.  The server MUST close the underlying TCP
     * connection immediately; the client SHOULD wait for the server to
     * close the connection but MAY close the connection at any time after
     * sending and receiving a close message, e.g. if it has not received a
     * TCP close from the server in a reasonable time period.
     *
     * @param int|Exception $statusCode
     * @return boolean
     */
    public function close($code = Protocol::CLOSE_NORMAL)
    {
        try {
            if (!$this->handshaked) {
                $response = $this->protocol->getResponseError($code);
                $this->socket->send($response);
            } else {
                $response = $this->protocol->getCloseFrame($code);
                $this->socket->send($response);
            }
        } catch (Exception $e) {
            $this->log('Unable to send close message', 'warning');
        }

        if ($this->application && method_exists($this->application, 'onDisconnect')) {
            $this->application->onDisconnect($this);
        }

        $this->socket->disconnect();
        $this->manager->removeConnection($this);
    }

    /**
     * Logs a message
     *
     * @param string $message
     * @param string $priority
     */
    public function log($message, $priority = 'info')
    {
        $this->manager->log(sprintf(
            '%s: %s:%d (%s): %s',
            __CLASS__,
            $this->getIp(),
            $this->getPort(),
            $this->getId(),
            $message
        ), $priority);
    }

    /**
     * Gets the IP address of the connection
     *
     * @return string Usually dotted quad notation
     */
    public function getIp()
    {
        return $this->ip;
    }

    /**
     * Gets the port of the connection
     *
     * @return int
     */
    public function getPort()
    {
        return $this->port;
    }

    /**
     * Gets the connection ID
     *
     * @return string
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Gets the socket object
     *
     * @return Socket\ServerClientSocket
     */
    public function getSocket()
    {
        return $this->socket;
    }

    /**
     * Gets the client application
     *
     * @return Application
     */
    public function getClientApplication()
    {
        return (isset($this->application)) ? $this->application : false;
    }
}


================================================
FILE: lib/Wrench/ConnectionManager.php
================================================
<?php

namespace Wrench;

use Wrench\Protocol\Protocol;
use Wrench\Resource;
use Wrench\Util\Configurable;
use Wrench\Exception\Exception as WrenchException;
use Wrench\Exception\CloseException;
use \Exception;
use \Countable;

class ConnectionManager extends Configurable implements Countable
{
    const TIMEOUT_SELECT          = 0;
    const TIMEOUT_SELECT_MICROSEC = 200000;

    /**
     * @var Server
     */
    protected $server;

    /**
     * Master socket
     *
     * @var Socket
     */
    protected $socket;

    /**
     * An array of client connections
     *
     * @var array<int => Connection>
     */
    protected $connections = array();

    /**
     * An array of raw socket resources, corresponding to connections, roughly
     *
     * @var array<int => resource>
     */
    protected $resources = array();

    /**
     * Constructor
     *
     * @param Server $server
     * @param array $options
     */
    public function __construct(Server $server, array $options = array())
    {
        $this->server = $server;

        parent::__construct($options);
    }

    /**
     * @see Countable::count()
     */
    public function count()
    {
        return count($this->connections);
    }

    /**
     * @see Wrench\Socket.Socket::configure()
     *   Options include:
     *     - timeout_select          => int, seconds, default 0
     *     - timeout_select_microsec => int, microseconds (NB: not milli), default: 200000
     */
    protected function configure(array $options)
    {
        $options = array_merge(array(
            'socket_master_class'     => 'Wrench\Socket\ServerSocket',
            'socket_master_options'   => array(),
            'socket_client_class'     => 'Wrench\Socket\ServerClientSocket',
            'socket_client_options'   => array(),
            'connection_class'        => 'Wrench\Connection',
            'connection_options'      => array(),
            'timeout_select'          => self::TIMEOUT_SELECT,
            'timeout_select_microsec' => self::TIMEOUT_SELECT_MICROSEC
        ), $options);

        parent::configure($options);

        $this->configureMasterSocket();
    }

    /**
     * Gets the application associated with the given path
     *
     * @param string $path
     */
    public function getApplicationForPath($path)
    {
        $path = ltrim($path, '/');
        return $this->server->getApplication($path);
    }

    /**
     * Configures the main server socket
     *
     * @param string $uri
     */
    protected function configureMasterSocket()
    {
        $class   = $this->options['socket_master_class'];
        $options = $this->options['socket_master_options'];
        $this->socket = new $class($this->server->getUri(), $options);
    }

    /**
     * Listens on the main socket
     *
     * @return void
     */
    public function listen()
    {
        $this->socket->listen();
        $this->resources[$this->socket->getResourceId()] = $this->socket->getResource();
    }

    /**
     * Gets all resources
     *
     * @return array<int => resource)
     */
    protected function getAllResources()
    {
        return array_merge($this->resources, array(
            $this->socket->getResourceId() => $this->socket->getResource()
        ));
    }

    /**
     * Returns the Connection associated with the specified socket resource
     *
     * @param resource $socket
     * @return Connection
     */
    protected function getConnectionForClientSocket($socket)
    {
        if (!isset($this->connections[$this->resourceId($socket)])) {
            return false;
        }
        return $this->connections[$this->resourceId($socket)];
    }

    /**
     * Select and process an array of resources
     *
     * @param array $resources
     */
    public function selectAndProcess()
    {
        $read             = $this->resources;
        $unused_write     = null;
        $unsued_exception = null;

        stream_select(
            $read,
            $unused_write,
            $unused_exception,
            $this->options['timeout_select'],
            $this->options['timeout_select_microsec']
        );

        foreach ($read as $socket) {
            if ($socket == $this->socket->getResource()) {
                $this->processMasterSocket();
            } else {
                $this->processClientSocket($socket);
            }
        }
    }

    /**
     * Process events on the master socket ($this->socket)
     *
     * @return void
     */
    protected function processMasterSocket()
    {
        $new = null;

        try {
            $new = $this->socket->accept();
        } catch (Exception $e) {
            $this->server->log('Socket error: ' . $e, 'err');
            return;
        }

        $connection = $this->createConnection($new);
        $this->server->notify(Server::EVENT_SOCKET_CONNECT, array($new, $connection));
    }

    /**
     * Creates a connection from a socket resource
     *
     * The create connection object is based on the options passed into the
     * constructor ('connection_class', 'connection_options'). This connection
     * instance and its associated socket resource are then stored in the
     * manager.
     *
     * @param resource $resource A socket resource
     * @return Connection
     */
    protected function createConnection($resource)
    {
        if (!$resource || !is_resource($resource)) {
            throw new InvalidArgumentException('Invalid connection resource');
        }

        $socket_class = $this->options['socket_client_class'];
        $socket_options = $this->options['socket_client_options'];

        $connection_class = $this->options['connection_class'];
        $connection_options = $this->options['connection_options'];

        $socket = new $socket_class($resource, $socket_options);
        $connection = new $connection_class($this, $socket, $connection_options);

        $id = $this->resourceId($resource);
        $this->resources[$id] = $resource;
        $this->connections[$id] = $connection;

        return $connection;
    }

    /**
     * Process events on a client socket
     *
     * @param resource $socket
     */
    protected function processClientSocket($socket)
    {
        $connection = $this->getConnectionForClientSocket($socket);

        if (!$connection) {
            $this->log('No connection for client socket', 'warning');
            return;
        }

        try {
            $connection->process();
        } catch (CloseException $e) {
            $this->log('Client connection closed: ' . $e, 'notice');
            $connection->close($e);
        } catch (WrenchException $e) {
            $this->log('Error on client socket: ' . $e, 'warning');
            $connection->close($e);
        }
    }

    /**
     * This server makes an explicit assumption: PHP resource types may be cast
     * to a integer. Furthermore, we assume this is bijective. Both seem to be
     * true in most circumstances, but may not be guaranteed.
     *
     * This method (and $this->getResourceId()) exist to make this assumption
     * explicit.
     *
     * This is needed on the connection manager as well as on resources
     *
     * @param resource $resource
     */
    protected function resourceId($resource)
    {
        return (int)$resource;
    }

    /**
     * Gets the connection manager's listening URI
     *
     * @return string
     */
    public function getUri()
    {
        return $this->server->getUri();
    }

    /**
     * Logs a message
     *
     * @param string $message
     * @param string $priority
     */
    public function log($message, $priority = 'info')
    {
        $this->server->log(sprintf(
            '%s: %s',
            __CLASS__,
            $message
        ), $priority);
    }

    /**
     * @return \Wrench\Server
     */
    public function getServer()
    {
        return $this->server;
    }

    /**
     * Removes a connection
     *
     * @param Connection $connection
     */
    public function removeConnection(Connection $connection)
    {
        $socket = $connection->getSocket();

        if ($socket->getResource()) {
            $index = $socket->getResourceId();
        } else {
            $index = array_search($connection, $this->connections);
        }

        if (!$index) {
            $this->log('Could not remove connection: not found', 'warning');
        }

        unset($this->connections[$index]);
        unset($this->resources[$index]);

        $this->server->notify(
            Server::EVENT_SOCKET_DISCONNECT,
            array($connection->getSocket(), $connection)
        );
    }
}


================================================
FILE: lib/Wrench/Exception/BadRequestException.php
================================================
<?php

namespace Wrench\Exception;

use Wrench\Protocol\Protocol;
use Wrench\Exception\HandshakeException;

class BadRequestException extends HandshakeException
{
    /**
     * @param string    $message
     * @param int       $code
     * @param Exception $previous
     */
    public function __construct($message = null, $code = null, $previous = null)
    {
        if ($code == null) {
            $code = Protocol::HTTP_BAD_REQUEST;
        }
        parent::__construct($message, $code, $previous);
    }
}

================================================
FILE: lib/Wrench/Exception/CloseException.php
================================================
<?php

namespace Wrench\Exception;

use Wrench\Protocol\Protocol;
use Wrench\Exception\Exception as WrenchException;

/**
 * Close connection exception
 */
class CloseException extends WrenchException
{
    /**
     * @param string    $message
     * @param int       $code
     * @param Exception $previous
     */
    public function __construct($message = null, $code = null, $previous = null)
    {
        if ($code == null) {
            $code = Protocol::CLOSE_UNEXPECTED;
        }
        parent::__construct($message, $code, $previous);
    }
}

================================================
FILE: lib/Wrench/Exception/ConnectionException.php
================================================
<?php

namespace Wrench\Exception;

class ConnectionException extends Exception
{
}

================================================
FILE: lib/Wrench/Exception/Exception.php
================================================
<?php

namespace Wrench\Exception;

class Exception extends \Exception
{
}

================================================
FILE: lib/Wrench/Exception/FrameException.php
================================================
<?php
namespace Wrench\Exception;

use Wrench\Exception\Exception as WrenchException;

class FrameException extends WrenchException
{
}


================================================
FILE: lib/Wrench/Exception/HandshakeException.php
================================================
<?php

namespace Wrench\Exception;

use Wrench\Protocol\Protocol;
use Wrench\Exception\Exception as WrenchException;

class HandshakeException extends WrenchException
{
    /**
     * @param string    $message
     * @param int       $code
     * @param Exception $previous
     */
    public function __construct($message = null, $code = null, $previous = null)
    {
        if ($code == null) {
            $code = Protocol::HTTP_SERVER_ERROR;
        }
        parent::__construct($message, $code, $previous);
    }
}

================================================
FILE: lib/Wrench/Exception/InvalidOriginException.php
================================================
<?php

namespace Wrench\Exception;

use Wrench\Protocol\Protocol;
use Wrench\Exception\HandshakeException;

/**
 * Invalid origin exception
 */
class InvalidOriginException extends HandshakeException
{
    /**
     * @param string    $message
     * @param int       $code
     * @param Exception $previous
     */
    public function __construct($message = null, $code = null, $previous = null)
    {
        if ($code == null) {
            $code = Protocol::HTTP_FORBIDDEN;
        }
        parent::__construct($message, $code, $previous);
    }
}


================================================
FILE: lib/Wrench/Exception/PayloadException.php
================================================
<?php
namespace Wrench\Exception;

use Wrench\Exception\Exception as WrenchException;

class PayloadException extends WrenchException
{
}


================================================
FILE: lib/Wrench/Exception/RateLimiterException.php
================================================
<?php
namespace Wrench\Exception;

use Wrench\Exception\Exception as WrenchException;

class RateLimiterException extends WrenchException
{
    /**
     * @param string    $message
     * @param int       $code
     * @param Exception $previous
     */
    public function __construct($message = null, $code = null, $previous = null)
    {
        if ($code == null) {
            $code = Protocol::CLOSE_GOING_AWAY;
        }
        parent::__construct($message, $code, $previous);
    }
}


================================================
FILE: lib/Wrench/Exception/SocketException.php
================================================
<?php
namespace Wrench\Exception;

use Wrench\Exception\Exception as WrenchException;

class SocketException extends WrenchException
{
}


================================================
FILE: lib/Wrench/Frame/Frame.php
================================================
<?php

namespace Wrench\Frame;

use Wrench\Payload\Payload;

use Wrench\Exception\FrameException;

/**
 * Represents a WebSocket frame
 */
abstract class Frame
{
    /**
     * The frame data length
     *
     * @var int
     */
    protected $length = null;

    /**
     * The type of this payload
     *
     * @var int
     */
    protected $type = null;

    /**
     * The buffer
     *
     * May not be a complete payload, because this frame may still be receiving
     * data. See
     *
     * @var string
     */
    protected $buffer = '';

    /**
     * The enclosed frame payload
     *
     * May not be a complete payload, because this frame might indicate a continuation
     * frame. See isFinal() versus isComplete()
     *
     * @var string
     */
    protected $payload = '';

    /**
     * Gets the length of the payload
     *
     * @throws FrameException
     * @return int
     */
    abstract public function getLength();

    /**
     * Resets the frame and encodes the given data into it
     *
     * @param string $data
     * @param int $type
     * @param boolean $masked
     * @return Frame
     */
    abstract public function encode($data, $type = Protocol::TYPE_TEXT, $masked = false);

    /**
     * Whether the frame is the final one in a continuation
     *
     * @return boolean
     */
    abstract public function isFinal();

    /**
     * @return int
     */
    abstract public function getType();

    /**
     * Decodes a frame payload from the buffer
     *
     * @return void
     */
    abstract protected function decodeFramePayloadFromBuffer();

    /**
     * Gets the expected length of the buffer once all the data has been
     *  receieved
     *
     * @return int
     */
    abstract protected function getExpectedBufferLength();

    /**
     * Whether the frame is complete
     *
     * @return boolean
     */
    public function isComplete()
    {
        if (!$this->buffer) {
            return false;
        }

        try {
            return $this->getBufferLength() >= $this->getExpectedBufferLength();
        } catch (FrameException $e) {
            return false;
        }
    }

    /**
     * Receieves data into the frame
     *
     * @param string $buffer
     */
    public function receiveData($data)
    {
        $this->buffer .= $data;
    }

    /**
     * Gets the remaining number of bytes before this frame will be complete
     *
     * @return number
     */
    public function getRemainingData()
    {
        try {
            return $this->getExpectedBufferLength() - $this->getBufferLength();
        } catch (FrameException $e) {
            return null;
        }
    }

    /**
     * Whether this frame is waiting for more data
     *
     * @return boolean
     */
    public function isWaitingForData()
    {
        return $this->getRemainingData() > 0;
    }

    /**
     * Gets the contents of the frame payload
     *
     * The frame must be complete to call this method.
     *
     * @return string
     */
    public function getFramePayload()
    {
        if (!$this->isComplete()) {
            throw new FrameException('Cannot get payload: frame is not complete');
        }

        if (!$this->payload && $this->buffer) {
            $this->decodeFramePayloadFromBuffer();
        }

        return $this->payload;
    }

    /**
     * Gets the contents of the frame buffer
     *
     * This is the encoded value, receieved into the frame with recieveData().
     *
     * @throws FrameException
     * @return string binary
     */
    public function getFrameBuffer()
    {
        if (!$this->buffer && $this->payload) {
            throw new FrameException('Cannot get frame buffer');
        }
        return $this->buffer;
    }

    /**
     * Gets the expected length of the frame payload
     *
     * @return int
     */
    protected function getBufferLength()
    {
        return strlen($this->buffer);
    }
}


================================================
FILE: lib/Wrench/Frame/HybiFrame.php
================================================
<?php

namespace Wrench\Frame;

use Wrench\Protocol\Protocol;
use Wrench\Exception\FrameException;
use \InvalidArgumentException;

class HybiFrame extends Frame
{
    // First byte
    const BITFIELD_FINAL = 0x80;
    const BITFIELD_RSV1  = 0x40;
    const BITFIELD_RSV2  = 0x20;
    const BITFIELD_RSV3  = 0x10;
    const BITFIELD_TYPE  = 0x0f;

    // Second byte
    const BITFIELD_MASKED = 0x80;
    const BITFIELD_INITIAL_LENGTH = 0x7f;

    // The inital byte offset before
    const BYTE_HEADER = 0;
    const BYTE_MASKED = 1;
    const BYTE_INITIAL_LENGTH = 1;

    /**
     * Whether the payload is masked
     *
     * @var boolean
     */
    protected $masked = null;

    /**
     * Masking key
     *
     * @var string
     */
    protected $mask = null;

    /**
     * Byte offsets
     *
     * @var int
     */
    protected $offset_payload = null;
    protected $offset_mask = null;

    /**
     * @see Wrench\Frame.Frame::encode()
     *     ws-frame         = frame-fin           ; 1 bit in length
     *                        frame-rsv1          ; 1 bit in length
     *                        frame-rsv2          ; 1 bit in length
     *                        frame-rsv3          ; 1 bit in length
     *                        frame-opcode        ; 4 bits in length
     *                        frame-masked        ; 1 bit in length
     *                        frame-payload-length   ; either 7, 7+16,
     *                                               ; or 7+64 bits in
     *                                               ; length
     *                        [ frame-masking-key ]  ; 32 bits in length
     *                        frame-payload-data     ; n*8 bits in
     *                                               ; length, where
     *                                               ; n >= 0
     */
    public function encode($payload, $type = Protocol::TYPE_TEXT, $masked = false)
    {
        if (!is_int($type) || !in_array($type, Protocol::$frameTypes)) {
            throw new InvalidArgumentException('Invalid frame type');
        }

        $this->type = $type;
        $this->masked = $masked;
        $this->payload = $payload;
        $this->length = strlen($this->payload);
        $this->offset_mask = null;
        $this->offset_payload = null;

        $this->buffer = "\x00\x00";

        $this->buffer[self::BYTE_HEADER] = chr(
            (self::BITFIELD_TYPE & $this->type)
            | (self::BITFIELD_FINAL & PHP_INT_MAX)
        );

        $masked_bit = (self::BITFIELD_MASKED & ($this->masked ? PHP_INT_MAX : 0));

        if ($this->length <= 125) {
            $this->buffer[self::BYTE_INITIAL_LENGTH] = chr(
                (self::BITFIELD_INITIAL_LENGTH & $this->length) | $masked_bit
            );
        } elseif ($this->length <= 65536) {
            $this->buffer[self::BYTE_INITIAL_LENGTH] = chr(
                (self::BITFIELD_INITIAL_LENGTH & 126) | $masked_bit
            );
            $this->buffer .= pack('n', $this->length);
        } else {
            $this->buffer[self::BYTE_INITIAL_LENGTH] = chr(
                (self::BITFIELD_INITIAL_LENGTH & 127) | $masked_bit
            );

            if (PHP_INT_MAX > 2147483647) {
                $this->buffer .= pack('NN', $this->length >> 32, $this->length);
                // $this->buffer .= pack('I', $this->length);
            } else {
                $this->buffer .= pack('NN', 0, $this->length);
            }
        }

        if ($this->masked) {
            $this->mask = $this->generateMask();
            $this->buffer .= $this->mask;
            $this->buffer .= $this->mask($this->payload);
        } else {
            $this->buffer .= $this->payload;
        }

        $this->offset_mask = $this->getMaskOffset();
        $this->offset_payload = $this->getPayloadOffset();

        return $this;
    }

    /**
     * Masks/Unmasks the frame
     *
     * @param string $payload
     * @return string
     */
    protected function mask($payload)
    {
        $length = strlen($payload);
        $mask = $this->getMask();

        $unmasked = '';
        for ($i = 0; $i < $length; $i++) {
            $unmasked .= $payload[$i] ^ $mask[$i % 4];
        }

        return $unmasked;
    }

    /**
     * Masks a payload
     *
     * @param string $payload
     * @return string
     */
    protected function unmask($payload)
    {
        return $this->mask($payload);
    }

    public function receiveData($data)
    {
        if ($this->getBufferLength() <= self::BYTE_INITIAL_LENGTH) {
            $this->length = null;
            $this->offset_payload = null;
        }
        parent::receiveData($data);
    }

    /**
     * Gets the mask
     *
     * @throws FrameException
     * @return string
     */
    protected function getMask()
    {
        if (!isset($this->mask)) {
            if (!$this->isMasked()) {
                throw new FrameException('Cannot get mask: frame is not masked');
            }
            $this->mask = substr($this->buffer, $this->getMaskOffset(), $this->getMaskSize());
        }
        return $this->mask;
    }

    /**
     * Generates a suitable masking key
     *
     * @return string
     */
    protected function generateMask()
    {
        if (extension_loaded('openssl')) {
            return openssl_random_pseudo_bytes(4);
        } else {
            // SHA1 is 128 bit (= 16 bytes)
            // So we pack it into 32 bits
            return pack('N', sha1(spl_object_hash($this) . mt_rand(0, PHP_INT_MAX) . uniqid('', true), true));
        }
    }

    /**
     * Whether the frame is masked
     *
     * @return boolean
     */
    public function isMasked()
    {
        if (!isset($this->masked)) {
            if (!isset($this->buffer[1])) {
                throw new FrameException('Cannot tell if frame is masked: not enough frame data recieved');
            }
            $this->masked = (boolean)(ord($this->buffer[1]) & self::BITFIELD_MASKED);
        }
        return $this->masked;
    }

    /**
     * @see Wrench\Frame.Frame::getExpectedDataLength()
     */
    protected function getExpectedBufferLength()
    {
        return $this->getLength() + $this->getPayloadOffset();
    }

    /**
     * Gets the offset of the payload in the frame
     *
     * @return int
     */
    protected function getPayloadOffset()
    {
        if (!isset($this->offset_payload)) {
            $offset = $this->getMaskOffset();
            $offset += $this->getMaskSize();

            $this->offset_payload = $offset;
        }
        return $this->offset_payload;
    }

    /**
     * Gets the offset in the frame to the masking bytes
     *
     * @return int
     */
    protected function getMaskOffset()
    {
        if (!isset($this->offset_mask)) {
            $offset = self::BYTE_INITIAL_LENGTH + 1;
            $offset += $this->getLengthSize();

            $this->offset_mask = $offset;
        }
        return $this->offset_mask;
    }

    /**
     * @see Wrench\Frame.Frame::getLength()
     */
    public function getLength()
    {
        if (!$this->length) {
            $initial = $this->getInitialLength();

            if ($initial < 126) {
                $this->length = $initial;
            } elseif ($initial >= 126) {
                // Extended payload length: 2 or 8 bytes
                $start = self::BYTE_INITIAL_LENGTH + 1;
                $end = self::BYTE_INITIAL_LENGTH + $this->getLengthSize();

                if ($end > $this->getBufferLength()) {
                    throw new FrameException('Cannot get extended length: need more data');
                }

                $length = 0;
                for ($i = $start; $i <= $end; $i++) {
                    $length <<= 8;
                    $length  += ord($this->buffer[$i]);
                }

                $this->length = $length;
            }
        }
        return $this->length;
    }

    /**
     * Gets the inital length value, stored in the first length byte
     *
     * This determines how the rest of the length value is parsed out of the
     * frame.
     *
     * @return int
     */
    protected function getInitialLength()
    {
        if (!isset($this->buffer[self::BYTE_INITIAL_LENGTH])) {
            throw new FrameException('Cannot yet tell expected length');
        }
        $a = (int)(ord($this->buffer[self::BYTE_INITIAL_LENGTH]) & self::BITFIELD_INITIAL_LENGTH);

        return (int)(ord($this->buffer[self::BYTE_INITIAL_LENGTH]) & self::BITFIELD_INITIAL_LENGTH);
    }

    /**
     * Returns the byte size of the length part of the frame
     *
     * Not including the initial 7 bit part
     *
     * @return int
     */
    protected function getLengthSize()
    {
        $initial = $this->getInitialLength();

        if ($initial < 126) {
            return 0;
        } elseif ($initial === 126) {
            return 2;
        } elseif ($initial === 127) {
            return 8;
        }
    }

    /**
     * Returns the byte size of the mask part of the frame
     *
     * @return int
     */
    protected function getMaskSize()
    {
        if ($this->isMasked()) {
            return 4;
        }
        return 0;
    }

    /**
     * @see Wrench\Frame.Frame::decodeFramePayloadFromBuffer()
     */
    protected function decodeFramePayloadFromBuffer()
    {
        $payload = substr($this->buffer, $this->getPayloadOffset());

        if ($this->isMasked()) {
            $payload = $this->unmask($payload);
        }

        $this->payload = $payload;
    }

    /**
     * @see Wrench\Frame.Frame::isFinal()
     */
    public function isFinal()
    {
        if (!isset($this->buffer[self::BYTE_HEADER])) {
            throw new FrameException('Cannot yet tell if frame is final');
        }
        return (boolean)(ord($this->buffer[self::BYTE_HEADER]) & self::BITFIELD_FINAL);
    }

    /**
     * @throws FrameException
     * @see Wrench\Frame.Frame::getType()
     */
    public function getType()
    {
        if (!isset($this->buffer[self::BYTE_HEADER])) {
            throw new FrameException('Cannot yet tell type of frame');
        }

        $type = (int)(ord($this->buffer[self::BYTE_HEADER]) & self::BITFIELD_TYPE);

        if (!in_array($type, Protocol::$frameTypes)) {
            throw new FrameException('Invalid payload type');
        }

        return $type;
    }
}

================================================
FILE: lib/Wrench/Listener/HandshakeRequestListener.php
================================================
<?php

namespace Wrench\Listener;

use Wrench\Connection;

interface HandshakeRequestListener
{
    /**
     * Handshake request listener
     *
     * @param Connection $connection
     * @param string $path
     * @param string $origin
     * @param string $key
     * @param array $extensions
     */
    public function onHandshakeRequest(Connection $connection, $path, $origin, $key, $extensions);
}

================================================
FILE: lib/Wrench/Listener/Listener.php
================================================
<?php

namespace Wrench\Listener;

use Wrench\Server;

interface Listener
{
    public function listen(Server $server);
}

================================================
FILE: lib/Wrench/Listener/OriginPolicy.php
================================================
<?php

namespace Wrench\Listener;

use Wrench\Connection;
use Wrench\Exception\InvalidOriginException;
use Wrench\Server;

class OriginPolicy implements Listener, Ha
Download .txt
gitextract_kle3fe4a/

├── .gitignore
├── .travis
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── TODO.md
├── VERSION
├── composer.json
├── doc/
│   ├── Makefile
│   ├── requirements.txt
│   └── source/
│       ├── api/
│       │   ├── Application/
│       │   │   ├── Application.rst
│       │   │   ├── EchoApplication.rst
│       │   │   └── index.rst
│       │   ├── BasicServer.rst
│       │   ├── Client.rst
│       │   ├── Connection.rst
│       │   ├── ConnectionManager.rst
│       │   ├── Exception/
│       │   │   ├── BadRequestException.rst
│       │   │   ├── CloseException.rst
│       │   │   ├── ConnectionException.rst
│       │   │   ├── Exception.rst
│       │   │   ├── FrameException.rst
│       │   │   ├── HandshakeException.rst
│       │   │   ├── InvalidOriginException.rst
│       │   │   ├── PayloadException.rst
│       │   │   ├── RateLimiterException.rst
│       │   │   ├── SocketException.rst
│       │   │   └── index.rst
│       │   ├── Frame/
│       │   │   ├── Frame.rst
│       │   │   ├── HybiFrame.rst
│       │   │   └── index.rst
│       │   ├── Listener/
│       │   │   ├── HandshakeRequestListener.rst
│       │   │   ├── Listener.rst
│       │   │   ├── OriginPolicy.rst
│       │   │   ├── RateLimiter.rst
│       │   │   └── index.rst
│       │   ├── Payload/
│       │   │   ├── HybiPayload.rst
│       │   │   ├── Payload.rst
│       │   │   └── index.rst
│       │   ├── Protocol/
│       │   │   ├── Hybi10Protocol.rst
│       │   │   ├── HybiProtocol.rst
│       │   │   ├── Protocol.rst
│       │   │   ├── Rfc6455Protocol.rst
│       │   │   └── index.rst
│       │   ├── Resource.rst
│       │   ├── Server.rst
│       │   ├── Socket/
│       │   │   ├── ClientSocket.rst
│       │   │   ├── ServerClientSocket.rst
│       │   │   ├── ServerSocket.rst
│       │   │   ├── Socket.rst
│       │   │   ├── UriSocket.rst
│       │   │   └── index.rst
│       │   ├── Util/
│       │   │   ├── Configurable.rst
│       │   │   ├── Ssl.rst
│       │   │   └── index.rst
│       │   └── index.rst
│       ├── authors.rst
│       ├── conf.py
│       ├── getting-started.rst
│       ├── index.rst
│       ├── installing.rst
│       ├── introduction.rst
│       ├── performance.rst
│       └── setup.py
├── examples/
│   ├── StatusApplication.php
│   ├── coffeescript/
│   │   ├── coffee/
│   │   │   ├── client.coffee
│   │   │   └── status.coffee
│   │   ├── css/
│   │   │   ├── client.css
│   │   │   └── status.css
│   │   ├── index.html
│   │   └── status.html
│   ├── server.pem
│   ├── server.php
│   └── server_ssl.php
├── lib/
│   ├── SplClassLoader.php
│   └── Wrench/
│       ├── Application/
│       │   ├── Application.php
│       │   ├── EchoApplication.php
│       │   └── ServerTimeApplication.php
│       ├── BasicServer.php
│       ├── Client.php
│       ├── Connection.php
│       ├── ConnectionManager.php
│       ├── Exception/
│       │   ├── BadRequestException.php
│       │   ├── CloseException.php
│       │   ├── ConnectionException.php
│       │   ├── Exception.php
│       │   ├── FrameException.php
│       │   ├── HandshakeException.php
│       │   ├── InvalidOriginException.php
│       │   ├── PayloadException.php
│       │   ├── RateLimiterException.php
│       │   └── SocketException.php
│       ├── Frame/
│       │   ├── Frame.php
│       │   └── HybiFrame.php
│       ├── Listener/
│       │   ├── HandshakeRequestListener.php
│       │   ├── Listener.php
│       │   ├── OriginPolicy.php
│       │   └── RateLimiter.php
│       ├── Payload/
│       │   ├── HybiPayload.php
│       │   ├── Payload.php
│       │   └── PayloadHandler.php
│       ├── Protocol/
│       │   ├── Hybi10Protocol.php
│       │   ├── HybiProtocol.php
│       │   ├── Protocol.php
│       │   └── Rfc6455Protocol.php
│       ├── Resource.php
│       ├── Server.php
│       ├── Socket/
│       │   ├── ClientSocket.php
│       │   ├── ServerClientSocket.php
│       │   ├── ServerSocket.php
│       │   ├── Socket.php
│       │   └── UriSocket.php
│       ├── Tests/
│       │   ├── Application/
│       │   │   └── EchoApplicationTest.php
│       │   ├── BasicServerTest.php
│       │   ├── ClientTest.php
│       │   ├── ConnectionManagerTest.php
│       │   ├── ConnectionTest.php
│       │   ├── Frame/
│       │   │   ├── BaseSubclassFrameTest.php
│       │   │   ├── FrameTest.php
│       │   │   └── HybiFrameTest.php
│       │   ├── Listener/
│       │   │   ├── ListenerTest.php
│       │   │   ├── OriginPolicyTest.php
│       │   │   └── RateLimiterTest.php
│       │   ├── Payload/
│       │   │   ├── HybiPayloadTest.php
│       │   │   └── PayloadTest.php
│       │   ├── Protocol/
│       │   │   ├── ProtocolTest.php
│       │   │   └── Rfc6455ProtocolTest.php
│       │   ├── ServerTest.php
│       │   ├── ServerTestHelper.php
│       │   ├── Socket/
│       │   │   ├── ClientSocketTest.php
│       │   │   ├── ServerClientSocketTest.php
│       │   │   ├── ServerSocketTest.php
│       │   │   ├── SocketTest.php
│       │   │   └── UriSocketTest.php
│       │   ├── Test.php
│       │   ├── bootstrap.php
│       │   └── server.php
│       └── Util/
│           ├── Configurable.php
│           └── Ssl.php
└── phpunit.xml
Download .txt
SYMBOL INDEX (428 symbols across 64 files)

FILE: examples/StatusApplication.php
  class StatusApplication (line 10) | class StatusApplication extends Application
    method onConnect (line 18) | public function onConnect($client)
    method onDisconnect (line 25) | public function onDisconnect($client)
    method onData (line 31) | public function onData($data, $client)
    method setServerInfo (line 36) | public function setServerInfo($serverInfo)
    method clientConnected (line 47) | public function clientConnected($ip, $port)
    method clientDisconnected (line 64) | public function clientDisconnected($ip, $port)
    method clientActivity (line 85) | public function clientActivity($port)
    method statusMsg (line 91) | public function statusMsg($text, $type = 'info')
    method _sendServerinfo (line 103) | private function _sendServerinfo($client)
    method _sendAll (line 117) | private function _sendAll($encodedData)

FILE: lib/SplClassLoader.php
  class SplClassLoader (line 20) | class SplClassLoader
    method __construct (line 33) | public function __construct($ns = null, $includePath = null)
    method setNamespaceSeparator (line 44) | public function setNamespaceSeparator($sep)
    method getNamespaceSeparator (line 54) | public function getNamespaceSeparator()
    method setIncludePath (line 64) | public function setIncludePath($includePath)
    method getIncludePath (line 74) | public function getIncludePath()
    method setFileExtension (line 84) | public function setFileExtension($fileExtension)
    method getFileExtension (line 94) | public function getFileExtension()
    method register (line 102) | public function register()
    method unregister (line 110) | public function unregister()
    method loadClass (line 121) | public function loadClass($className)

FILE: lib/Wrench/Application/Application.php
  class Application (line 8) | abstract class Application
    method onData (line 33) | abstract public function onData($payload, $connection);

FILE: lib/Wrench/Application/EchoApplication.php
  class EchoApplication (line 11) | class EchoApplication extends Application
    method onData (line 16) | public function onData($data, $client)

FILE: lib/Wrench/Application/ServerTimeApplication.php
  class ServerTimeApplication (line 13) | class ServerTimeApplication extends Application
    method onConnect (line 21) | public function onConnect($client)
    method onUpdate (line 29) | public function onUpdate()

FILE: lib/Wrench/BasicServer.php
  class BasicServer (line 7) | class BasicServer extends Server
    method __construct (line 18) | public function __construct($uri, array $options = array())
    method configure (line 29) | protected function configure(array $options)
    method configureRateLimiter (line 41) | protected function configureRateLimiter()
    method configureOriginPolicy (line 51) | protected function configureOriginPolicy()
    method addAllowedOrigin (line 66) | public function addAllowedOrigin($origin)

FILE: lib/Wrench/Client.php
  class Client (line 23) | class Client extends Configurable
    method __construct (line 81) | public function __construct($uri, $origin, array $options = array())
    method configure (line 110) | protected function configure(array $options)
    method configureSocket (line 123) | protected function configureSocket()
    method configurePayloadHandler (line 132) | protected function configurePayloadHandler()
    method onData (line 145) | public function onData(Payload $payload)
    method addRequestHeader (line 162) | public function addRequestHeader($name, $value)
    method sendData (line 175) | public function sendData($data, $type = Protocol::TYPE_TEXT, $masked =...
    method receive (line 198) | public function receive()
    method connect (line 220) | public function connect()
    method isConnected (line 247) | public function isConnected()
    method disconnect (line 256) | public function disconnect()

FILE: lib/Wrench/Connection.php
  class Connection (line 28) | class Connection extends Configurable
    method __construct (line 94) | public function __construct(
    method getConnectionManager (line 116) | public function getConnectionManager()
    method configure (line 124) | protected function configure(array $options)
    method configurePayloadHandler (line 134) | protected function configurePayloadHandler()
    method configureClientInformation (line 145) | protected function configureClientInformation()
    method configureClientId (line 160) | protected function configureClientId()
    method onData (line 191) | public function onData($data)
    method handshake (line 207) | public function handshake($data)
    method export (line 263) | protected function export($data)
    method handle (line 283) | public function handle($data)
    method handlePayload (line 295) | public function handlePayload(Payload $payload)
    method send (line 351) | public function send($data, $type = Protocol::TYPE_TEXT)
    method process (line 375) | public function process()
    method close (line 410) | public function close($code = Protocol::CLOSE_NORMAL)
    method log (line 438) | public function log($message, $priority = 'info')
    method getIp (line 455) | public function getIp()
    method getPort (line 465) | public function getPort()
    method getId (line 475) | public function getId()
    method getSocket (line 485) | public function getSocket()
    method getClientApplication (line 495) | public function getClientApplication()

FILE: lib/Wrench/ConnectionManager.php
  class ConnectionManager (line 13) | class ConnectionManager extends Configurable implements Countable
    method __construct (line 50) | public function __construct(Server $server, array $options = array())
    method count (line 60) | public function count()
    method configure (line 71) | protected function configure(array $options)
    method getApplicationForPath (line 94) | public function getApplicationForPath($path)
    method configureMasterSocket (line 105) | protected function configureMasterSocket()
    method listen (line 117) | public function listen()
    method getAllResources (line 128) | protected function getAllResources()
    method getConnectionForClientSocket (line 141) | protected function getConnectionForClientSocket($socket)
    method selectAndProcess (line 154) | public function selectAndProcess()
    method processMasterSocket (line 182) | protected function processMasterSocket()
    method createConnection (line 208) | protected function createConnection($resource)
    method processClientSocket (line 235) | protected function processClientSocket($socket)
    method resourceId (line 267) | protected function resourceId($resource)
    method getUri (line 277) | public function getUri()
    method log (line 288) | public function log($message, $priority = 'info')
    method getServer (line 300) | public function getServer()
    method removeConnection (line 310) | public function removeConnection(Connection $connection)

FILE: lib/Wrench/Exception/BadRequestException.php
  class BadRequestException (line 8) | class BadRequestException extends HandshakeException
    method __construct (line 15) | public function __construct($message = null, $code = null, $previous =...

FILE: lib/Wrench/Exception/CloseException.php
  class CloseException (line 11) | class CloseException extends WrenchException
    method __construct (line 18) | public function __construct($message = null, $code = null, $previous =...

FILE: lib/Wrench/Exception/ConnectionException.php
  class ConnectionException (line 5) | class ConnectionException extends Exception

FILE: lib/Wrench/Exception/Exception.php
  class Exception (line 5) | class Exception extends \Exception

FILE: lib/Wrench/Exception/FrameException.php
  class FrameException (line 6) | class FrameException extends WrenchException

FILE: lib/Wrench/Exception/HandshakeException.php
  class HandshakeException (line 8) | class HandshakeException extends WrenchException
    method __construct (line 15) | public function __construct($message = null, $code = null, $previous =...

FILE: lib/Wrench/Exception/InvalidOriginException.php
  class InvalidOriginException (line 11) | class InvalidOriginException extends HandshakeException
    method __construct (line 18) | public function __construct($message = null, $code = null, $previous =...

FILE: lib/Wrench/Exception/PayloadException.php
  class PayloadException (line 6) | class PayloadException extends WrenchException

FILE: lib/Wrench/Exception/RateLimiterException.php
  class RateLimiterException (line 6) | class RateLimiterException extends WrenchException
    method __construct (line 13) | public function __construct($message = null, $code = null, $previous =...

FILE: lib/Wrench/Exception/SocketException.php
  class SocketException (line 6) | class SocketException extends WrenchException

FILE: lib/Wrench/Frame/Frame.php
  class Frame (line 12) | abstract class Frame
    method getLength (line 54) | abstract public function getLength();
    method encode (line 64) | abstract public function encode($data, $type = Protocol::TYPE_TEXT, $m...
    method isFinal (line 71) | abstract public function isFinal();
    method getType (line 76) | abstract public function getType();
    method decodeFramePayloadFromBuffer (line 83) | abstract protected function decodeFramePayloadFromBuffer();
    method getExpectedBufferLength (line 91) | abstract protected function getExpectedBufferLength();
    method isComplete (line 98) | public function isComplete()
    method receiveData (line 116) | public function receiveData($data)
    method getRemainingData (line 126) | public function getRemainingData()
    method isWaitingForData (line 140) | public function isWaitingForData()
    method getFramePayload (line 152) | public function getFramePayload()
    method getFrameBuffer (line 173) | public function getFrameBuffer()
    method getBufferLength (line 186) | protected function getBufferLength()

FILE: lib/Wrench/Frame/HybiFrame.php
  class HybiFrame (line 9) | class HybiFrame extends Frame
    method encode (line 65) | public function encode($payload, $type = Protocol::TYPE_TEXT, $masked ...
    method mask (line 129) | protected function mask($payload)
    method unmask (line 148) | protected function unmask($payload)
    method receiveData (line 153) | public function receiveData($data)
    method getMask (line 168) | protected function getMask()
    method generateMask (line 184) | protected function generateMask()
    method isMasked (line 200) | public function isMasked()
    method getExpectedBufferLength (line 214) | protected function getExpectedBufferLength()
    method getPayloadOffset (line 224) | protected function getPayloadOffset()
    method getMaskOffset (line 240) | protected function getMaskOffset()
    method getLength (line 254) | public function getLength()
    method getInitialLength (line 290) | protected function getInitialLength()
    method getLengthSize (line 307) | protected function getLengthSize()
    method getMaskSize (line 325) | protected function getMaskSize()
    method decodeFramePayloadFromBuffer (line 336) | protected function decodeFramePayloadFromBuffer()
    method isFinal (line 350) | public function isFinal()
    method getType (line 362) | public function getType()

FILE: lib/Wrench/Listener/HandshakeRequestListener.php
  type HandshakeRequestListener (line 7) | interface HandshakeRequestListener
    method onHandshakeRequest (line 18) | public function onHandshakeRequest(Connection $connection, $path, $ori...

FILE: lib/Wrench/Listener/Listener.php
  type Listener (line 7) | interface Listener
    method listen (line 9) | public function listen(Server $server);

FILE: lib/Wrench/Listener/OriginPolicy.php
  class OriginPolicy (line 9) | class OriginPolicy implements Listener, HandshakeRequestListener
    method __construct (line 13) | public function __construct(array $allowed)
    method onHandshakeRequest (line 29) | public function onHandshakeRequest(Connection $connection, $path, $ori...
    method isAllowed (line 42) | public function isAllowed($origin)
    method listen (line 69) | public function listen(Server $server)

FILE: lib/Wrench/Listener/RateLimiter.php
  class RateLimiter (line 8) | class RateLimiter extends Configurable implements Listener
    method __construct (line 36) | public function __construct(array $options = array())
    method configure (line 44) | protected function configure(array $options)
    method listen (line 58) | public function listen(Server $server)
    method onSocketConnect (line 84) | public function onSocketConnect($socket, $connection)
    method onSocketDisconnect (line 96) | public function onSocketDisconnect($socket, $connection)
    method onClientData (line 107) | public function onClientData($socket, $connection)
    method checkConnections (line 117) | protected function checkConnections($connection)
    method checkConnectionsPerIp (line 131) | protected function checkConnectionsPerIp($connection)
    method releaseConnection (line 159) | protected function releaseConnection($connection)
    method checkRequestsPerMinute (line 182) | protected function checkRequestsPerMinute($connection)
    method limit (line 209) | protected function limit($connection, $limit)
    method log (line 226) | public function log($message, $priority = 'info')

FILE: lib/Wrench/Payload/HybiPayload.php
  class HybiPayload (line 13) | class HybiPayload extends Payload
    method getFrame (line 18) | protected function getFrame()

FILE: lib/Wrench/Payload/Payload.php
  class Payload (line 17) | abstract class Payload
    method getCurrentFrame (line 31) | protected function getCurrentFrame()
    method getReceivingFrame (line 45) | protected function getReceivingFrame()
    method getFrame (line 65) | abstract protected function getFrame();
    method isComplete (line 72) | public function isComplete()
    method encode (line 86) | public function encode($data, $type = Protocol::TYPE_TEXT, $masked = f...
    method getRemainingData (line 107) | public function getRemainingData()
    method isWaitingForData (line 129) | public function isWaitingForData()
    method sendToSocket (line 138) | public function sendToSocket(Socket $socket)
    method receiveData (line 153) | public function receiveData($data)
    method getPayload (line 178) | public function getPayload()
    method __toString (line 192) | public function __toString()
    method getType (line 210) | public function getType()

FILE: lib/Wrench/Payload/PayloadHandler.php
  class PayloadHandler (line 13) | class PayloadHandler extends Configurable
    method __construct (line 32) | public function __construct($callback, array $options = array())
    method handle (line 48) | public function handle($data)
    method getCurrent (line 96) | public function getCurrent()
    method emit (line 106) | protected function emit(Payload $payload)

FILE: lib/Wrench/Protocol/Hybi10Protocol.php
  class Hybi10Protocol (line 10) | class Hybi10Protocol extends HybiProtocol
    method getVersion (line 17) | public function getVersion()
    method acceptsVersion (line 27) | public function acceptsVersion($version)

FILE: lib/Wrench/Protocol/HybiProtocol.php
  class HybiProtocol (line 15) | abstract class HybiProtocol extends Protocol
    method getPayload (line 20) | public function getPayload()

FILE: lib/Wrench/Protocol/Protocol.php
  class Protocol (line 17) | abstract class Protocol
    method getVersion (line 233) | abstract public function getVersion();
    method acceptsVersion (line 242) | abstract public function acceptsVersion($version);
    method getPayload (line 250) | abstract public function getPayload();
    method generateKey (line 260) | public function generateKey()
    method getRequestHandshake (line 290) | public function getRequestHandshake(
    method getResponseHandshake (line 325) | public function getResponseHandshake($key, array $headers = array())
    method getResponseError (line 343) | public function getResponseError($e, array $headers = array())
    method getHttpResponse (line 366) | protected function getHttpResponse($status, array $headers = array())
    method validateResponseHandshake (line 392) | public function validateResponseHandshake($response, $key)
    method getEncodedHash (line 424) | public function getEncodedHash($key)
    method validateRequestHandshake (line 435) | public function validateRequestHandshake(
    method getCloseFrame (line 507) | public function getCloseFrame($e)
    method validateUri (line 533) | public function validateUri($uri)
    method validateSocketUri (line 568) | public function validateSocketUri($uri)
    method validateOriginUri (line 598) | public function validateOriginUri($origin)
    method validateRequestLine (line 624) | protected function validateRequestLine($line)
    method getAcceptValue (line 644) | protected function getAcceptValue($encoded_key)
    method getHeaders (line 656) | protected function getHeaders($response, &$request_line = null)
    method getRequestHeaders (line 694) | protected function getRequestHeaders($response)
    method validateScheme (line 715) | protected function validateScheme($scheme)
    method getDefaultRequestHeaders (line 741) | protected function getDefaultRequestHeaders($host, $key, $origin)
    method getSuccessResponseHeaders (line 758) | protected function getSuccessResponseHeaders($key)
    method getPort (line 777) | protected function getPort($scheme)

FILE: lib/Wrench/Protocol/Rfc6455Protocol.php
  class Rfc6455Protocol (line 12) | class Rfc6455Protocol extends HybiProtocol
    method getVersion (line 19) | public function getVersion()
    method acceptsVersion (line 29) | public function acceptsVersion($version)

FILE: lib/Wrench/Resource.php
  type Resource (line 8) | interface Resource
    method getResourceId (line 10) | public function getResourceId();
    method getResource (line 11) | public function getResource();

FILE: lib/Wrench/Server.php
  class Server (line 23) | class Server extends Configurable
    method __construct (line 92) | public function __construct($uri, array $options = array())
    method configure (line 113) | protected function configure(array $options)
    method configureLogger (line 131) | protected function configureLogger()
    method configureConnectionManager (line 147) | protected function configureConnectionManager()
    method getConnectionManager (line 159) | public function getConnectionManager()
    method getUri (line 167) | public function getUri()
    method setLogger (line 178) | public function setLogger($logger)
    method run (line 191) | public function run()
    method log (line 225) | public function log($message, $priority = 'info')
    method notify (line 237) | public function notify($event, array $arguments = array())
    method addListener (line 260) | public function addListener($event, $callback)
    method getApplication (line 279) | public function getApplication($key)
    method registerApplication (line 299) | public function registerApplication($key, $application)

FILE: lib/Wrench/Socket/ClientSocket.php
  class ClientSocket (line 10) | class ClientSocket extends UriSocket
    method configure (line 28) | protected function configure(array $options)
    method connect (line 42) | public function connect()
    method reconnect (line 73) | public function reconnect()
    method getSocketStreamContextOptions (line 82) | protected function getSocketStreamContextOptions()
    method getSslStreamContextOptions (line 91) | protected function getSslStreamContextOptions()

FILE: lib/Wrench/Socket/ServerClientSocket.php
  class ServerClientSocket (line 7) | class ServerClientSocket extends Socket
    method __construct (line 18) | public function __construct($accepted_socket, array $options = array())

FILE: lib/Wrench/Socket/ServerSocket.php
  class ServerSocket (line 15) | class ServerSocket extends UriSocket
    method configure (line 37) | protected function configure(array $options)
    method listen (line 55) | public function listen()
    method accept (line 82) | public function accept()
    method getSocketStreamContextOptions (line 99) | protected function getSocketStreamContextOptions()
    method getSslStreamContextOptions (line 113) | protected function getSslStreamContextOptions()

FILE: lib/Wrench/Socket/Socket.php
  class Socket (line 23) | abstract class Socket extends Configurable implements Resource
    method configure (line 91) | protected function configure(array $options)
    method getName (line 103) | protected function getName()
    method getNamePart (line 124) | public static function getNamePart($name, $part)
    method getIp (line 152) | public function getIp()
    method getPort (line 168) | public function getPort()
    method getLastError (line 184) | public function getLastError()
    method isConnected (line 205) | public function isConnected()
    method disconnect (line 215) | public function disconnect()
    method getResource (line 227) | public function getResource()
    method getResourceId (line 235) | public function getResourceId()
    method send (line 245) | public function send($data)
    method receive (line 276) | public function receive($length = self::DEFAULT_RECEIVE_LENGTH)

FILE: lib/Wrench/Socket/UriSocket.php
  class UriSocket (line 9) | abstract class UriSocket extends Socket
    method __construct (line 31) | public function __construct($uri, array $options = array())
    method getUri (line 44) | protected function getUri()
    method getName (line 58) | protected function getName()
    method getHost (line 66) | public function getHost()
    method getPort (line 74) | public function getPort()
    method getStreamContext (line 82) | protected function getStreamContext($listen = false)
    method getSocketStreamContextOptions (line 108) | abstract protected function getSocketStreamContextOptions();
    method getSslStreamContextOptions (line 117) | abstract protected function getSslStreamContextOptions();

FILE: lib/Wrench/Tests/Application/EchoApplicationTest.php
  class EchoApplicationTest (line 8) | class EchoApplicationTest extends WrenchTest
    method getClass (line 13) | protected function getClass()
    method testConstructor (line 21) | public function testConstructor()
    method testOnData (line 30) | public function testOnData($payload)
    method getValidPayloads (line 50) | public function getValidPayloads()

FILE: lib/Wrench/Tests/BasicServerTest.php
  class BasicServerTest (line 16) | class BasicServerTest extends ServerTest
    method getClass (line 21) | protected function getClass()
    method testValidOriginPolicy (line 31) | public function testValidOriginPolicy(array $allowed, $origin)
    method testInvalidOriginPolicy (line 58) | public function testInvalidOriginPolicy(array $allowed, $origin)
    method getValidConstructorArguments (line 83) | public function getValidConstructorArguments()
    method getValidOrigins (line 98) | public function getValidOrigins()
    method getInvalidOrigins (line 111) | public function getInvalidOrigins()

FILE: lib/Wrench/Tests/ClientTest.php
  class ClientTest (line 17) | class ClientTest extends Test
    method getClass (line 22) | protected function getClass()
    method testConstructor (line 27) | public function testConstructor()
    method getMockSocket (line 50) | protected function getMockSocket()
    method testConstructorSocketUnspecified (line 58) | public function testConstructorSocketUnspecified()
    method testConstructorUriInvalid (line 66) | public function testConstructorUriInvalid()
    method testConstructorUriEmpty (line 74) | public function testConstructorUriEmpty()
    method testConstructorUriPathUnspecified (line 82) | public function testConstructorUriPathUnspecified()
    method testConstructorOriginUnspecified (line 90) | public function testConstructorOriginUnspecified()
    method testConstructorOriginEmpty (line 98) | public function testConstructorOriginEmpty()
    method testConstructorOriginInvalid (line 106) | public function testConstructorOriginInvalid()
    method testSendInvalidType (line 114) | public function testSendInvalidType()
    method testSendInvalidTypeString (line 123) | public function testSendInvalidTypeString()
    method testSend (line 129) | public function testSend()

FILE: lib/Wrench/Tests/ConnectionManagerTest.php
  class ConnectionManagerTest (line 16) | class ConnectionManagerTest extends Test
    method getClass (line 21) | protected function getClass()
    method testValidConstructorArguments (line 31) | public function testValidConstructorArguments($server, array $options)
    method testConstructor (line 45) | public function testConstructor()
    method testCount (line 61) | public function testCount($instance)
    method getValidConstructorArguments (line 69) | public function getValidConstructorArguments()
    method getMockServer (line 79) | protected function getMockServer()
    method getMockApplication (line 97) | protected function getMockApplication()

FILE: lib/Wrench/Tests/ConnectionTest.php
  class ConnectionTest (line 19) | class ConnectionTest extends Test
    method getClass (line 24) | protected function getClass()
    method testConstructor (line 34) | public function testConstructor($manager, $socket, array $options)
    method testClose (line 51) | public function testClose($code)
    method testHandshake (line 72) | public function testHandshake($path, $request)
    method testHandshakeBadSocket (line 89) | public function testHandshakeBadSocket($path, $request)
    method testWrongPathHandshake (line 105) | public function testWrongPathHandshake($path, $request)
    method testHandle (line 118) | public function testHandle($path, $request_handshake, array $requests,...
    method getConnectedSocket (line 139) | protected function getConnectedSocket()
    method getNotConnectedSocket (line 153) | protected function getNotConnectedSocket()
    method getConnectionForHandshake (line 164) | protected function getConnectionForHandshake($socket, $path, $request)
    method getConnectionForHandle (line 187) | protected function getConnectionForHandle($socket, $path, $handshake, ...
    method getMockConnectionManager (line 222) | protected function getMockConnectionManager()
    method getMockSocket (line 232) | protected function getMockSocket()
    method getMockApplication (line 242) | protected function getMockApplication()
    method getValidCloseCodes (line 252) | public function getValidCloseCodes()
    method getValidConstructorArguments (line 266) | public function getValidConstructorArguments()
    method getValidHandleData (line 303) | public function getValidHandleData()
    method getValidHandshakeData (line 352) | public function getValidHandshakeData()
    method getWrongPathHandshakeData (line 371) | public function getWrongPathHandshakeData()

FILE: lib/Wrench/Tests/Frame/BaseSubclassFrameTest.php
  class BadSubclassFrame (line 8) | class BadSubclassFrame extends HybiFrame
  class BadSubclassFrameTest (line 14) | class BadSubclassFrameTest extends Test
    method testInvalidFrameBuffer (line 19) | public function testInvalidFrameBuffer()
    method getClass (line 25) | protected function getClass()

FILE: lib/Wrench/Tests/Frame/FrameTest.php
  class FrameTest (line 13) | abstract class FrameTest extends Test
    method setUp (line 25) | public function setUp()
    method getNewFrame (line 31) | protected function getNewFrame()
    method tearDown (line 40) | protected function tearDown()
    method testBijection (line 50) | public function testBijection($type, $payload, $masked)
    method testEncodeTypeReflection (line 120) | public function testEncodeTypeReflection($type, $payload, $masked)
    method testEncodeLengthReflection (line 130) | public function testEncodeLengthReflection($type, $payload, $masked)
    method testEncodePayloadReflection (line 140) | public function testEncodePayloadReflection($type, $payload, $masked)
    method getValidEncodePayloads (line 151) | public function getValidEncodePayloads()

FILE: lib/Wrench/Tests/Frame/HybiFrameTest.php
  class HybiFrameTest (line 8) | class HybiFrameTest extends FrameTest
    method getClass (line 10) | protected function getClass()

FILE: lib/Wrench/Tests/Listener/ListenerTest.php
  class ListenerTest (line 10) | abstract class ListenerTest extends Test
    method testListen (line 15) | public function testListen($instance)
    method testConstructor (line 22) | abstract public function testConstructor();

FILE: lib/Wrench/Tests/Listener/OriginPolicyTest.php
  class OriginPolicyTest (line 8) | class OriginPolicyTest extends ListenerTest
    method getClass (line 13) | public function getClass()
    method testConstructor (line 21) | public function testConstructor()
    method testValidAllowed (line 33) | public function testValidAllowed($allowed, $domain)
    method testValidHandshake (line 44) | public function testValidHandshake($allowed, $domain)
    method testInvalidAllowed (line 62) | public function testInvalidAllowed($allowed, $bad_domain)
    method testInvalidHandshake (line 73) | public function testInvalidHandshake($allowed, $bad_domain)
    method getValidArguments (line 89) | public function getValidArguments()
    method getInvalidArguments (line 101) | public function getInvalidArguments()

FILE: lib/Wrench/Tests/Listener/RateLimiterTest.php
  class RateLimiterTest (line 8) | class RateLimiterTest extends ListenerTest
    method getClass (line 13) | public function getClass()
    method testConstructor (line 21) | public function testConstructor()
    method testOnSocketConnect (line 28) | public function testOnSocketConnect()
    method testOnSocketDisconnect (line 33) | public function testOnSocketDisconnect()
    method testOnClientData (line 38) | public function testOnClientData()
    method getConnection (line 43) | protected function getConnection()

FILE: lib/Wrench/Tests/Payload/HybiPayloadTest.php
  class HybiPayloadTest (line 8) | class HybiPayloadTest extends PayloadTest
    method getClass (line 10) | protected function getClass()

FILE: lib/Wrench/Tests/Payload/PayloadTest.php
  class PayloadTest (line 13) | abstract class PayloadTest extends Test
    method setUp (line 25) | public function setUp()
    method testConstructor (line 35) | public function testConstructor()
    method testBijection (line 44) | public function testBijection($type, $payload)
    method testEncodeTypeReflection (line 71) | public function testEncodeTypeReflection($type, $payload)
    method testEncodePayloadReflection (line 81) | public function testEncodePayloadReflection($type, $payload)
    method testSendToSocket (line 91) | public function testSendToSocket($type, $payload)
    method testReceieveData (line 114) | public function testReceieveData($type, $payload)
    method getValidEncodePayloads (line 125) | public function getValidEncodePayloads()

FILE: lib/Wrench/Tests/Protocol/ProtocolTest.php
  class ProtocolTest (line 8) | abstract class ProtocolTest extends Test
    method setUp (line 13) | public function setUp()
    method testValidatHandshakeRequestValid (line 21) | public function testValidatHandshakeRequestValid($request)
    method testValidateHandshakeResponseValid (line 40) | public function testValidateHandshakeResponseValid($response, $key)
    method testGetResponseHandsake (line 54) | public function testGetResponseHandsake($unused, $key)
    method assertHttpResponse (line 69) | protected function assertHttpResponse($response, $message = '')
    method testGetVersion (line 75) | public function testGetVersion()
    method testGetResponseError (line 81) | public function testGetResponseError()
    method testValidateOriginUriValid (line 96) | public function testValidateOriginUriValid($uri)
    method testValidateOriginUriInvalid (line 109) | public function testValidateOriginUriInvalid($uri)
    method getValidOriginUris (line 114) | public function getValidOriginUris()
    method getInvalidOriginUris (line 123) | public function getInvalidOriginUris()
    method getValidHandshakeRequests (line 133) | public function getValidHandshakeRequests()
    method getValidHandshakeResponses (line 165) | public function getValidHandshakeResponses()

FILE: lib/Wrench/Tests/Protocol/Rfc6455ProtocolTest.php
  class Rfc6455ProtocolTest (line 8) | class Rfc6455ProtocolTest extends ProtocolTest
    method getClass (line 10) | protected function getClass()

FILE: lib/Wrench/Tests/ServerTest.php
  class ServerTest (line 15) | class ServerTest extends Test
    method getClass (line 20) | protected function getClass()
    method testConstructor (line 32) | public function testConstructor($url, array $options = array())
    method testLogging (line 43) | public function testLogging()
    method getValidConstructorArguments (line 64) | public function getValidConstructorArguments()

FILE: lib/Wrench/Tests/ServerTestHelper.php
  class ServerTestHelper (line 9) | class ServerTestHelper
    method getNextPort (line 23) | public static function getNextPort()
    method __destruct (line 34) | public function __destruct()
    method getConnectionString (line 42) | public function getConnectionString()
    method getEchoConnectionString (line 50) | public function getEchoConnectionString()
    method setUp (line 59) | public function setUp()
    method tearDown (line 82) | public function tearDown()
    method getCommand (line 129) | protected function getCommand()
    method log (line 140) | public function log($message, $priority = 'info')

FILE: lib/Wrench/Tests/Socket/ClientSocketTest.php
  class ClientSocketTest (line 11) | class ClientSocketTest extends UriSocketTest
    method getClass (line 16) | public function getClass()
    method testConstructor (line 26) | public function testConstructor()
    method testOptions (line 55) | public function testOptions()
    method testProtocolTypeError (line 90) | public function testProtocolTypeError()
    method testConstructorUriUnspecified (line 102) | public function testConstructorUriUnspecified()
    method testConstructorUriEmpty (line 110) | public function testConstructorUriEmpty()
    method testConstructorUriInvalid (line 119) | public function testConstructorUriInvalid()
    method testSendTooEarly (line 129) | public function testSendTooEarly($instance)
    method testConnect (line 137) | public function testConnect()

FILE: lib/Wrench/Tests/Socket/ServerClientSocketTest.php
  class ServerClientSocketTest (line 7) | class ServerClientSocketTest extends SocketTest
    method getClass (line 9) | public function getClass()
    method testConstructor (line 17) | public function testConstructor()
    method testGetIpTooSoon (line 29) | public function testGetIpTooSoon($instance)
    method testGetPortTooSoon (line 38) | public function testGetPortTooSoon($instance)

FILE: lib/Wrench/Tests/Socket/ServerSocketTest.php
  class ServerSocketTest (line 7) | class ServerSocketTest extends UriSocketTest
    method getClass (line 9) | public function getClass()

FILE: lib/Wrench/Tests/Socket/SocketTest.php
  class SocketTest (line 9) | abstract class SocketTest extends Test
    method testConstructor (line 14) | abstract public function testConstructor();
    method testIsConnected (line 19) | public function testIsConnected($instance)
    method testGetNamePart (line 30) | public function testGetNamePart($name, $ip, $port)
    method getValidNames (line 39) | public function getValidNames()

FILE: lib/Wrench/Tests/Socket/UriSocketTest.php
  class UriSocketTest (line 7) | abstract class UriSocketTest extends SocketTest
    method testConstructor (line 12) | public function testConstructor()
    method testInvalidConstructor (line 23) | public function testInvalidConstructor($uri)
    method testGetIp (line 31) | public function testGetIp($instance)
    method testGetPort (line 39) | public function testGetPort($instance)
    method getInvalidConstructorArguments (line 47) | public function getInvalidConstructorArguments()

FILE: lib/Wrench/Tests/Test.php
  class Test (line 11) | abstract class Test extends PHPUnit_Framework_TestCase
    method getClass (line 18) | abstract protected function getClass();
    method assertInstanceOfClass (line 26) | public function assertInstanceOfClass($instance, $message = null)
    method getInstance (line 42) | public function getInstance(/* ... */)
    method log (line 57) | public function log($message, $priority = 'info')

FILE: lib/Wrench/Util/Configurable.php
  class Configurable (line 12) | abstract class Configurable
    method __construct (line 33) | public function __construct(
    method configure (line 45) | protected function configure(array $options)
    method configureProtocol (line 57) | protected function configureProtocol()

FILE: lib/Wrench/Util/Ssl.php
  class Ssl (line 5) | class Ssl
    method generatePemFile (line 22) | public static function generatePemFile($pem_file, $pem_passphrase, $co...
Condensed preview — 141 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (334K chars).
[
  {
    "path": ".gitignore",
    "chars": 34,
    "preview": "*.sw[m-p]\nphpunit\nbuild\ndoc/build\n"
  },
  {
    "path": ".travis",
    "chars": 151,
    "preview": "#!/bin/bash\n\nphpunit\nreturn=$?\n\necho \"\"\necho \"Server error log\"\ncat build/server.err.log\n\necho \"\"\necho \"Server log\"\ncat "
  },
  {
    "path": ".travis.yml",
    "chars": 161,
    "preview": "language: php\n\nscript: ./.travis\n\nphp:\n  - 5.3\n  - 5.4\n\nbranches:\n  only:\n    - master\n    - devel\n    - 2.0\n\nnotificati"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 1598,
    "preview": "<!-- vim: set tw=79 sw=4 ts=4 et ft=markdown : -->\n# Changelog\n\n## 2.0.0\n\n* Name change: php-websocket was renamed to Wr"
  },
  {
    "path": "LICENSE",
    "chars": 483,
    "preview": "            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE\n                    Version 2, December 2004\n\n Copyright (C) 200"
  },
  {
    "path": "README.md",
    "chars": 3051,
    "preview": "<!-- vim: set tw=79 sw=4 ts=4 et ft=markdown : -->\n# Wrench\n## Simple WebSocket Client/Server for PHP\n### Formerly known"
  },
  {
    "path": "TODO.md",
    "chars": 105,
    "preview": "# TODO\n\n - Unify the socket handling of `WebSocket\\Client` with that of `Websocket\\Socket`\n - Moar tests!"
  },
  {
    "path": "VERSION",
    "chars": 6,
    "preview": "2.0.0\n"
  },
  {
    "path": "composer.json",
    "chars": 886,
    "preview": "{\n    \"name\": \"wrench/wrench\",\n    \"type\": \"library\",\n    \"description\": \"PHP WebSocket client/server library\",\n    \"key"
  },
  {
    "path": "doc/Makefile",
    "chars": 5958,
    "preview": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD "
  },
  {
    "path": "doc/requirements.txt",
    "chars": 24,
    "preview": "sphinxcontrib-phpdomain\n"
  },
  {
    "path": "doc/source/api/Application/Application.rst",
    "chars": 461,
    "preview": "--------------------------------\nWrench\\\\Application\\\\Application\n--------------------------------\n\n.. php:namespace: Wr"
  },
  {
    "path": "doc/source/api/Application/EchoApplication.rst",
    "chars": 322,
    "preview": "------------------------------------\nWrench\\\\Application\\\\EchoApplication\n------------------------------------\n\n.. php:n"
  },
  {
    "path": "doc/source/api/Application/index.rst",
    "chars": 148,
    "preview": ":::::::::::::::::::\nWrench\\\\Application\n:::::::::::::::::::\n\n.. php:namespace: Wrench\\\\Application\n\n.. toctree::\n\n   App"
  },
  {
    "path": "doc/source/api/BasicServer.rst",
    "chars": 3888,
    "preview": "-------------------\nWrench\\\\BasicServer\n-------------------\n\n.. php:namespace: Wrench\n\n.. php:class:: BasicServer\n\n    ."
  },
  {
    "path": "doc/source/api/Client.rst",
    "chars": 2031,
    "preview": "--------------\nWrench\\\\Client\n--------------\n\n.. php:namespace: Wrench\n\n.. php:class:: Client\n\n    Client class\n\n    Rep"
  },
  {
    "path": "doc/source/api/Connection.rst",
    "chars": 4366,
    "preview": "------------------\nWrench\\\\Connection\n------------------\n\n.. php:namespace: Wrench\n\n.. php:class:: Connection\n\n    Repre"
  },
  {
    "path": "doc/source/api/ConnectionManager.rst",
    "chars": 3519,
    "preview": "-------------------------\nWrench\\\\ConnectionManager\n-------------------------\n\n.. php:namespace: Wrench\n\n.. php:class:: "
  },
  {
    "path": "doc/source/api/Exception/BadRequestException.rst",
    "chars": 855,
    "preview": "--------------------------------------\nWrench\\\\Exception\\\\BadRequestException\n--------------------------------------\n\n.."
  },
  {
    "path": "doc/source/api/Exception/CloseException.rst",
    "chars": 867,
    "preview": "---------------------------------\nWrench\\\\Exception\\\\CloseException\n---------------------------------\n\n.. php:namespace:"
  },
  {
    "path": "doc/source/api/Exception/ConnectionException.rst",
    "chars": 799,
    "preview": "--------------------------------------\nWrench\\\\Exception\\\\ConnectionException\n--------------------------------------\n\n.."
  },
  {
    "path": "doc/source/api/Exception/Exception.rst",
    "chars": 759,
    "preview": "----------------------------\nWrench\\\\Exception\\\\Exception\n----------------------------\n\n.. php:namespace: Wrench\\\\Except"
  },
  {
    "path": "doc/source/api/Exception/FrameException.rst",
    "chars": 779,
    "preview": "---------------------------------\nWrench\\\\Exception\\\\FrameException\n---------------------------------\n\n.. php:namespace:"
  },
  {
    "path": "doc/source/api/Exception/HandshakeException.rst",
    "chars": 851,
    "preview": "-------------------------------------\nWrench\\\\Exception\\\\HandshakeException\n-------------------------------------\n\n.. ph"
  },
  {
    "path": "doc/source/api/Exception/InvalidOriginException.rst",
    "chars": 897,
    "preview": "-----------------------------------------\nWrench\\\\Exception\\\\InvalidOriginException\n------------------------------------"
  },
  {
    "path": "doc/source/api/Exception/PayloadException.rst",
    "chars": 787,
    "preview": "-----------------------------------\nWrench\\\\Exception\\\\PayloadException\n-----------------------------------\n\n.. php:name"
  },
  {
    "path": "doc/source/api/Exception/RateLimiterException.rst",
    "chars": 859,
    "preview": "---------------------------------------\nWrench\\\\Exception\\\\RateLimiterException\n---------------------------------------\n"
  },
  {
    "path": "doc/source/api/Exception/SocketException.rst",
    "chars": 783,
    "preview": "----------------------------------\nWrench\\\\Exception\\\\SocketException\n----------------------------------\n\n.. php:namespa"
  },
  {
    "path": "doc/source/api/Exception/index.rst",
    "chars": 312,
    "preview": ":::::::::::::::::\nWrench\\\\Exception\n:::::::::::::::::\n\n.. php:namespace: Wrench\\\\Exception\n\n.. toctree::\n\n   BadRequestE"
  },
  {
    "path": "doc/source/api/Frame/Frame.rst",
    "chars": 2542,
    "preview": "--------------------\nWrench\\\\Frame\\\\Frame\n--------------------\n\n.. php:namespace: Wrench\\\\Frame\n\n.. php:class:: Frame\n\n "
  },
  {
    "path": "doc/source/api/Frame/HybiFrame.rst",
    "chars": 3577,
    "preview": "------------------------\nWrench\\\\Frame\\\\HybiFrame\n------------------------\n\n.. php:namespace: Wrench\\\\Frame\n\n.. php:clas"
  },
  {
    "path": "doc/source/api/Frame/index.rst",
    "chars": 112,
    "preview": ":::::::::::::\nWrench\\\\Frame\n:::::::::::::\n\n.. php:namespace: Wrench\\\\Frame\n\n.. toctree::\n\n   Frame\n   HybiFrame\n"
  },
  {
    "path": "doc/source/api/Listener/HandshakeRequestListener.rst",
    "chars": 621,
    "preview": "------------------------------------------\nWrench\\\\Listener\\\\HandshakeRequestListener\n----------------------------------"
  },
  {
    "path": "doc/source/api/Listener/Listener.rst",
    "chars": 241,
    "preview": "--------------------------\nWrench\\\\Listener\\\\Listener\n--------------------------\n\n.. php:namespace: Wrench\\\\Listener\n\n.."
  },
  {
    "path": "doc/source/api/Listener/OriginPolicy.rst",
    "chars": 1053,
    "preview": "------------------------------\nWrench\\\\Listener\\\\OriginPolicy\n------------------------------\n\n.. php:namespace: Wrench\\\\"
  },
  {
    "path": "doc/source/api/Listener/RateLimiter.rst",
    "chars": 2620,
    "preview": "-----------------------------\nWrench\\\\Listener\\\\RateLimiter\n-----------------------------\n\n.. php:namespace: Wrench\\\\Lis"
  },
  {
    "path": "doc/source/api/Listener/index.rst",
    "chars": 173,
    "preview": "::::::::::::::::\nWrench\\\\Listener\n::::::::::::::::\n\n.. php:namespace: Wrench\\\\Listener\n\n.. toctree::\n\n   HandshakeReques"
  },
  {
    "path": "doc/source/api/Payload/HybiPayload.rst",
    "chars": 1887,
    "preview": "----------------------------\nWrench\\\\Payload\\\\HybiPayload\n----------------------------\n\n.. php:namespace: Wrench\\\\Payloa"
  },
  {
    "path": "doc/source/api/Payload/Payload.rst",
    "chars": 2005,
    "preview": "------------------------\nWrench\\\\Payload\\\\Payload\n------------------------\n\n.. php:namespace: Wrench\\\\Payload\n\n.. php:cl"
  },
  {
    "path": "doc/source/api/Payload/index.rst",
    "chars": 124,
    "preview": ":::::::::::::::\nWrench\\\\Payload\n:::::::::::::::\n\n.. php:namespace: Wrench\\\\Payload\n\n.. toctree::\n\n   HybiPayload\n   Payl"
  },
  {
    "path": "doc/source/api/Protocol/Hybi10Protocol.rst",
    "chars": 6959,
    "preview": "--------------------------------\nWrench\\\\Protocol\\\\Hybi10Protocol\n--------------------------------\n\n.. php:namespace: Wr"
  },
  {
    "path": "doc/source/api/Protocol/HybiProtocol.rst",
    "chars": 7096,
    "preview": "------------------------------\nWrench\\\\Protocol\\\\HybiProtocol\n------------------------------\n\n.. php:namespace: Wrench\\\\"
  },
  {
    "path": "doc/source/api/Protocol/Protocol.rst",
    "chars": 7331,
    "preview": "--------------------------\nWrench\\\\Protocol\\\\Protocol\n--------------------------\n\n.. php:namespace: Wrench\\\\Protocol\n\n.."
  },
  {
    "path": "doc/source/api/Protocol/Rfc6455Protocol.rst",
    "chars": 6969,
    "preview": "---------------------------------\nWrench\\\\Protocol\\\\Rfc6455Protocol\n---------------------------------\n\n.. php:namespace:"
  },
  {
    "path": "doc/source/api/Protocol/index.rst",
    "chars": 167,
    "preview": "::::::::::::::::\nWrench\\\\Protocol\n::::::::::::::::\n\n.. php:namespace: Wrench\\\\Protocol\n\n.. toctree::\n\n   Hybi10Protocol\n"
  },
  {
    "path": "doc/source/api/Resource.rst",
    "chars": 198,
    "preview": "----------------\nWrench\\\\Resource\n----------------\n\n.. php:namespace: Wrench\n\n.. php:class:: Resource\n\n    Resource inte"
  },
  {
    "path": "doc/source/api/Server.rst",
    "chars": 4094,
    "preview": "--------------\nWrench\\\\Server\n--------------\n\n.. php:namespace: Wrench\n\n.. php:class:: Server\n\n    WebSocket server\n\n   "
  },
  {
    "path": "doc/source/api/Socket/ClientSocket.rst",
    "chars": 3607,
    "preview": "----------------------------\nWrench\\\\Socket\\\\ClientSocket\n----------------------------\n\n.. php:namespace: Wrench\\\\Socket"
  },
  {
    "path": "doc/source/api/Socket/ServerClientSocket.rst",
    "chars": 3325,
    "preview": "----------------------------------\nWrench\\\\Socket\\\\ServerClientSocket\n----------------------------------\n\n.. php:namespa"
  },
  {
    "path": "doc/source/api/Socket/ServerSocket.rst",
    "chars": 3725,
    "preview": "----------------------------\nWrench\\\\Socket\\\\ServerSocket\n----------------------------\n\n.. php:namespace: Wrench\\\\Socket"
  },
  {
    "path": "doc/source/api/Socket/Socket.rst",
    "chars": 3373,
    "preview": "----------------------\nWrench\\\\Socket\\\\Socket\n----------------------\n\n.. php:namespace: Wrench\\\\Socket\n\n.. php:class:: S"
  },
  {
    "path": "doc/source/api/Socket/UriSocket.rst",
    "chars": 3849,
    "preview": "-------------------------\nWrench\\\\Socket\\\\UriSocket\n-------------------------\n\n.. php:namespace: Wrench\\\\Socket\n\n.. php:"
  },
  {
    "path": "doc/source/api/Socket/index.rst",
    "chars": 171,
    "preview": "::::::::::::::\nWrench\\\\Socket\n::::::::::::::\n\n.. php:namespace: Wrench\\\\Socket\n\n.. toctree::\n\n   ClientSocket\n   ServerC"
  },
  {
    "path": "doc/source/api/Util/Configurable.rst",
    "chars": 602,
    "preview": "--------------------------\nWrench\\\\Util\\\\Configurable\n--------------------------\n\n.. php:namespace: Wrench\\\\Util\n\n.. php"
  },
  {
    "path": "doc/source/api/Util/Ssl.rst",
    "chars": 1136,
    "preview": "-----------------\nWrench\\\\Util\\\\Ssl\n-----------------\n\n.. php:namespace: Wrench\\\\Util\n\n.. php:class:: Ssl\n\n    .. php:me"
  },
  {
    "path": "doc/source/api/Util/index.rst",
    "chars": 109,
    "preview": "::::::::::::\nWrench\\\\Util\n::::::::::::\n\n.. php:namespace: Wrench\\\\Util\n\n.. toctree::\n\n   Configurable\n   Ssl\n"
  },
  {
    "path": "doc/source/api/index.rst",
    "chars": 315,
    "preview": "`````````````````\nAPI Documentation\n`````````````````\n\n.. php:namespace: Wrench\n\n.. toctree::\n\n   Application/index\n   B"
  },
  {
    "path": "doc/source/authors.rst",
    "chars": 388,
    "preview": "-------\nAuthors\n-------\n\nThe original maintainer and author was `@nicokaiser\n<https://github.com/nicokaiser>`_. Plentifu"
  },
  {
    "path": "doc/source/conf.py",
    "chars": 8106,
    "preview": "# -*- coding: utf-8 -*-\n#\n# Wrench documentation build configuration file, created by\n# sphinx-quickstart on Thu Jul 26 "
  },
  {
    "path": "doc/source/getting-started.rst",
    "chars": 1161,
    "preview": ".. vim: set tw=78 sw=4 ts=4 :\n\n***************\nGetting Started\n***************\n\n-----------------\nStarting a Server\n----"
  },
  {
    "path": "doc/source/index.rst",
    "chars": 217,
    "preview": ".. vim: set tw=78 sw=2 ts=2 :\n\n======\nWrench\n======\n\nWrench is a WebSockets library for PHP 5.3+\n\n.. toctree::\n   :maxde"
  },
  {
    "path": "doc/source/installing.rst",
    "chars": 945,
    "preview": ".. vim: set tw=78 sw=4 ts=4 :\n\n*****************\nInstalling Wrench\n*****************\n\nThe library is PSR-0 compatible, w"
  },
  {
    "path": "doc/source/introduction.rst",
    "chars": 617,
    "preview": ".. vim: set tw=78 sw=4 ts=4 :\n\n************\nIntroduction\n************\n\nWrench is a simple websocket server and client pa"
  },
  {
    "path": "doc/source/performance.rst",
    "chars": 627,
    "preview": ".. vim: set tw=78 sw=4 ts=4 :\n\n***********\nPerformance\n***********\n\nWrench uses a single-process server, without threads"
  },
  {
    "path": "doc/source/setup.py",
    "chars": 200,
    "preview": "#!/usr/bin/env python\n\nfrom distutils.core import setup\n\nsetup(\n        name='wrench-documentation',\n        version='2."
  },
  {
    "path": "examples/StatusApplication.php",
    "chars": 3187,
    "preview": "<?php\nnamespace Wrench\\Application;\n\n/**\n * Shiny WSS Status Application\n * Provides live server infos/messages to clien"
  },
  {
    "path": "examples/coffeescript/coffee/client.coffee",
    "chars": 1087,
    "preview": "$(document).ready ->\n  log = (msg) -> $('#log').append(\"#{msg}<br />\")\n  serverUrl = 'ws://127.0.0.1:8000/demo'\n  if win"
  },
  {
    "path": "examples/coffeescript/coffee/status.coffee",
    "chars": 1933,
    "preview": "$(document).ready ->\n  log = (msg) -> $('#log').prepend(\"#{msg}<br />\")\n  serverUrl = 'ws://localhost:8000/status'\n  if "
  },
  {
    "path": "examples/coffeescript/css/client.css",
    "chars": 1254,
    "preview": "body {\n\tbackground: #f1f1f1;\n\tpadding-top: 65px;\n\ttext-align: center;\n\tfont-family: Arial, Helvetica, sans-serif;\n\ttext-"
  },
  {
    "path": "examples/coffeescript/css/status.css",
    "chars": 1383,
    "preview": "body {\n\tbackground: #f1f1f1;\n\tpadding-top: 65px;\n\ttext-align: center;\n\tfont-family: Arial, Helvetica, sans-serif;\n\ttext-"
  },
  {
    "path": "examples/coffeescript/index.html",
    "chars": 891,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <link rel=\"stylesheet\" href=\"css/client.css\">\n\n    <script src=\"js/jquery.min.js\"></sc"
  },
  {
    "path": "examples/coffeescript/status.html",
    "chars": 1151,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <link rel=\"stylesheet\" href=\"css/status.css\">\n\n    <script src=\"js/jquery.min.js\"></sc"
  },
  {
    "path": "examples/server.pem",
    "chars": 1944,
    "preview": "-----BEGIN CERTIFICATE-----\nMIICsDCCAhmgAwIBAgIBADANBgkqhkiG9w0BAQQFADB1MQswCQYDVQQGEwJERTEN\nMAsGA1UECAwEbm9uZTENMAsGA1U"
  },
  {
    "path": "examples/server.php",
    "chars": 1883,
    "preview": "#!/usr/bin/env php\n<?php\n\n/* This program is free software. It comes without any warranty, to\n * the extent permitted by"
  },
  {
    "path": "examples/server_ssl.php",
    "chars": 1724,
    "preview": "<?php\n/* This program is free software. It comes without any warranty, to\n * the extent permitted by applicable law. You"
  },
  {
    "path": "lib/SplClassLoader.php",
    "chars": 4081,
    "preview": "<?php\n\n/**\n * SplClassLoader implementation that implements the technical interoperability\n * standards for PHP 5.3 name"
  },
  {
    "path": "lib/Wrench/Application/Application.php",
    "chars": 746,
    "preview": "<?php\n\nnamespace Wrench\\Application;\n\n/**\n * Wrench Server Application\n */\nabstract class Application\n{\n    /**\n     * O"
  },
  {
    "path": "lib/Wrench/Application/EchoApplication.php",
    "chars": 370,
    "preview": "<?php\n\nnamespace Wrench\\Application;\n\nuse Wrench\\Application\\Application;\nuse Wrench\\Application\\NamedApplication;\n\n/**\n"
  },
  {
    "path": "lib/Wrench/Application/ServerTimeApplication.php",
    "chars": 913,
    "preview": "<?php\n\nnamespace Wrench\\Application;\n\nuse Wrench\\Application\\Application;\nuse Wrench\\Application\\NamedApplication;\n\n/**\n"
  },
  {
    "path": "lib/Wrench/BasicServer.php",
    "chars": 1624,
    "preview": "<?php\n\nnamespace Wrench;\n\nuse Wrench\\Server;\n\nclass BasicServer extends Server\n{\n    protected $rateLimiter;\n    protect"
  },
  {
    "path": "lib/Wrench/Client.php",
    "chars": 5939,
    "preview": "<?php\n\nnamespace Wrench;\n\nuse Wrench\\Payload\\Payload;\n\nuse Wrench\\Payload\\PayloadHandler;\n\nuse Wrench\\Util\\Configurable;"
  },
  {
    "path": "lib/Wrench/Connection.php",
    "chars": 13340,
    "preview": "<?php\n\nnamespace Wrench;\n\nuse Wrench\\Payload\\PayloadHandler;\n\nuse Wrench\\Protocol\\Protocol;\n\nuse Wrench\\Payload\\Payload;"
  },
  {
    "path": "lib/Wrench/ConnectionManager.php",
    "chars": 8672,
    "preview": "<?php\n\nnamespace Wrench;\n\nuse Wrench\\Protocol\\Protocol;\nuse Wrench\\Resource;\nuse Wrench\\Util\\Configurable;\nuse Wrench\\Ex"
  },
  {
    "path": "lib/Wrench/Exception/BadRequestException.php",
    "chars": 514,
    "preview": "<?php\n\nnamespace Wrench\\Exception;\n\nuse Wrench\\Protocol\\Protocol;\nuse Wrench\\Exception\\HandshakeException;\n\nclass BadReq"
  },
  {
    "path": "lib/Wrench/Exception/CloseException.php",
    "chars": 554,
    "preview": "<?php\n\nnamespace Wrench\\Exception;\n\nuse Wrench\\Protocol\\Protocol;\nuse Wrench\\Exception\\Exception as WrenchException;\n\n/*"
  },
  {
    "path": "lib/Wrench/Exception/ConnectionException.php",
    "chars": 83,
    "preview": "<?php\n\nnamespace Wrench\\Exception;\n\nclass ConnectionException extends Exception\n{\n}"
  },
  {
    "path": "lib/Wrench/Exception/Exception.php",
    "chars": 74,
    "preview": "<?php\n\nnamespace Wrench\\Exception;\n\nclass Exception extends \\Exception\n{\n}"
  },
  {
    "path": "lib/Wrench/Exception/FrameException.php",
    "chars": 136,
    "preview": "<?php\nnamespace Wrench\\Exception;\n\nuse Wrench\\Exception\\Exception as WrenchException;\n\nclass FrameException extends Wren"
  },
  {
    "path": "lib/Wrench/Exception/HandshakeException.php",
    "chars": 521,
    "preview": "<?php\n\nnamespace Wrench\\Exception;\n\nuse Wrench\\Protocol\\Protocol;\nuse Wrench\\Exception\\Exception as WrenchException;\n\ncl"
  },
  {
    "path": "lib/Wrench/Exception/InvalidOriginException.php",
    "chars": 552,
    "preview": "<?php\n\nnamespace Wrench\\Exception;\n\nuse Wrench\\Protocol\\Protocol;\nuse Wrench\\Exception\\HandshakeException;\n\n/**\n * Inval"
  },
  {
    "path": "lib/Wrench/Exception/PayloadException.php",
    "chars": 138,
    "preview": "<?php\nnamespace Wrench\\Exception;\n\nuse Wrench\\Exception\\Exception as WrenchException;\n\nclass PayloadException extends Wr"
  },
  {
    "path": "lib/Wrench/Exception/RateLimiterException.php",
    "chars": 492,
    "preview": "<?php\nnamespace Wrench\\Exception;\n\nuse Wrench\\Exception\\Exception as WrenchException;\n\nclass RateLimiterException extend"
  },
  {
    "path": "lib/Wrench/Exception/SocketException.php",
    "chars": 137,
    "preview": "<?php\nnamespace Wrench\\Exception;\n\nuse Wrench\\Exception\\Exception as WrenchException;\n\nclass SocketException extends Wre"
  },
  {
    "path": "lib/Wrench/Frame/Frame.php",
    "chars": 3954,
    "preview": "<?php\n\nnamespace Wrench\\Frame;\n\nuse Wrench\\Payload\\Payload;\n\nuse Wrench\\Exception\\FrameException;\n\n/**\n * Represents a W"
  },
  {
    "path": "lib/Wrench/Frame/HybiFrame.php",
    "chars": 10399,
    "preview": "<?php\n\nnamespace Wrench\\Frame;\n\nuse Wrench\\Protocol\\Protocol;\nuse Wrench\\Exception\\FrameException;\nuse \\InvalidArgumentE"
  },
  {
    "path": "lib/Wrench/Listener/HandshakeRequestListener.php",
    "chars": 404,
    "preview": "<?php\n\nnamespace Wrench\\Listener;\n\nuse Wrench\\Connection;\n\ninterface HandshakeRequestListener\n{\n    /**\n     * Handshake"
  },
  {
    "path": "lib/Wrench/Listener/Listener.php",
    "chars": 121,
    "preview": "<?php\n\nnamespace Wrench\\Listener;\n\nuse Wrench\\Server;\n\ninterface Listener\n{\n    public function listen(Server $server);\n"
  },
  {
    "path": "lib/Wrench/Listener/OriginPolicy.php",
    "chars": 1837,
    "preview": "<?php\n\nnamespace Wrench\\Listener;\n\nuse Wrench\\Connection;\nuse Wrench\\Exception\\InvalidOriginException;\nuse Wrench\\Server"
  },
  {
    "path": "lib/Wrench/Listener/RateLimiter.php",
    "chars": 5240,
    "preview": "<?php\n\nnamespace Wrench\\Listener;\n\nuse Wrench\\Util\\Configurable;\nuse Wrench\\Server;\n\nclass RateLimiter extends Configura"
  },
  {
    "path": "lib/Wrench/Payload/HybiPayload.php",
    "chars": 333,
    "preview": "<?php\n\nnamespace Wrench\\Payload;\n\nuse Wrench\\Frame\\HybiFrame;\nuse Wrench\\Exception\\PayloadException;\n\n/**\n * Gets a HyBi"
  },
  {
    "path": "lib/Wrench/Payload/Payload.php",
    "chars": 4792,
    "preview": "<?php\n\nnamespace Wrench\\Payload;\n\nuse Wrench\\Frame\\Frame;\n\nuse Wrench\\Exception\\FrameException;\n\nuse Wrench\\Socket\\Socke"
  },
  {
    "path": "lib/Wrench/Payload/PayloadHandler.php",
    "chars": 2928,
    "preview": "<?php\n\nnamespace Wrench\\Payload;\n\nuse Wrench\\Exception\\PayloadException;\nuse Wrench\\Exception\\ConnectionException;\nuse W"
  },
  {
    "path": "lib/Wrench/Protocol/Hybi10Protocol.php",
    "chars": 660,
    "preview": "<?php\n\nnamespace Wrench\\Protocol;\n\nuse Wrench\\Protocol\\HybiProtocol;\n\n/**\n * http://tools.ietf.org/html/draft-ietf-hybi-"
  },
  {
    "path": "lib/Wrench/Protocol/HybiProtocol.php",
    "chars": 430,
    "preview": "<?php\n\nnamespace Wrench\\Protocol;\n\nuse Wrench\\Payload\\HybiPayload;\n\nuse Wrench\\Exception\\ConnectionException;\n\nuse Wrenc"
  },
  {
    "path": "lib/Wrench/Protocol/Protocol.php",
    "chars": 22384,
    "preview": "<?php\n\nnamespace Wrench\\Protocol;\n\nuse Wrench\\Payload\\Payload;\n\nuse Wrench\\Exception\\BadRequestException;\n\nuse \\Exceptio"
  },
  {
    "path": "lib/Wrench/Protocol/Rfc6455Protocol.php",
    "chars": 687,
    "preview": "<?php\n\nnamespace Wrench\\Protocol;\n\nuse Wrench\\Protocol\\HybiProtocol;\n\n/**\n * This is the version of websockets used by C"
  },
  {
    "path": "lib/Wrench/Resource.php",
    "chars": 151,
    "preview": "<?php\n\nnamespace Wrench;\n\n/**\n * Resource interface\n */\ninterface Resource\n{\n    public function getResourceId();\n    pu"
  },
  {
    "path": "lib/Wrench/Server.php",
    "chars": 7613,
    "preview": "<?php\n\nnamespace Wrench;\n\nuse Wrench\\Util\\Configurable;\n\nuse Wrench\\Socket;\nuse Wrench\\Resource;\n\nuse \\Closure;\nuse \\Inv"
  },
  {
    "path": "lib/Wrench/Socket/ClientSocket.php",
    "chars": 2555,
    "preview": "<?php\nnamespace Wrench\\Socket;\n\nuse Wrench\\Socket\\UriSocket;\n\n/**\n * Options:\n *  - timeout_connect      => int, seconds"
  },
  {
    "path": "lib/Wrench/Socket/ServerClientSocket.php",
    "chars": 570,
    "preview": "<?php\n\nnamespace Wrench\\Socket;\n\nuse Wrench\\Socket\\Socket;\n\nclass ServerClientSocket extends Socket\n{\n    /**\n     * Con"
  },
  {
    "path": "lib/Wrench/Socket/ServerSocket.php",
    "chars": 3230,
    "preview": "<?php\n\nnamespace Wrench\\Socket;\n\nuse Wrench\\Exception\\ConnectionException;\n\nuse Wrench\\Socket\\UriSocket;\n\n/**\n * Server "
  },
  {
    "path": "lib/Wrench/Socket/Socket.php",
    "chars": 7565,
    "preview": "<?php\n\nnamespace Wrench\\Socket;\n\nuse Wrench\\Resource;\nuse Wrench\\Exception\\ConnectionException;\nuse Wrench\\Exception\\Soc"
  },
  {
    "path": "lib/Wrench/Socket/UriSocket.php",
    "chars": 3007,
    "preview": "<?php\n\nnamespace Wrench\\Socket;\n\nuse Wrench\\Protocol\\Protocol;\n\nuse Wrench\\Socket\\Socket;\n\nabstract class UriSocket exte"
  },
  {
    "path": "lib/Wrench/Tests/Application/EchoApplicationTest.php",
    "chars": 1312,
    "preview": "<?php\n\nnamespace Wrench\\Tests\\Application;\n\nuse Wrench\\Protocol\\Protocol;\nuse Wrench\\Tests\\Test as WrenchTest;\n\nclass Ec"
  },
  {
    "path": "lib/Wrench/Tests/BasicServerTest.php",
    "chars": 2967,
    "preview": "<?php\n\nnamespace Wrench\\Tests;\n\nuse Wrench\\Server;\nuse Wrench\\BasicServer;\nuse Wrench\\Tests\\ServerTest;\nuse Wrench\\Socke"
  },
  {
    "path": "lib/Wrench/Tests/ClientTest.php",
    "chars": 4531,
    "preview": "<?php\n\nnamespace Wrench\\Tests;\n\nuse Wrench\\Protocol\\Protocol;\n\nuse Wrench\\Client;\nuse Wrench\\Tests\\Test;\nuse Wrench\\Sock"
  },
  {
    "path": "lib/Wrench/Tests/ConnectionManagerTest.php",
    "chars": 2122,
    "preview": "<?php\n\nnamespace Wrench\\Tests;\n\nuse Wrench\\ConnectionManager;\nuse Wrench\\Tests\\Test;\n\nuse Wrench\\Application\\EchoApplica"
  },
  {
    "path": "lib/Wrench/Tests/ConnectionTest.php",
    "chars": 10304,
    "preview": "<?php\n\nnamespace Wrench\\Tests;\n\nuse Wrench\\Application\\EchoApplication;\n\nuse Wrench\\Protocol\\Protocol;\n\nuse Wrench\\Conne"
  },
  {
    "path": "lib/Wrench/Tests/Frame/BaseSubclassFrameTest.php",
    "chars": 557,
    "preview": "<?php\n\nnamespace Wrench\\Tests\\Frame;\n\nuse Wrench\\Frame\\HybiFrame;\nuse Wrench\\Tests\\Test;\n\nclass BadSubclassFrame extends"
  },
  {
    "path": "lib/Wrench/Tests/Frame/FrameTest.php",
    "chars": 4735,
    "preview": "<?php\n\nnamespace Wrench\\Tests\\Frame;\n\nuse Wrench\\Protocol\\Protocol;\nuse Wrench\\Frame\\Frame;\nuse Wrench\\Tests\\Test;\nuse \\"
  },
  {
    "path": "lib/Wrench/Tests/Frame/HybiFrameTest.php",
    "chars": 229,
    "preview": "<?php\n\nnamespace Wrench\\Tests\\Frame;\n\nuse Wrench\\Frame\\HybiFrame;\nuse Wrench\\Tests\\Frame\\FrameTest;\n\nclass HybiFrameTest"
  },
  {
    "path": "lib/Wrench/Tests/Listener/ListenerTest.php",
    "chars": 401,
    "preview": "<?php\n\nnamespace Wrench\\Tests\\Listener;\n\nuse Wrench\\Tests\\Test;\n\n/**\n * Payload test\n */\nabstract class ListenerTest ext"
  },
  {
    "path": "lib/Wrench/Tests/Listener/OriginPolicyTest.php",
    "chars": 2870,
    "preview": "<?php\n\nnamespace Wrench\\Tests\\Listener;\n\nuse Wrench\\Listener\\RateLimiter;\nuse Wrench\\Tests\\Listener\\ListenerTest;\n\nclass"
  },
  {
    "path": "lib/Wrench/Tests/Listener/RateLimiterTest.php",
    "chars": 1771,
    "preview": "<?php\n\nnamespace Wrench\\Tests\\Listener;\n\nuse Wrench\\Listener\\RateLimiter;\nuse Wrench\\Tests\\Listener\\ListenerTest;\n\nclass"
  },
  {
    "path": "lib/Wrench/Tests/Payload/HybiPayloadTest.php",
    "chars": 248,
    "preview": "<?php\n\nnamespace Wrench\\Tests\\Protocol;\n\nuse Wrench\\Payload\\HybiPayload;\nuse Wrench\\Tests\\Payload\\PayloadTest;\n\nclass Hy"
  },
  {
    "path": "lib/Wrench/Tests/Payload/PayloadTest.php",
    "chars": 3718,
    "preview": "<?php\n\nnamespace Wrench\\Tests\\Payload;\n\nuse Wrench\\Protocol\\Protocol;\nuse Wrench\\Payload\\Payload;\nuse Wrench\\Tests\\Test;"
  },
  {
    "path": "lib/Wrench/Tests/Protocol/ProtocolTest.php",
    "chars": 5141,
    "preview": "<?php\n\nnamespace Wrench\\Tests\\Protocol;\n\nuse Wrench\\Tests\\Test;\nuse \\Exception;\n\nabstract class ProtocolTest extends Tes"
  },
  {
    "path": "lib/Wrench/Tests/Protocol/Rfc6455ProtocolTest.php",
    "chars": 265,
    "preview": "<?php\n\nnamespace Wrench\\Tests\\Protocol;\n\nuse Wrench\\Protocol\\Rfc6455Protocol;\nuse Wrench\\Tests\\Protocol\\ProtocolTest;\n\nc"
  },
  {
    "path": "lib/Wrench/Tests/ServerTest.php",
    "chars": 1735,
    "preview": "<?php\n\nnamespace Wrench\\Tests;\n\nuse Wrench\\Server;\nuse Wrench\\Tests\\Test;\nuse Wrench\\Socket;\n\nuse \\InvalidArgumentExcept"
  },
  {
    "path": "lib/Wrench/Tests/ServerTestHelper.php",
    "chars": 3788,
    "preview": "<?php\n\nnamespace Wrench\\Tests;\n\n/**\n * In conjunction with server.php, provides a listening server\n * against which test"
  },
  {
    "path": "lib/Wrench/Tests/Socket/ClientSocketTest.php",
    "chars": 4029,
    "preview": "<?php\n\nnamespace Wrench\\Tests\\Socket;\n\nuse Wrench\\Protocol\\Rfc6455Protocol;\nuse Wrench\\Socket\\ClientSocket;\nuse Wrench\\T"
  },
  {
    "path": "lib/Wrench/Tests/Socket/ServerClientSocketTest.php",
    "chars": 873,
    "preview": "<?php\n\nnamespace Wrench\\Tests\\Socket;\n\nuse \\Exception;\n\nclass ServerClientSocketTest extends SocketTest\n{\n    public fun"
  },
  {
    "path": "lib/Wrench/Tests/Socket/ServerSocketTest.php",
    "chars": 192,
    "preview": "<?php\n\nnamespace Wrench\\Tests\\Socket;\n\nuse \\Exception;\n\nclass ServerSocketTest extends UriSocketTest\n{\n    public functi"
  },
  {
    "path": "lib/Wrench/Tests/Socket/SocketTest.php",
    "chars": 1182,
    "preview": "<?php\n\nnamespace Wrench\\Tests\\Socket;\n\nuse Wrench\\Tests\\Test;\nuse \\Exception;\nuse Wrench\\Socket\\Socket;\n\nabstract class "
  },
  {
    "path": "lib/Wrench/Tests/Socket/UriSocketTest.php",
    "chars": 1214,
    "preview": "<?php\n\nnamespace Wrench\\Tests\\Socket;\n\nuse \\Exception;\n\nabstract class UriSocketTest extends SocketTest\n{\n    /**\n     *"
  },
  {
    "path": "lib/Wrench/Tests/Test.php",
    "chars": 1350,
    "preview": "<?php\n\nnamespace Wrench\\Tests;\n\nuse \\PHPUnit_Framework_TestCase;\nuse \\ReflectionClass;\n\n/**\n * Test base class\n */\nabstr"
  },
  {
    "path": "lib/Wrench/Tests/bootstrap.php",
    "chars": 220,
    "preview": "<?php\n\n/**\n * Bootstrap file for the test suite\n */\n\n// Use SplClassLoader\nrequire_once(__DIR__ . '/../../SplClassLoader"
  },
  {
    "path": "lib/Wrench/Tests/server.php",
    "chars": 502,
    "preview": "<?php\n\nrequire_once(__DIR__ . '/../../SplClassLoader.php');\n\nif ($argc != 2 || !$argv[1] || !is_numeric($argv[1]) || (in"
  },
  {
    "path": "lib/Wrench/Util/Configurable.php",
    "chars": 1466,
    "preview": "<?php\n\nnamespace Wrench\\Util;\n\nuse Wrench\\Protocol\\Protocol;\nuse Wrench\\Protocol\\Rfc6455Protocol;\nuse \\InvalidArgumentEx"
  },
  {
    "path": "lib/Wrench/Util/Ssl.php",
    "chars": 1909,
    "preview": "<?php\n\nnamespace Wrench\\Util;\n\nclass Ssl\n{\n\t/**\n\t * Generates a new PEM File given the informations\n\t *\n\t * @param strin"
  },
  {
    "path": "phpunit.xml",
    "chars": 763,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<phpunit bootstrap=\"lib/Wrench/Tests/bootstrap.php\">\n\t<testsuites>\n\t\t<testsuite "
  }
]

About this extraction

This page contains the full source code of the nicokaiser/php-websocket GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 141 files (303.3 KB), approximately 78.8k tokens, and a symbol index with 428 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!