Ruby TCPServer strange behavior in writing to client

别来无恙 提交于 2019-12-12 02:21:41

问题


I'm creating a Ruby gem named EmeraldCutter which is, essentially, a very simple TCP server. It happens that I detected a very strange behavior and I'd be very glad if someone could give me some clue about this.

As you may see by the code below, it starts a new Thread for each request received, grabs the message sent to the server, separate its parameters and stores them in a hash and then writes to the client a list with the elements of this hash in a list of the form

key => parameter

Then when I run this server and navigate to http://localhost:4321/something my browser should receive something like

http_verb => GET
query_string => /something
http_version => HTTP/1.1
host => localhost:4321
connection => keep-alive
cache_control => max-age=0
accept => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
upgrade_insecure_requests => 1
user_agent => Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
dnt => 1
accept_encoding => gzip, deflate, sdch
accept_language => pt-BR,pt;q=0.8,en-US;q=0.6,en;q=0.4,fr-CA;q=0.2,fr;q=0.2

but nothing is displayed and when I visit the Network tab at the developer's console to examine this request, I see a message saying Failed to load response data.

Here is my code:

lib/emerald.rb

require "emeraldcutter/auxiliary"
require "emeraldcutter/version"

module EmeraldCutter

  def self.start
    require 'socket'

    server = TCPServer.new 4321
    loop do 
      Thread.start(server.accept) do |client|
        message = client.recvmsg[0]
        request = get_request_parameters(message)
        request.each{ |k,v| client.puts "#{k} => #{v}" }
        client.close
      end
    end
  end

  private

  def self.http_verb(msg_token)
    msg_token.split(' ')[0]
  end

  def self.http_protocol(msg_token)
    msg_token.split(' ')[2]
  end

  def self.query_string(msg_token)
    msg_token.split(' ')[1]
  end

  def self.get_request_parameters(message)
    result = Hash.new
    lines = message.split("\n");
    first_line = lines.shift
    result['http_verb'] = http_verb(first_line)
    result['query_string'] = query_string(first_line)
    result['http_version'] = http_protocol(first_line)
    lines.each{ |line|
      key_value = line.split(': ')
      key = EmeraldCutter::Auxiliary.normalize_hash_key(key_value[0].strip)
      result[key] = key_value[1].strip if not key.empty?
    }
    result
  end

end

lib/emeraldcutter/auxiliary.rb

module EmeraldCutter
  module Auxiliary

    def self.normalize_hash_key(key)
      key.downcase.tr('-','_')
    end

  end
end

This wouldn't be so strange. But things get really weird when I add client.puts "Teste" to the Thread block like this

    server = TCPServer.new 4321
    loop do 
      Thread.start(server.accept) do |client|
        client.puts "Test"
        message = client.recvmsg[0]
        request = get_request_parameters(message)
        request.each{ |k,v| client.puts "#{k} => #{v}" }
        client.close
      end
    end
  end

and then it works perfectly well and I get

Test
http_verb => GET
query_string => /something
http_version => HTTP/1.1
host => localhost:4321
connection => keep-alive
cache_control => max-age=0
accept => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
upgrade_insecure_requests => 1
user_agent => Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
dnt => 1
accept_encoding => gzip, deflate, sdch
accept_language => pt-BR,pt;q=0.8,en-US;q=0.6,en;q=0.4,fr-CA;q=0.2,fr;q=0.2

Have you ever seen something like this? If so, what is the reason?

来源:https://stackoverflow.com/questions/37823161/ruby-tcpserver-strange-behavior-in-writing-to-client

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!