我正在尝试通过 ruby TCPSocket 与 HiveServer2 通信。根据 Thrift SASL 规范,我发送 START 消息,然后发送普通身份验证信息。服务器返回 COMPLETE 状态,有效负载为空。它应该将挑战作为有效负载返回,但返回一个空字符串。
START = 0x01
OK = 0x02
COMPLETE = 0x05
auth = 'PLAIN'
header = [START, auth.length].pack('cl>')
auth_string = ['anonymous'].pack('u')
auth_message = "[LOGIN] \u0000 #{auth_string} \u0000 #{auth_string}"
auth_header = [OK, auth_message.length].pack('cl>')
socket = TCPSocket.new localhost, 10000
socket.write header + auth
socket.write auth_header + auth_message
socket.read(5).unpack('cl>')
=> [5,0]
HiveServer2 返回 5 状态,即 COMPLETE。由于服务器不再返回任何内容,因此无法通过此套接字进行进一步的通信。
我怀疑 auth_message 以错误的方式构造或其他错误。
谁能建议 HiveServer2 理解我的请求的方式?
任何帮助将不胜感激。
UPD:节俭 SASL 规范
UPD2:已解决!STARTTLS 块应如下所示:
START = 0x01
OK = 0x02
COMPLETE = 0x05
auth = 'PLAIN'
header = [START, auth.length].pack('cl>')
auth_message = "[ANONYMOUS]\u0000anonymous\u0000anonymous"
auth_header = [OK, auth_message.length].pack('cl>')
socket = TCPSocket.new localhost, 10000
socket.write header + auth
socket.write auth_header + auth_message
socket.read(5).unpack('cl>')
=> [5,0]
从服务器收到 COMPLETE 状态后,我可以使用 TCLIService::Client 与 HiveServer2 进行通信。只有一件事需要注意:
所有对底层传输的写入都必须以有效负载数据的 4 字节长度为前缀,然后是有效负载。从此传输中的所有读取都应读取 4 字节长度的字,然后读取此长度字指定的全部字节数。