0

NoMethodError: undefined method 'bytesize' 当我尝试通过 java 连接到我的 ruby​​ sinatra 服务器时出现错误。

这是我的 ruby​​ 代码,我怀疑我需要某种方法,它在客户端连接时运行,但我不确定:

require 'sinatra'

get '/hello' do
'this page displays hello'
end

get '/' do
'this page is the main page'
end

这是我的 java 应用程序的代码:

private static Socket connect;
private static OutputStream output;
private static InputStream input;

public static void main(String[] args) throws IOException {
    System.out.println("Connecting...");
    connect = new Socket(InetAddress.getByName("localhost"), 4567);
    System.out.println("Connected to: " + connect.getInetAddress().getHostName());

    output = new ObjectOutputStream(connect.getOutputStream());
    output.flush();

    //input = new ObjectInputStream(connect.getInputStream());
    System.out.println("Streams ready");
}
4

1 回答 1

0

我猜这是因为以下代码中的theory错误,以及您的 Java 客户端调用 Ruby 服务器中的错误:Racktheory

# Return the bytesize of String; uses String#size under Ruby 1.8 and
# String#bytesize under 1.9.
if ''.respond_to?(:bytesize)
  def bytesize(string)
    string.bytesize
  end
else
  def bytesize(string)
    string.size
  end
end
module_function :bytesize

那是在<rack>lib/rack/utils.rbSinatra 使用的文件中,这里是:

headers["Content-Length"] = body.inject(0) { |l, p| l + Rack::Utils.bytesize(p) }.to_s

那是在<sinatra>lib/sinatra/base.rb#finish方法中的文件中,在检查哪些测试calculate_content_length?

...无论如何,在#bytesize 方法中没有测试是否string为Nil...它只是在测试Ruby 引擎本身是否支持#bytesize。

换句话说,我猜你的 body 是Nil,或者不兼容的 Object 类型,它没有 #bytesize 方法,因为Rack没有测试,它只是假设进入该方法的数据是好的,并将方法调用传递给该对象,纯粹基于底层引擎......而不是基于 user_agent。那Rack理论错误。

进一步排除故障,我猜想在您的 Java 代码中存在特定于 user_agent 的东西,而不是您的 Ruby 代码。甚至不是真正的 user_agent,因为您似乎没有实例化“浏览器”,而只是打开了一个套接字连接。我猜你需要通过正式请求中的 HTTP 命令、符合 RFC 的协议等来实际调用服务器......所以你需要发送一个语法正确的标题和正文。

我已经看到这种事情发生在奇怪的客户端上,例如不发送正确标题的模糊爬虫,或者不发送正文而只发送标题。我会进一步进一步猜测打开 Socket 连接是不够的。您需要将标头和正文发送到服务器。我最终猜想您可能会使用类似于 acurl或 a的 Java 库,wget而不仅仅是操作原始套接字。这将为您提供适当的协议聊天,并从您的 Ruby/Sinatra 端点返回您正在寻找的内容。环顾四周,我发现:

JAVA 中的 cURL 等效项

于 2013-08-17T14:00:51.433 回答