Project

General

Profile

Feature #11266

[PATCH] WEBrick: allow subclassing of Response and Request

Added by julik (Julik Tarkhanov) almost 5 years ago. Updated over 1 year ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:69604]

Description

To properly support the Rack specification features introduced in 2013, a number of features is needed in HTTPResponse.

  • The Response should be able to handle it's socket to the given proc for writing (the socket control should be transferred to another routine). This is required for rack.hijack to work.
  • The Response assumes an "IO pull" model via read()/readpartial() for grabbing data from the body. Rack assumes a "push" model for writing the response, so having the ability to take over the socket is better for Rack as well. We can make a Fiber-based adapter to let an iterable object present itself like an IO to WEBrick but having direct socket control is much easier.
  • The Response should be able to take control of the chunking. This is currently done as a monkeypatch in Rack, but we much rather have it contained in the Response objects used by the Rack-supplied server handler.

Rack currently solves it by giving WEBrick the read end of an IO pipe, which has a side effect of buffering the entire response even when direct socket operation is needed. This creates a situation where no Rack-based streaming servers can function (no long-polling, no server-sent-events, no large streamed responses via HTTP/FTP adapters etc.)

Since all the three of those require patches to the HTTPResponse, a better approach would be to let the Server object create the right Response and let that response deal with the socket in a way it sees fit. This, however, is impossible at the moment because HTTPResponse and HTTPRequest are hardcoded in the main Server loop code, so if you want to override them with your implementations you have to override the entire service() method.

If we let the Server object instantiate the Response and Request in it's own separate method a Server subclass could use customized versions of those. Pretty much the only downside is one extra method call per HTTP request. Rack could then use it's own Server subclass with the right Response and Request objects in place.

I will be happy to provide a patch.


Files

custom_req_response.patch (3.25 KB) custom_req_response.patch julik (Julik Tarkhanov), 06/16/2015 12:47 PM
req_response_sub2.patch (2.54 KB) req_response_sub2.patch julik (Julik Tarkhanov), 06/19/2015 09:39 AM

Updated by julik (Julik Tarkhanov) almost 5 years ago

Patch against current trunk, should be backportable.

Updated by julik (Julik Tarkhanov) almost 5 years ago

  • Subject changed from WEBrick: allow subclassing of Response and Request to [PATCH] WEBrick: allow subclassing of Response and Request

Updated by nobu (Nobuyoshi Nakada) almost 5 years ago

Any reason to create both together in create_request_and_response?

Updated by julik (Julik Tarkhanov) almost 5 years ago

No specific reason, only to make the changes to the library smaller. They certainly can be separate methods.

Updated by julik (Julik Tarkhanov) over 4 years ago

Nobu, is there something else I can do?

Updated by nobu (Nobuyoshi Nakada) over 4 years ago

  • Status changed from Open to Assigned
  • Assignee set to nahi (Hiroshi Nakamura)

Updated by julik (Julik Tarkhanov) over 4 years ago

Is there still anything I can do/change?

Updated by julik (Julik Tarkhanov) almost 4 years ago

It has been a year. Is there still anything I can do/change?

Updated by naruse (Yui NARUSE) almost 4 years ago

  • Assignee changed from nahi (Hiroshi Nakamura) to 11083

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) over 3 years ago

+1 Since WEBrick is part of stdlib, being able to use it in a generic test server which supported Rack hijack would be great as such requests could be tested without any sort of mocking.

Updated by julik (Julik Tarkhanov) over 1 year ago

It has been... a very long time. Nobu, is there something else I can do?

#13

Updated by normalperson (Eric Wong) over 1 year ago

  • Status changed from Assigned to Closed

Applied in changeset trunk|r66452.


webrick: add the ability to override res, req creation

So that a customized HTTPServer subclass can use it's own
Request/Response classes.

To apply the override, make a subclass of WEBrick::HTTPServer
and override the
create_request_and_response(with_webrick_config) method. The
method should return an Array of [request, response].

To check whether the Server supports this method (i.e. when
using older versions of WEBrick when needing this
functionality), you can ask the server if it responds to the
method

server.respond_to?(:create_request_and_response)

This is backportable.

[ruby-core:69604] [Feature #11266]

From: Julik Tarkhanov me@julik.nl

Updated by normalperson (Eric Wong) over 1 year ago

me@julik.nl wrote:

It has been... a very long time. Nobu, is there something else I can do?

https://bugs.ruby-lang.org/issues/11266#change-74992

Committed as r66452. Sorry for the delays, I wasn't webrick
maintainer at the time this was brought up so I missed it.

In the future, ping us every week or so to get more people to notice
it. And feel free to Cc: me on webrick or any changes I've been
responsible for in the past. Thanks.

Also available in: Atom PDF