Ruby undefined method `bytesize' for #<Hash:0x2954fe8>
Asked Answered
A

5

24

i have the following Ruby Code, for a tracking website in sandbox mode:

require "net/http"
require "net/https"
require "uri"

xml = <<XML
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?><data appname="dhl_entwicklerportal" language-code="de" password="Dhl_123!" request="get-status-for-public-user"><data piece-code="00340433836536550280"></data></data>
XML

uri = URI('https://cig.dhl.de/services/sandbox/rest/sendungsverfolgung')

nhttp = Net::HTTP.new(uri.host, uri.port)
nhttp.use_ssl=true
nhttp.verify_mode=OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(uri)
request.basic_auth 'xpackageWP', 'hidden'
response = nhttp.start {|http|
http.request(request, xml:xml)
}

puts response.body

I always get the error :

d:/Ruby200/lib/ruby/2.0.0/net/http/generic_request.rb:179:in `send_request_with_body' undefined method `bytesize' for #<Hash:0x2954fe8> (NoMethodError)
from d:/Ruby200/lib/ruby/2.0.0/net/http/generic_request.rb:130:in `exec'
from d:/Ruby200/lib/ruby/2.0.0/net/http.rb:1404:in `block in transport_request'
from d:/Ruby200/lib/ruby/2.0.0/net/http.rb:1403:in `catch'
from d:/Ruby200/lib/ruby/2.0.0/net/http.rb:1403:in `transport_request'
from d:/Ruby200/lib/ruby/2.0.0/net/http.rb:1376:in `request'
from D:/Dropbox_5BHIF/Dropbox/TempDHL/Main.rb:17:in `block in <main>'
from d:/Ruby200/lib/ruby/2.0.0/net/http.rb:852:in `start'
from D:/Dropbox_5BHIF/Dropbox/TempDHL/Main.rb:16:in `<main>'

I tried really hard to solve this, but i cannot think of any problem. When i test it in the Browser with the Link and then a ?xml= it works perfectly, so it seems to be a problem with my Ruby Code.

Arterial answered 15/2, 2014 at 15:50 Comment(1)
do you submit an xml along with a GET request??Hydrotherapeutics
A
44

You're sending post data as a hash. You should encode it as string.

For example Using URI::encode_www_form:

request = Net::HTTP::Post.new(uri)
...
response = nhttp.start do |http|
  post_data = URI.encode_www_form({xml: xml})
  http.request(request, post_data)
end

UPDATE If you want GET request, append the query string to the url.

post_data = URI.encode_www_form({xml: xml})
uri = URI('https://cig.dhl.de/services/sandbox/rest/sendungsverfolgung?' +
          post_data)

...

response = nhttp.start do |http|
  http.request(request)
end
Antonyantonym answered 15/2, 2014 at 15:57 Comment(2)
Thanks, that solves my problem, but generates a new one ^^ Probably you can help me with this too: The server expects the following format: https ://cig.dhl.de/services/sandbox/rest/sendungsverfolgung/?xml=<XML_CODE> i thought that this will achieve that, but obviously it doesnt. Do you have a solution for that too?Arterial
@Crusader633, I updated the answer. BTW, are you sure the server expect GET ?Antonyantonym
P
2

request expects a string for its second argument, on which it invokes bytesize. You're giving it a hash, which doesn't respond to bytesize.

Pasahow answered 15/2, 2014 at 15:53 Comment(1)
how should i change my request? The browser needs the following format : link?xml=<XML> ... i cant think off how else to achieve thatArterial
H
1

Use POST and not GET request

xml = <<XML
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?><data 

appname="dhl_entwicklerportal" language-code="de" password="Dhl_123!" request="get-status-for-public-user"><data piece-code="00340433836536550280"></data></data>
XML

uri = URI('https://cig.dhl.de/services/sandbox/rest/sendungsverfolgung')

nhttp = Net::HTTP.new(uri.host, uri.port)
nhttp.use_ssl=true
nhttp.verify_mode=OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(uri)
request.body = xml
request.basic_auth 'xpackageWP', 'hidden'
response = nhttp.start {|http|
  http.request(request)
}
Hydrotherapeutics answered 15/2, 2014 at 16:0 Comment(0)
K
0

I solved by using .to_s, it returns a 200.

@client.job.create_or_update(job_name, job_xml.get_xml.to_s)

This is Jenkins API client what I'm currently using: https://github.com/arangamani/jenkins_api_client

Kozloski answered 16/9, 2016 at 6:21 Comment(0)
B
0

I had a similar issue when testing POST/GET requests using rack/test. In my case the responding controller didn't respond to GET request with JSON, but a Hash.

Seems that POST requests need to call .to_s on the data being sent, and GET requests on the data being received. Makes sense though.

Button answered 13/11, 2023 at 1:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.