module Stomper module Frames # Encapsulates a client side frame for the Stomp Protocol. # # See the {Stomp Protocol Specification}[http://stomp.codehaus.org/Protocol] # for more details. class ClientFrame attr_reader :headers, :body, :command # Creates a new ClientFrame instance with the specified +command+, # +headers+ and +body+. # If +headers+ includes a key of :generate_content_length, the # associated value will determine if a 'content-length' header is automatically # generated for this particular frame instance. This key can be # specified in the +headers+ parameter of any of the subclasses of ClientFrame, # and it will be interpretted in the same fashion. def initialize(command, headers={}, body=nil) @command = command @generate_content_length = headers.delete(:generate_content_length) @headers = Headers.new(headers) @body = body end # If +bool+ false or nil, this frame instance will not attempt to # automatically generate a content-length header. This is useful when # dealing with ActiveMQ as a stomp message broker, which will treat incoming # messages lacking a content-length header as +TextMessage+s and # +BytesMessage+s if the header is present. For more information see: # {Apache ActiveMQ - Stomp}[http://activemq.apache.org/stomp.html] def generate_content_length=(bool) @generate_content_length=bool end # If generate_content_length= has been called on this instance, then the # value supplied there is returned here. Otherwise, we defer to the # class method of the same name. def generate_content_length? @generate_content_length.nil? ? self.class.generate_content_length? : @generate_content_length end # Converts the frame instance into a valid string representation of the # desired command according to the specifications of the # {Stomp Protocol}[http://stomp.codehaus.org/Protocol] # # This is where the content-length header is generated if the frame # has a body of non-zero length and generate_content_length? is true. def to_stomp @headers["content-length"] = str_size(@body) if @body && !@body.empty? && generate_content_length? "#{@command}\n#{@headers.to_stomp}\n#{@body}\0" end class << self # Sets a class level setting for determining if a content-length header # should automatically be generated. def generate_content_length=(bool) @generate_content_length = bool end # Returns the value passed to the class level generate_content_length= # method, or true if no value has been set (thus, defaults to true.) # # The precedence for resolving whether or not a content-length header # is generated by the to_stomp method is: check the instance setting, # if it has not been set, defer to the class setting, if it hasn't # been set, default to true. def generate_content_length? if @generate_content_length.nil? @generate_content_length = true end @generate_content_length end end private def str_size(str) if str.respond_to?(:bytesize) def str_size(strng); strng.bytesize; end str.bytesize else def str_size(strng); strng.size; end str.size end end end end end