Module: RUPNP::SSDP::SearchResponder
- Includes:
- HTTP
- Included in:
- MSearchResponder, USearchResponder
- Defined in:
- lib/rupnp/ssdp/search_responder.rb
Overview
M-SEARCH responder for M-SEARCH multicast requests from control points.
Instance Method Summary collapse
Methods included from HTTP
#get_http_headers, #get_http_verb, #is_http_status_ok?
Instance Method Details
#receive_data(data) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/rupnp/ssdp/search_responder.rb', line 8 def receive_data(data) port, ip = peer_info log :debug, "#{self.class}: Receive data from #{ip}:#{port}" log :debug, data io = StringIO.new(data) h = get_http_verb(io) if h[:verb].upcase == 'NOTIFY' return end if h.nil? or !(h[:verb].upcase == 'M-SEARCH' and h[:path] == '*' and h[:http_version] == '1.1') log :warn, "#{self.class}: Unknown HTTP command: #{h[:cmd]}" return end h = get_http_headers(io) if h['man'] != '"ssdp:discover"' log :warn, "#{self.class}: Unknown MAN field: #{h['man']}" return end log :info, "#{self.class}: Receive M-SEARCH request from #{ip}:#{port}" callback = nil case h['st'] when 'ssdp:all' callback = Proc.new do send_response 'upnp:rootdevice' send_response "uuid:#{@device.uuid}" send_response "urn:#{@device.urn}" @device.services.each do |s| send_response "urn:#{s.urn}" end end when 'upnp:rootdevice' callback = Proc.new { send_response 'upnp:rootdevice' } when /^uuid:([0-9a-fA-F-]+)/ if $1 and $1 == @device.uuid callback = Proc.new { send_response "uuid:#{@device.uuid}" } end when /^urn:schemas-upnp-org:(\w+):(\w+):(\w+)/ case $1 when 'device' if urn_are_equivalent?(h['st'], @device.urn) callback = Proc.new { send_response "urn:#{@device.urn}" } end when 'service' if @device.services.one? { |s| urn_are_equivalent? h['st'], s.urn } callback = Proc.new { send_response h['st'] } end end end if callback if self.is_a? SSDP::MulticastConnection if h['mx'] mx = h['mx'].to_i # MX MUST not be greater than 5 mx = 5 if mx > 5 # Wait for a random time less than MX wait_time = rand(mx) EM.add_timer wait_time, &callback else log :warn, "#{self.class}: Multicast M-SEARCH request with no MX" + " field. Discarded." end else # Unicast request. Don't bother for MX field. callback.call end else log :debug, 'No response sent' end end |
#send_response(st) ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/rupnp/ssdp/search_responder.rb', line 87 def send_response(st) usn = "uuid:#{@device.uuid}" usn += case st when 'upnp:rootdevice', /^urn/ "::#{st}" else '' end response =<<EOR HTTP/1.1 200 OK\r CACHE-CONTROL: max-age = #{@options[:max_age]}\r DATE: #{Time.now.httpdate}\r EXT:\r LOCATION: http://#{@options[:ip]}/root_description.xml\r SERVER: #{USER_AGENT}\r ST: #{st} USN: #{usn}\r BOOTID.UPNP.ORG: #{@options[:boot_id]}\r CONFIGID.UPNP.ORG: #{@options[:config_id]}\r SEARCHPORT.UPNP.ORG: #{@options[:u_search_port]}\r \r EOR send_data response end |