Content-Length for Sinatra file steaming - ruby

I am trying to set the Content-Length header before I stream a file out to the client. I am setting it with:
response.headers['Content-Length'] = "12341234"
and then i do something like:
steam do |out|
file_chunks.each do |chunk|
out << chunk
end
out.close
end
However when I attempt to down the file in a browser the Content-Length header is blank. Does anyone know whether this is a Sinatra issue or a Passenger/Apache issue?
I assume whats happening is some layer between this block of code and when the response actually gets sent it seeing that it first sends the headers and the data block is empty so it assumes a content-length of 0 even though I set it explicitly.
Is there another way to tell the browser how big the file is that I'm sending it?
EDIT
Looks to be a passenger problem not a Sinatra problem. If I run the server with thin the Content-Length is passed correctly. I guess the question changes to not change the Content-Length if it is already set?

The issue here is that when using Transfer-Encoding:chunked, the Content-Length header is omitted.
See : http://greenbytes.de/tech/webdav/rfc2616.html#rfc.section.4.4

This is a Sinatra issue. Its stream API only supports EventMachine-based servers. In other words, the API only supports Thin. When using Passenger you should bypass the Sinatra stream API, and you should stream an HTTP response directly by using the Rack socket hijacking API, which is supported by Phusion Passenger. Here is an example which demonstrates how to use the Rack socket hijacking API to stream Server Sent Events on Phusion Passenger.

Related

Get request with curl works but Net::HTTP and OpenURI fail

My Rails application regularly polls partners' ICS files and sometimes it fails for no reason whatsoever. When I do:
curl https://www.airbnb.es/calendar/ical/234892374.ics?s=23412342323
(params #'s faked here)
I get output matching the content of the ICS file. Just opening it in the browser works fine as well.
When I use:
Net::HTTP.get(URI(a.ics_link))
I get a "503 Service Temporarily Unavailable" response. I also tried the same with OpenURI with similar results.
Why is it that the server is treating requests from curl or a browser differently?
Is there some way to get Ruby to get around this?
It's an https issue... not sure why, but switch your url in Ruby to https and it should work.

gSoap caches error response in FCGI mode

We are using gSoap compiled with the WITH_FASTCGI flag. The resulting soap FCGI server is processing (successive) SOAP packets OK, but there is a problem with the error responses.
The first time an error response is created everything works OK. But all subsequent SOAP packets that result in an error will show that first response again, even if the error is different.
I had a quick look through the source code. The stdsoap2.cpp:soap_set_fault(struct soap *soap) seems to simply return if a faultstring has already been set in the soap structure that is being used, rather than update it. This being a FCGI server, gSoap re-uses the soap structure you start it with for each SOAP request so it looks like this is not being cleared properly.
Is there anyone else having similar problems?

Net::ReadTimeout with local URI

I'm trying to understand why is the following method is blocking my app.
url = 'http://192.168.1.33/assets/my_small_pic.jpg'
image_file = open(url).read
It's working perfectly when I try it in the console. But when I do it from an API method, it blocks my app and after a long while I have the following error:
Net::ReadTimeout (Net::ReadTimeout)
What does my app not like my way of reading the file?
I assume you're using 'open-uri' and the api is a part of the same RoR app where you're sending the request to. In this case your app is just being blocked by the first request while you send a second request to it so the second request gives a timeout. You should see this issue in development only. In production things will be a bit different since static assets to be served by the Nginx or Apache. Additionally Rails 4 is by default is thread safe in production which means it can serve multiple requests at a time. So if you're on Rails4 then in production calls to other apis will work as well. For Rails3 you would have to explicitly specify config.threadsafe!
In general I would recommend you to access resources or make any other API calls from the same app directly. It's more efficient. In your example above you can read the file like this:
File.read(File.join(Rails.root, 'public/assets/my_small_pic.jpg'))
If you still want to send the request then to make it work in development you have to start a new thread similar to this:
Thread.new do
open('http://192.168.1.33/assets/my_small_pic.jpg').read
end

XML-RPC over SSL with Ruby: end of file reached (EOFError)

I have some very simple Ruby code that is attempting to do XML-RPC over SSL:
require 'xmlrpc/client'
require 'pp'
server = XMLRPC::Client.new2("https://%s:%d/" % [ 'api.ultradns.net', 8755 ])
pp server.call2('UDNS_OpenConnection', 'sponsor', 'username', 'password')
The problem is that it always results in the following EOFError exception:
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/protocol.rb:135:in `sysread': end of file reached (EOFError)
So it appears that after doing the POST, I don't get anything back. Interestingly, this is the behavior I would expect if I tried to make an HTTP connection on the HTTPS port (or visa versa), and I actually do get the same exact exception if I change the protocol. Everything I've looked at indicates that using "https://" in the URL is enough to enable SSL, but I'm starting wonder if I've missed something.
Note that Even though the credentials I'm using in the RPC are made up, I'm expecting to at least get back an XML error page (similar to if you access https://api.ultradns.net:8755/ with a web browser). I've tried running this code on OSX and Linux with the exact same result, so I have to conclude that I'm just doing something wrong here. Does anyone have any examples of doing XML-RPC over SSL with Ruby?
http://www.ultradns.net/api/NUS_API_XML.pdf explicitly states that the protocol is not compatible with standard XML-RPC clients. You need to add a toplevel transaction and session tag on top of method call.
<transaction>
<methodCall>
...
</methodCall>
</transaction>
So I guess the ruby xml-rpc parser is just not being able to parse the response. Just a theory. Have your tried other xml-rpc clients?

Debug static file requests from IIS6

How can I debug what is being returned by IIS(6) when the response goes through proxies before getting to the browser?
I have requests for static files which are being sent with the 'Accept-encoding: gzip' header. These are being gzipped correctly. However, if a 'Via: ' header (to redirect the response via a proxy) is also included the content is not received gzipped by the browser.
I want to know if the issue is with IIS not applying the compression or related to something the proxy is doing.
How can I investigate this problem?
This is related to IIS6 not doing gzip compression when including Via header in request.
In case anyone else hits this problem i believe it's due to the "HcNoCompressionForProxies" option, configurable in the metabase. It specifically lets you disable compression for proxied requests.
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/05f67ae3-fab6-4822-8465-313d4a3a473e.mspx?mfr=true
If your still interested my answer would be install Fiddler probably on the client first. For HTML snooping you can't do much better.
That would be my first port of call.

Resources