0

Because I am limited to working off a scripting environment of a packaged application with a restricted set of Ruby 1.9.3 base libraries, I can only use TCPSocket to access the internet. In particular, I cannot use net/http or json or uri...

Nonetheless, I would like to call an Azure ML Model Endpoint.

Below is what I am trying to do, but unfortunately I get an error from "socket.gets":

Errno::ECONNRESET (An existing connection was forcibly closed by the remote host. @ io_fillbuf - fd:3 )

require 'socket'

data =  '{
            "Inputs": {
              "data": [
                {
                  "Column1": "example_value",
                  "Column2": 0
                }
              ]
            },
            "GlobalParameters": {
              "method": "predict"
            }
          }'

# Send the HTTP request
socket = TCPSocket.open('xxxxx-ml-yyyyy.northeurope.inference.ml.azure.com', 443)
request = "POST 'xxxxx-ml-yyyyy.northeurope.inference.ml.azure.com HTTP/1.1\r\n"
request += "Host: xxxxx-ml-yyyyy.northeurope.inference.ml.azure.com\r\n"
request += "Content-Type: application/json\r\n"
request += "Authorization: Bearer 1234567890abcdefghjklmnopqrstuvwx\r\n"
request += "Content-Length: #{data.bytesize}\r\n"
request += "\r\n"
request += data
socket.print(request)

# Get the response
response = ""
while line = socket.gets
  response += line
end

# Close the socket
socket.close

puts response

(reproducible with irb 2.5.3)

Calling the Endpoint through Python from the same machine works perfectly. So I suppose smth is wrong with my HTTP request?

Ambro
  • 3
  • 2
  • You aren't connecting with TLS. – anothermh Apr 16 '23 at 08:55
  • @anothermh what does that mean? Would appreciate if you could elaborate more. Net is not my strong side, neither is ruby... So I am really struggling to establish this connection using low level coding only... – Ambro Apr 19 '23 at 18:52
  • Meanwhile, I have worked around the issue by just calling an external python script. But I'd still be interested to learn how to do it in low level ruby. – Ambro Apr 19 '23 at 18:56
  • You're making a raw TCP socket connection to port 443 and then sending it plaintext. That won't work. Port 443 is HTTPS and requires SSL/TLS to connect. Here's [an example of using SSL/TLS](https://stackoverflow.com/a/12838200/3784008). – anothermh Apr 19 '23 at 20:34

1 Answers1

-1

Try below code,

require 'net/http'
uri = URI('https://xxxxxxxxxxx.centralindia.inference.ml.azure.com/score')
data = <<~JSON {
  "data": [
    [1,2,3,4,5,6,7,8,9,10],
    [10,9,8,7,6,5,4,3,2,1]
  ],
"GlobalParameters": {
  "method": "predict"
    } 
}
JSON
res = Net::HTTP.post(uri, data, 'Authorization' => 'Bearer e3QYxI3Cxxxxxxxxxxxxxxxxxxx4NOcFFu','Content-Length' => '#{data.bytesize}', 'Content-Type' => 'application/json')
puts res.body

enter image description here

This is the result I got. I've verified this with postman also. enter image description here

JayashankarGS
  • 1,501
  • 2
  • 2
  • 6
  • 1
    Please do not post images of plaintext as [they are not appropriate on StackOverflow](https://meta.stackoverflow.com/a/285557/3784008). Please copy and paste plaintext into your answer. – anothermh Apr 19 '23 at 17:18
  • 1
    while I learned smth from your reply (I didnt know you can specify JSON like that), unfortunately it doesn't help, since I'm not allowed to use 'net/http' (as specified above) – Ambro Apr 19 '23 at 18:44
  • OP states in the first paragraph of their post *In particular, I cannot use net/http or json or uri* and here's an answer with both net/http and URI. – anothermh Apr 19 '23 at 20:35