2013-08-17 85 views
0

当我尝试通过java连接到我的ruby sinatra服务器时,出现错误NoMethodError: undefined method 'bytesize'NoMethodError:未定义的方法`bytesize'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"); 
} 
+0

正确?西纳特拉应用程序的工作,当你通过浏览器访问它? –

+0

@RossPenman是的,工作完全正常 – Cj1m

+0

你期望在Java代码中会发生什么?你不做任何HTTP请求。你为什么使用ObjectOutputStream? – matt

回答

0

我猜想这是因为theory错误Rack在下面的代码,在Ruby服务器的Java客户机调用了theory错误配对的发生:

# 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.rb ......这西纳特拉使用,在这里:

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

也就是说在#finish方法文件<sinatra>lib/sinatra/base.rb中,在支票测试calculate_content_length?

...无论如何,在#bytesize方法中,如果string是Nil,那么就没有测试...它只是测试一下,看看Ruby引擎本身是否支持#bytesize。

换句话说,我猜你的身体是Nil,或者是一种不兼容的Object,它没有#bytesize方法,因为Rack没有测试,它只是假定进入该方法的数据是好的,并将方法调用传递到该对象上,纯粹基于基础引擎...不基于user_agent。那是Rack理论错误。

进一步故障排除,我猜想有一些是你的Java代码中的user_agent特有的,而不是你的Ruby代码。甚至没有真正的user_agent,因为你似乎没有实例化一个'浏览器',而只是打开一个套接字连接。我猜你需要通过正式请求,RFC兼容协议等通过HTTP命令实际调用服务器......所以你需要发送一个语法正确的头文件和正文。

我见过这种事情发生在奇怪的客户端上,比如隐藏的抓取工具不发送正确的页眉,或者不发送正文和唯一的页眉。我进一步猜想,打开一个Socket连接是不够的。您需要将标题和正文发送到服务器。我终于猜测你可能会使用一个类似于curlwget的Java库,而不仅仅是操作原始套接字。那样会为你做适当的协议聊天,并且只是从你的Ruby/Sinatra端点把你想要的东西还给你。在这里有点环顾四周,我发现:

cURL equivalent in JAVA

+0

是的。回到你的问题后,我最好这样说:哪里有一个端点叫?甚至“/”是在PATH_INFO标头字段中显式调用的端点。下面的'Sinatra'和'Rack'没有任何反应。从技术上讲,这应该更优雅地失败,但它仍然可以通过使用实际的文本浏览器库,如我添加的链接解决。我看到马特在更仔细地阅读了关于您的原始问题的评论之后也提到了这一点。 – digitalextremist

相关问题