Your response body must be wrapped in an Array:
return [200, {"Content-Type" => "text/html"}, ["Hello, World!"]]
Note the [
and ]
surrounding "Hello, World!"
. For an explanation of why the Array wrapper is needed, see:
Why is rack response body an array not a string?
And in particular, this section of the Python WSGI specification:
For large files, however, or for specialized uses of HTTP streaming (such as multipart "server push"), an application may need to provide output in smaller blocks (e.g. to avoid loading a large file into memory). It's also sometimes the case that part of a response may be time-consuming to produce, but it would be useful to send ahead the portion of the response that precedes it.
In these cases, applications will usually return an iterator (often a generator-iterator) that produces the output in a block-by-block fashion. These blocks may be broken to coincide with mulitpart boundaries (for "server push"), or just before time-consuming tasks (such as reading another block of an on-disk file).
That spec refers to Python, but the analogue in a Ruby Rack application is wrapping the HTTP response body in an Array (or any Enumerable which responds to the each
method).
EDIT: To address the original question's edit, about how to specifically serve an index.html
file, you can do that by reading the file and outputting its contents in the Rack response:
return [200, {"Content-Type" => "text/html"}, [File.read("index.html")]]
EDIT 2: While the above will work for showing index.html
only, if you want to serve an entire directory of static resources (JS, CSS, etc.) you can try using the Rack::Static middleware. See its documentation for details, but I think what you're trying to do could be accomplished with this:
require 'rack/static'
use Rack::Static, :urls => {"/" => 'index.html'}