diff options
Diffstat (limited to 'libpathod')
-rw-r--r-- | libpathod/language/__init__.py | 15 | ||||
-rw-r--r-- | libpathod/language/base.py | 55 | ||||
-rw-r--r-- | libpathod/language/websockets.py | 11 | ||||
-rw-r--r-- | libpathod/templates/docs_lang_websockets.html | 39 |
4 files changed, 89 insertions, 31 deletions
diff --git a/libpathod/language/__init__.py b/libpathod/language/__init__.py index 8837a174..36ec19e2 100644 --- a/libpathod/language/__init__.py +++ b/libpathod/language/__init__.py @@ -5,20 +5,7 @@ import pyparsing as pp from . import base, http, websockets, writer, exceptions from exceptions import * - - -class Settings: - def __init__( - self, - staticdir = None, - unconstrained_file_access = False, - request_host = None, - websocket_key = None - ): - self.staticdir = staticdir - self.unconstrained_file_access = unconstrained_file_access - self.request_host = request_host - self.websocket_key = websocket_key +from base import Settings def parse_response(s): diff --git a/libpathod/language/base.py b/libpathod/language/base.py index 4179fa7d..41ad639a 100644 --- a/libpathod/language/base.py +++ b/libpathod/language/base.py @@ -7,6 +7,21 @@ from .. import utils from . import generators, exceptions +class Settings: + def __init__( + self, + staticdir = None, + unconstrained_file_access = False, + request_host = None, + websocket_key = None + ): + self.staticdir = staticdir + self.unconstrained_file_access = unconstrained_file_access + self.request_host = request_host + self.websocket_key = websocket_key + + + Sep = pp.Optional(pp.Literal(":")).suppress() @@ -375,6 +390,46 @@ class Value(_Component): return self.__class__(self.value.freeze(settings)) +class FixedLengthValue(Value): + """ + A value component lead by an optional preamble. + """ + preamble = "" + length = None + + def __init__(self, value): + Value.__init__(self, value) + lenguess = None + try: + lenguess = len(value.get_generator(Settings())) + except exceptions.RenderError: + pass + # This check will fail if we know the length upfront + if lenguess is not None and lenguess != self.length: + raise exceptions.RenderError( + "Invalid value length: '%s' is %s bytes, should be %s."%( + self.spec(), + lenguess, + self.length + ) + ) + + def values(self, settings): + ret = Value.values(self, settings) + l = sum(len(i) for i in ret) + # This check will fail if we don't know the length upfront - i.e. for + # file inputs + if l != self.length: + raise exceptions.RenderError( + "Invalid value length: '%s' is %s bytes, should be %s."%( + self.spec(), + l, + self.length + ) + ) + return ret + + class Boolean(_Component): """ A boolean flag. diff --git a/libpathod/language/websockets.py b/libpathod/language/websockets.py index a6674988..3abdf9d8 100644 --- a/libpathod/language/websockets.py +++ b/libpathod/language/websockets.py @@ -8,8 +8,9 @@ from . import base, generators, actions, message wf:c15:r'foo' wf:fin:rsv1:rsv2:rsv3:mask wf:-fin:-rsv1:-rsv2:-rsv3:-mask - wf:p234 - wf:m"mask" + + wf:k"mask" + wf:l234 """ @@ -58,6 +59,11 @@ class Mask(base.Boolean): name = "mask" +class Key(base.FixedLengthValue): + preamble = "k" + length = 4 + + class WebsocketFrame(message.Message): comps = ( Body, @@ -72,6 +78,7 @@ class WebsocketFrame(message.Message): actions.PauseAt, actions.DisconnectAt, actions.InjectAt, + Key, Raw, ) diff --git a/libpathod/templates/docs_lang_websockets.html b/libpathod/templates/docs_lang_websockets.html index 9b595e74..c50d081f 100644 --- a/libpathod/templates/docs_lang_websockets.html +++ b/libpathod/templates/docs_lang_websockets.html @@ -24,6 +24,13 @@ </tr> <tr> + <td> d<a href="#offsetspec">OFFSET</a> </td> + <td> + Disconnect after OFFSET bytes. + </td> + </tr> + + <tr> <td> [-]fin </td> <td> Set or un-set the <b>fin</b> bit. @@ -31,54 +38,56 @@ </tr> <tr> - <td> [-]rsv1 </td> + <td> i<a href="#offsetspec">OFFSET</a>,<a href="#valuespec">VALUE</a> </td> <td> - Set or un-set the <b>rsv1</b> bit. + Inject the specified value at the offset. </td> </tr> <tr> - <td> [-]rsv2 </td> + <td> [-]mask </td> <td> - Set or un-set the <b>rsv2</b> bit. + Set or un-set the <b>mask</b> bit. </td> </tr> <tr> - <td> [-]rsv3 </td> + <td> p<a href="#offsetspec">OFFSET</a>,SECONDS </td> <td> - Set or un-set the <b>rsv3</b> bit. + Pause for SECONDS seconds after OFFSET bytes. SECONDS can + be an integer or "f" to pause forever. </td> </tr> <tr> - <td> [-]mask </td> + <td> r </td> <td> - Set or un-set the <b>mask</b> bit. + Create a "raw" frame - disables auto-generation of the masking + key if the mask bit is on. </td> </tr> <tr> - <td> d<a href="#offsetspec">OFFSET</a> </td> + <td> [-]rsv1 </td> <td> - Disconnect after OFFSET bytes. + Set or un-set the <b>rsv1</b> bit. </td> </tr> <tr> - <td> i<a href="#offsetspec">OFFSET</a>,<a href="#valuespec">VALUE</a> </td> + <td> [-]rsv2 </td> <td> - Inject the specified value at the offset. + Set or un-set the <b>rsv2</b> bit. </td> </tr> <tr> - <td> p<a href="#offsetspec">OFFSET</a>,SECONDS </td> + <td> [-]rsv3 </td> <td> - Pause for SECONDS seconds after OFFSET bytes. SECONDS can - be an integer or "f" to pause forever. + Set or un-set the <b>rsv3</b> bit. </td> </tr> + </tbody> </table> |