问题
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