jnunemaker / httparty

:tada: Makes http fun again!
MIT License
5.8k stars 964 forks source link

Response nil when empty body #225

Closed jandudulski closed 11 years ago

jandudulski commented 11 years ago

I need to handle case when I'm receiving just headers with empty body, but HTTParty returns just nil instead of Response object (as far I've debugged that nil is returned here) so I'm not able to read headers.

Expected result: return Response object with empty body and parsed headers.

jandudulski commented 11 years ago

I found out that nil is truly HTTParty::Response object, just by inspect is displayed as nil which confused me. Maybe you should consider better handling for such a case?

mamlukishay commented 10 years ago

thanks

mrhead commented 9 years ago

Oh. This is really, really confusing.

@jnunemaker would you consider changing this behaviour?

jnunemaker commented 9 years ago

I'm open to PR's, but this was added for a reason so I'm not sure what would be a good change.

DougPuchalski commented 8 years ago

@jnunemaker What's the reason? It seems important to be able to read HTTP status for a header-only response.

jnunemaker commented 8 years ago

Sorry, to be clear, always returning a response object no matter what and lazily parsing the body was added for a reason. If you just want to check the status code, you shouldn't have to read the whole body. That is why things work the way they do. @aceofspades are you hitting an issue where you cannot check the status code on a request for an empty body?

DougPuchalski commented 8 years ago

@jnunemaker I'm getting a nil response, not an object, when the body is a blank string.

jnunemaker commented 8 years ago

Can you provide a script that I can run to inspect/debug?

DougPuchalski commented 8 years ago

@jnunemaker https://gist.github.com/aceofspades/f6806f4867f688e6f2d1

jnunemaker commented 8 years ago

@aceofspades what version are you using? I just installed latest and tested in irb and I get a response, not nil.

Fetching: httparty-0.13.7.gem (100%) httparty-0.13.7.gem
When you HTTParty, you must party hard!
Successfully installed httparty-0.13.7
1 gem installed
11:32 ~ $ irb -r rubygems -r httparty
irb(main):001:0> class MyClass
irb(main):002:1>   include HTTParty
irb(main):003:1> 
irb(main):004:1*   def self.post
irb(main):005:2>     super("http://example.com/", body: "hello world")
irb(main):006:2>   end
irb(main):007:1> end
=> :post
irb(main):008:0> response = MyClass.post
=> #<HTTParty::Response:0x7fa69c15b248 parsed_response="<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <style type=\"text/css\">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n        \n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 50px;\n        background-color: #fff;\n        border-radius: 1em;\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        body {\n            background-color: #fff;\n        }\n        div {\n            width: auto;\n            margin: 0 auto;\n            border-radius: 0;\n            padding: 1em;\n        }\n    }\n    </style>    \n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is established to be used for illustrative examples in documents. You may use this\n    domain in examples without prior coordination or asking for permission.</p>\n    <p><a href=\"http://www.iana.org/domains/example\">More information...</a></p>\n</div>\n</body>\n</html>\n", @response=#<Net::HTTPOK 200 OK readbody=true>, @headers={"accept-ranges"=>["bytes"], "cache-control"=>["max-age=604800"], "content-type"=>["text/html"], "date"=>["Mon, 18 Jan 2016 16:32:55 GMT"], "etag"=>["\"359670651\""], "expires"=>["Mon, 25 Jan 2016 16:32:55 GMT"], "last-modified"=>["Fri, 09 Aug 2013 23:54:35 GMT"], "server"=>["EOS (lax004/2813)"], "content-length"=>["1270"], "connection"=>["close"]}>
irb(main):009:0> response
=> #<HTTParty::Response:0x7fa69c15b248 parsed_response="<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <style type=\"text/css\">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n        \n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 50px;\n        background-color: #fff;\n        border-radius: 1em;\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        body {\n            background-color: #fff;\n        }\n        div {\n            width: auto;\n            margin: 0 auto;\n            border-radius: 0;\n            padding: 1em;\n        }\n    }\n    </style>    \n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is established to be used for illustrative examples in documents. You may use this\n    domain in examples without prior coordination or asking for permission.</p>\n    <p><a href=\"http://www.iana.org/domains/example\">More information...</a></p>\n</div>\n</body>\n</html>\n", @response=#<Net::HTTPOK 200 OK readbody=true>, @headers={"accept-ranges"=>["bytes"], "cache-control"=>["max-age=604800"], "content-type"=>["text/html"], "date"=>["Mon, 18 Jan 2016 16:32:55 GMT"], "etag"=>["\"359670651\""], "expires"=>["Mon, 25 Jan 2016 16:32:55 GMT"], "last-modified"=>["Fri, 09 Aug 2013 23:54:35 GMT"], "server"=>["EOS (lax004/2813)"], "content-length"=>["1270"], "connection"=>["close"]}>
irb(main):010:0> response.nil?
=> false
DougPuchalski commented 8 years ago

@jnunemaker Did you try running is through rspec in my gist? How are you ensuring the blank body as the response in your example?

jnunemaker commented 8 years ago

@aceofspades I don't trust webmock and those. I want to see an actual httparty call against an actual service so I can avoid an rabbit holes. I don't want to end up debugging a bunch of tools in the middle. Does that make sense?

jnunemaker commented 8 years ago

I still don't understand how your example is testing the condition of the server returning a blank body.

Yeah, it might not be. I think I misunderstood what you were trying to do and should have explained that on my last response. I thought that you were just using rspec for repeatability and that the request would return an empty body with or without rspec and webmock.

In the past, people have had issues like this and it feels like every time it came down to something unique about their setup or some dependency. When I asked for a script, I was asking for a script I could run that would use straight httparty to hit an endpoint and reproduce the issue. I don't want to use a script with dependencies as the issue could be in the dependency and I'm really tired of debugging dependency issues. I'm not saying that something isn't wrong with httparty, but I would like a good example showing what is wrong that doesn't use other things that could be wrong. Does that make it more clear? Sorry if I wasn't clear on the last response.

jnunemaker commented 8 years ago

If you're not willing to even look at it, I'm not going to be able to justify spending any more time.

Also, I am and have been looking at everything you've thrown my way. I pulled down the gist and played with it in irb.

Is the issue your having happening against a live service or against something in rspec/webmock?

arielperez82 commented 8 years ago

@jnunemaker I'm having the same exact problem however, when I run a clean example in IRB, it works. Digging through my set up to see if I can find out why I get a nil response when running my application.

arielperez82 commented 8 years ago

Seems to be related to Issue 285. When running this in Rails, the Response returned is nil yet, it still responds to methods in Response like code, success?, etc..., which is extremely confusing.

typeoneerror commented 7 years ago

Experiencing same issue as @arielperez82. An API that has a 204 response (no content) results in the following (for example, posting to the events API on Drip https://www.getdrip.com/docs/rest-api#events):

> result = self.class.post(url, options)
> result
=> nil
> result.code
=> 204
> result.class
=> HTTParty::Response

So result seems to be an HTTParty::Response, but also...kind of nil? I get that you don't need to see a body for that, but result should probably be '' in this case rather that nil to avoid confusion.

lexsoul commented 7 years ago

If someone still have this issue, what it worked for me was to downgrade to version 0.13.7 gem install httparty -v 0.13.7 Hope it helps.

lalaflying commented 6 years ago

Having the same issue here. Tested with the latest version Version: 0.16.0 I have using wireshark to verify the request/response. The resposne is a 204 response with the empty body. I want to parse out from the response header, but get nil for response object.

downgrade to 0.13.7 won't work for me, due to the json version conflicts Unable to activate httparty-0.13.7, because json-2.1.0 conflicts with json (~> 1.8) (Gem::ConflictError)

jwomble commented 6 years ago

I'm running into this also. You don't need to consume a live API to reproduce the behavior, just instantiate a HTTParty::Response object:

it "should handle responses with an empty body" do
      put_request = HTTParty::Request.new Net::HTTP::Put, '/some_path', {body:""}
      put_response_object = Net::HTTPNoContent.new('1.1', 204, 'no content')
      put_response_object['last-modified'] = Date.new(2010, 1, 15).to_s
      put_response_object['content-length'] = '1024'
      allow(put_response_object).to receive_messages(body: "")

      put_response = HTTParty::Response.new(put_request, put_response_object, @parsed_response)

      expect(put_response.code).to be(204)
      expect(put_response).not_to be_nil
    end

This will fail on the second expect()

knepprath commented 6 years ago

Wasted an afternoon on this trying to figure out why the response is nil in the debugger, only to find out that the response.code was 202. 🤦‍♂️