简单的ruby TCP请求没有命中服务器

时间:2016-05-25 00:05:47

标签: ruby-on-rails ruby sockets tcp websocket

我有一个简单的ruby脚本通过TCP连接将文件上传到服务器/网络应用程序但它不起作用。当我运行脚本时,Web应用程序/服务器端没有任何反应。服务器工作正常,因为我有试图用CURL上传文件,它确实上传了。看看我下面的代码,让我知道我做错了什么。我正在使用ruby 1.9.2-p290。谢谢你提前。

require 'socket'   

host = "myapp.herokuapp.com"
port = 80

client = TCPSocket.open(host, port)

client.print("POST /api/binary HTTP/1.1\r\n")
client.print("Host: myapp.herokuapp.com\r\n")
client.print ("Accept: */* \r\n")
client.print ("Content-Type: multipart/form-data;boundary=AaB03x \r\n")


client.print("\n" + "AaB03x"+ "\n" "Content-Disposition: form-data; name='datafile'; filename='cam.jpg' \n Content-Type: image/jpeg \r\n")
client.print ("\r\n")
data = File.open("./pic.jpg", "rb") {|io| io.read}
client.print (data)
client.print ("\r\n") 
client.print("boundary=AaB03x\r\n")

client.close

IRB控制台

>require 'socket'
 => true 
>  client = TCPSocket.open("myapp.herokuapp.com", 80)
 => #<TCPSocket:fd 3>
> client.print("GET /api/users HTTP/1.1")
  => nil 
> client.print("POST /api/binary HTTP/1.1")
  => nil 

1 个答案:

答案 0 :(得分:1)

您需要确保发送有效的HTTP请求。

  1. 您需要Content-Length标头。这意味着您需要提前组装主体,以便确定标题的长度,然后发送正文。如果你弄错了,服务器最终可能会阻止尝试读取更多未输入的内容。

  2. 您的多部分边界需要修复。它们应以--开头,然后是标题中的标记:--AaB03x。最后一个也应以--结尾:--AaB03x--。确保标题中没有尾随空格,这可能会导致问题。

  3. 其他一些可能不会阻止请求被解析的东西,但你应该整理一下:

    1. 标题中的换行符应为\r\n,而不仅仅是\n

    2. 标题行之前不应有任何空格。

    3. require 'socket'   
      
      host = "myapp.herokuapp.com"
      port = 80
      
      client = TCPSocket.open(host, port)
      
      # Write out the headers.
      client.print("POST /api/binary HTTP/1.1\r\n")
      client.print("Host: myapp.herokuapp.com\r\n")
      client.print ("Accept: */* \r\n")
      # Note: no trailing whitespace.
      client.print ("Content-Type: multipart/form-data;boundary=AaB03x\r\n")
      
      # Assemble the body.
      # Note \r\n for all line endings, body doesn't start with newline.
      # Boundary marker starts with '--'.
      body = "--AaB03x\r\n"
      body << "Content-Disposition: form-data; name='datafile'; filename='cam.jpg'\r\n"
      # Header starts at left of line, no leading whitespace.
      body << "Content-Type: image/jpeg\r\n"
      body << "\r\n"
      data = File.open("./pic.jpg", "rb") {|io| io.read}
      body << data
      body << "\r\n"
      # Final boundary marker has trailing '--'
      body << "--AaB03x--\r\n"
      
      # Now we can write the Content-Length header, since
      # we now know the size of the body.
      client.print "Content-Length: #{body.bytesize}\r\n"
      # Blank line.
      client.print "\r\n"
      # Finally write out the body.
      client.print body
      
      # In reality you would want to parse the response from
      # the server before closing the socket.
      client.close