Tuesday, January 5, 2016

H2O version 1.7.0-beta1 released with enhanced mruby scripting, CGI, and much more

Today I am happy to announce that we have tagged the 1.7.0-beta1 release of H2O HTTP2 server. Among the changes, there are few ones that should be noted.

HTTP client in mruby #643

In 1.7, mruby support has ben enhanced so that handlers written in mruby can issue HTTP requests. And it is damn simple. Shown below is a full-fledged reverse proxy implementation using mruby.
mruby.handler: |
  Proc.new do |env|
    # copy headers
    headers = {}
    env.each do |key, value|
      if /^HTTP_/.match(key)
        headers[$'] = value
      end
    end
    # issue the request
    http_request(
      "http://app.example.com#{env["REQUEST_URI"]}",
      method:  env["REQUEST_METHOD"],
      headers: headers,
      body:    env["rack.input"],
    ).join
  end
H2O exports one ruby method named http_request. It takes a URL and a hash of optional parameters (e.g. method, headers, body) as the arguments, and returns immediately a handle to the request. All the network operations are handled asynchronously in the event loop of H2O.

When the mruby code calls the #join method, it returns a Rack response, either immediately (if available), or when the response headers become available. The returned body (3rd element of the response array) is an object that responds to #each; calling the method will yield the chunks of an HTTP response as they arrive.

Using the asynchronous nature of the HTTP client interface, it is possible to implement sophisticated server-side logic like Edge-side includes in very few lines of code; hopefully I will cover that in a different post.

Support for CGI #618

A FastCGI-to-CGI gateway script is included in the distribution. As shown in the example below, it is easy to create per-extention mapping to the gateway script to run CGI applications as they do on the Apache HTTP server.
file.custom-handler:
  extension: .cgi
  fastcgi.spawn:
    command: "exec share/h2o/fastcgi-cgi"
It also has the flexibility to limit the number of CGI processes running concurrently (by using --max-workers option), or to run CGI applications under different directories with different user privileges by specifying appropriate user names for each directory-level fastcgi.spawn configuration.

Support for Basic Authentication #624

The distribution also bundles a basic authenticator written in mruby. The configuration snippet below will be enough to understand how it should be configured.
mruby.handler: |
  require "#{$H2O_ROOT}/share/h2o/mruby/htpasswd.rb"
  Htpasswd.new("/path/to/.htpasswd", "realm-name")
file.dir: /path/to/secret-files
The script will also be a good reference for people learning how to write mruby handlers for H2O.

Support for wild-card hostnames #634

The server finally supports wild-card hostnames as well, which is essential if you have multiple wild-card certificates to be used.

5 comments: