faye / websocket-driver-ruby

WebSocket protocol handler with pluggable I/O
Other
223 stars 43 forks source link

Preserve raw payload when processing events #33

Closed bigsur0 closed 8 years ago

bigsur0 commented 9 years ago

Would it be possible to preserve and expose the "raw" payload as a part of emit_message processing? The payload either gets encoded for converted to a byte array in this method, it would be nice to have a handle on the raw payload. Are there downsides to exposing the raw payload?

Relevant code snippets below.

lib/websocket/driver/hybi.rb

386       def emit_message
387         message  = @extensions.process_incoming_message(@message)
388         @message = nil
389
390         payload = message.data
391
392         case message.opcode
393           when OPCODES[:text] then
394             payload = Driver.encode(payload, :utf8)
395           when OPCODES[:binary]
396             payload = payload.bytes.to_a
397         end
398
399         if payload
400           emit(:message, MessageEvent.new(payload))
401         else
402           fail(:encoding_error, 'Could not decode a text frame as UTF-8')
403         end
404       rescue ::WebSocket::Extensions::ExtensionError => error
405         fail(:extension_error, error.message)
406       end
407     end
 lib/websocket/driver.rb

 43     ConnectEvent = Struct.new(nil)
 44     OpenEvent    = Struct.new(nil)
 45     MessageEvent = Struct.new(:data)
 46     CloseEvent   = Struct.new(:code, :reason)
jcoglan commented 9 years ago

What do you mean by the "raw payload" exactly?

bigsur0 commented 9 years ago

Basically "message.data" to be preserved in an extra field within the *Event Structs in addition to the "payload". My goal is to proxy some traffic through relatively untouched with at most permessage_deflate being applied. So quasi-raw after all...

jcoglan commented 9 years ago

I think this out of scope, partly because the question of what the "raw payload" is has no general definition; it depends very much on your use case. It might mean the masked message, unmasked message before extensions, the message after some or all extensions, or the data of individual frames, depending on what you want to do.

It would be hard to add something like this without holding onto large chunks of data that we currently let go of once they're processed, or without introducing breaking changes in future releases. I think that if you're implementing a proxy, you either use this library and you proxy completely decodes and reencodes messages between peers, or you're working at a level of abstraction beneath what we provide here and you should implement it yourself.

jcoglan commented 8 years ago

Can I close this issue?

bigsur0 commented 8 years ago

I think you can close this. If I can always re-open another issue if I look at the code and think an implementation in websocket-driver-ruby makes sense.

bigsur0 commented 8 years ago

Thanks for looking into this.