rack-devel archive mirror (unofficial) https://groups.google.com/group/rack-devel
 help / color / mirror / code / Atom feed
* rational for rewind()
@ 2014-05-22 21:12 Torsten Robitzki
  2014-05-23 10:46 ` Magnus Holm
  2014-07-17 22:34 ` Eric Wong
  0 siblings, 2 replies; 11+ messages in thread
From: Torsten Robitzki @ 2014-05-22 21:12 UTC (permalink / raw)
  To: rack-devel

[-- Attachment #1: Type: text/plain, Size: 1207 bytes --]

Hello,
I'm implementing a C++ comet web server, that (tries) to implement rack to 
adapt ruby applications. Currently I'm reading a body very naively put the 
body into a ruby String and wrap it with a StringIO to provide the 
rack.input for the implementation. As I'm going to use the server for 
uploading images, I would like to implement a real, stream-like object to 
circumvent the need to buffer the POST body before handing it to the 
application.

Now, I've read the rack specs and read about rewind(). To implement 
rewind(), I would have to store the whole body, even when the upstream 
application just calculates some kind of checksum on the body, or uploads 
it to s3. What's the rational behind this part of the specification? Is it 
possible to not implement rewind() and to tell applications that need 
rewind(), to keep there own copy of the body, in case it is needed? 

kind regards,
Torsten

-- 

--- 
You received this message because you are subscribed to the Google Groups "Rack Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rack-devel+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

[-- Attachment #2: Type: text/html, Size: 1476 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rational for rewind()
  2014-05-22 21:12 rational for rewind() Torsten Robitzki
@ 2014-05-23 10:46 ` Magnus Holm
  2014-05-24 12:35   ` Torsten Robitzki
  2014-07-17 22:34 ` Eric Wong
  1 sibling, 1 reply; 11+ messages in thread
From: Magnus Holm @ 2014-05-23 10:46 UTC (permalink / raw)
  To: rack-devel

On Thu, May 22, 2014 at 11:12 PM, Torsten Robitzki <Torsten@robitzki.de> wrote:
> Hello,
> I'm implementing a C++ comet web server, that (tries) to implement rack to
> adapt ruby applications. Currently I'm reading a body very naively put the
> body into a ruby String and wrap it with a StringIO to provide the
> rack.input for the implementation. As I'm going to use the server for
> uploading images, I would like to implement a real, stream-like object to
> circumvent the need to buffer the POST body before handing it to the
> application.
>
> Now, I've read the rack specs and read about rewind(). To implement
> rewind(), I would have to store the whole body, even when the upstream
> application just calculates some kind of checksum on the body, or uploads it
> to s3. What's the rational behind this part of the specification? Is it
> possible to not implement rewind() and to tell applications that need
> rewind(), to keep there own copy of the body, in case it is needed?
>
> kind regards,
> Torsten

One word: Middleware.

Some middleware need to access the HTTP body (e.g. for fetching the
CSRF-token from a POST-parameter). In order to allow middleware to
process HTTP bodies, rewind() was added.

Yes, we are all aware of the issues it present. Yes, it sucks.

Yes, you can implement a server which doesn't support rewind(), but it
won't work with many middleware.

// Magnus Holm

-- 

--- 
You received this message because you are subscribed to the Google Groups "Rack Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rack-devel+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rational for rewind()
  2014-05-23 10:46 ` Magnus Holm
@ 2014-05-24 12:35   ` Torsten Robitzki
  2014-06-30 22:16     ` Daniel Doubrovkine
  0 siblings, 1 reply; 11+ messages in thread
From: Torsten Robitzki @ 2014-05-24 12:35 UTC (permalink / raw)
  To: rack-devel

[-- Attachment #1: Type: text/plain, Size: 1006 bytes --]

Hi Magnus,
 

> One word: Middleware. 
>

sorry, I didn't found the old discussions here regarding rewind (maybe a 
typo in my search phrase). Is there any proposal planned to change the 
specs to allow a more effective input implementation? 

My first thought was something like an unrewindable_input() function, that 
provides an input stream that doesn't provide a rewind() interface, but 
buffers the data read through this interface, so that the original input 
can still provide this data. If all middleware would be aware of this 
interface and the final application wouldn't need to rewind(), the input 
would just have to store the part of the input that have to be processed 
twice.

Cheers,
Torsten 

-- 

--- 
You received this message because you are subscribed to the Google Groups "Rack Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rack-devel+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

[-- Attachment #2: Type: text/html, Size: 1444 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rational for rewind()
  2014-05-24 12:35   ` Torsten Robitzki
@ 2014-06-30 22:16     ` Daniel Doubrovkine
  2014-07-15  4:30       ` James Tucker
  0 siblings, 1 reply; 11+ messages in thread
From: Daniel Doubrovkine @ 2014-06-30 22:16 UTC (permalink / raw)
  To: rack-devel

[-- Attachment #1: Type: text/plain, Size: 2004 bytes --]

If you're interested in an example that uses rewind, check out
https://github.com/intridea/grape/blob/5c785324a071f7eb527683256ad34db70e965830/lib/grape/middleware/formatter.rb#L55
.

Basically, in Rails the input would get read, and left at the end of the
stream. So when Grape was mounted on Rails it would want to re-read that
input to get more/better/different data and therefore you had to call
rewind.


On Sat, May 24, 2014 at 8:35 AM, Torsten Robitzki <Torsten@robitzki.de>
wrote:

> Hi Magnus,
>
>
>> One word: Middleware.
>>
>
> sorry, I didn't found the old discussions here regarding rewind (maybe a
> typo in my search phrase). Is there any proposal planned to change the
> specs to allow a more effective input implementation?
>
> My first thought was something like an unrewindable_input() function, that
> provides an input stream that doesn't provide a rewind() interface, but
> buffers the data read through this interface, so that the original input
> can still provide this data. If all middleware would be aware of this
> interface and the final application wouldn't need to rewind(), the input
> would just have to store the part of the input that have to be processed
> twice.
>
> Cheers,
> Torsten
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "Rack Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to rack-devel+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>



-- 

dB. | Moscow - Geneva - Seattle - New York
code.dblock.org - @dblockdotorg <http://twitter.com/#!/dblockdotorg> -
artsy.net - github/dblock <https://github.com/dblock>

-- 

--- 
You received this message because you are subscribed to the Google Groups "Rack Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rack-devel+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

[-- Attachment #2: Type: text/html, Size: 3631 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rational for rewind()
  2014-06-30 22:16     ` Daniel Doubrovkine
@ 2014-07-15  4:30       ` James Tucker
  0 siblings, 0 replies; 11+ messages in thread
From: James Tucker @ 2014-07-15  4:30 UTC (permalink / raw)
  To: rack-devel

[-- Attachment #1: Type: text/plain, Size: 2727 bytes --]

The use case is generally explained in previous mails, but yes it's a
problem for these kinds of servers.

My best recommendation to you is that you violate the recommendation and
clearly document the rationale. We can't easily address this in the SPEC at
this time.


On Mon, Jun 30, 2014 at 3:16 PM, Daniel Doubrovkine <dblock@dblock.org>
wrote:

> If you're interested in an example that uses rewind, check out
> https://github.com/intridea/grape/blob/5c785324a071f7eb527683256ad34db70e965830/lib/grape/middleware/formatter.rb#L55
> .
>
> Basically, in Rails the input would get read, and left at the end of the
> stream. So when Grape was mounted on Rails it would want to re-read that
> input to get more/better/different data and therefore you had to call
> rewind.
>
>
> On Sat, May 24, 2014 at 8:35 AM, Torsten Robitzki <Torsten@robitzki.de>
> wrote:
>
>> Hi Magnus,
>>
>>
>>> One word: Middleware.
>>>
>>
>> sorry, I didn't found the old discussions here regarding rewind (maybe a
>> typo in my search phrase). Is there any proposal planned to change the
>> specs to allow a more effective input implementation?
>>
>> My first thought was something like an unrewindable_input() function,
>> that provides an input stream that doesn't provide a rewind() interface,
>> but buffers the data read through this interface, so that the original
>> input can still provide this data. If all middleware would be aware of this
>> interface and the final application wouldn't need to rewind(), the input
>> would just have to store the part of the input that have to be processed
>> twice.
>>
>> Cheers,
>> Torsten
>>
>> --
>>
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Rack Development" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to rack-devel+unsubscribe@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> --
>
> dB. | Moscow - Geneva - Seattle - New York
> code.dblock.org - @dblockdotorg <http://twitter.com/#!/dblockdotorg> -
> artsy.net - github/dblock <https://github.com/dblock>
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "Rack Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to rack-devel+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 

--- 
You received this message because you are subscribed to the Google Groups "Rack Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rack-devel+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

[-- Attachment #2: Type: text/html, Size: 4961 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rational for rewind()
  2014-05-22 21:12 rational for rewind() Torsten Robitzki
  2014-05-23 10:46 ` Magnus Holm
@ 2014-07-17 22:34 ` Eric Wong
  2014-07-17 23:10   ` James Tucker
  1 sibling, 1 reply; 11+ messages in thread
From: Eric Wong @ 2014-07-17 22:34 UTC (permalink / raw)
  To: rack-devel

(resending my original message for the archives, original seems lost,
 Torsten already got this privately)

Torsten Robitzki <Torsten@Robitzki.de> wrote:
> Hello,
> I'm implementing a C++ comet web server, that (tries) to implement rack to 
> adapt ruby applications. Currently I'm reading a body very naively put the 
> body into a ruby String and wrap it with a StringIO to provide the 
> rack.input for the implementation. As I'm going to use the server for 
> uploading images, I would like to implement a real, stream-like object to 
> circumvent the need to buffer the POST body before handing it to the 
> application.

unicorn implements input like tee(1) doing lazy, rewindable buffering:
	http://unicorn.bogomips.org/Unicorn/TeeInput.html

> Now, I've read the rack specs and read about rewind(). To implement 
> rewind(), I would have to store the whole body, even when the upstream 
> application just calculates some kind of checksum on the body, or uploads 
> it to s3. What's the rational behind this part of the specification? Is it 
> possible to not implement rewind() and to tell applications that need 
> rewind(), to keep there own copy of the body, in case it is needed? 

I don't know the rationale, but I suspect it's to make life easier for
application/API authors to know the data will exist for the lifetime
of the request/response cycle.

But I think having rewind as part of the spec sucks.  I seem to recall
there was hope of getting rid of it for Rack 2 (if it ever happens).
However, since I'm not sure if Rack 2 will happen, rewind can already
be disabled and break spec in servers I implement:

unicorn has a "rewindable_input <true|false>" option (default=true):
	http://unicorn.bogomips.org/Unicorn/Configurator.html

yahns is a tri-state: "input_buffering <:lazy|true|false>" option:
	http://yahns.yhbt.net/yahns_config.txt (default=true)

Fwiw, rewindable_input(true) in unicorn is equivalent to
input_buffering(:lazy) in yahns.  This is because unicorn expects nginx
to buffer for slow clients, whereas yahns does not require nginx and
buffers asynchronously even with trickling clients.

-- 

--- 
You received this message because you are subscribed to the Google Groups "Rack Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rack-devel+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rational for rewind()
  2014-07-17 22:34 ` Eric Wong
@ 2014-07-17 23:10   ` James Tucker
  2014-07-17 23:44     ` Eric Wong
  2014-07-19  9:55     ` Torsten Robitzki
  0 siblings, 2 replies; 11+ messages in thread
From: James Tucker @ 2014-07-17 23:10 UTC (permalink / raw)
  To: rack-devel

[-- Attachment #1: Type: text/plain, Size: 3704 bytes --]

On Thu, Jul 17, 2014 at 3:34 PM, Eric Wong <e@80x24.org> wrote:

> (resending my original message for the archives, original seems lost,
>  Torsten already got this privately)
>
> Torsten Robitzki <Torsten@Robitzki.de> wrote:
> > Hello,
> > I'm implementing a C++ comet web server, that (tries) to implement rack
> to
> > adapt ruby applications. Currently I'm reading a body very naively put
> the
> > body into a ruby String and wrap it with a StringIO to provide the
> > rack.input for the implementation. As I'm going to use the server for
> > uploading images, I would like to implement a real, stream-like object to
> > circumvent the need to buffer the POST body before handing it to the
> > application.
>
> unicorn implements input like tee(1) doing lazy, rewindable buffering:
>         http://unicorn.bogomips.org/Unicorn/TeeInput.html


This is the approach I would take. I'm not sure if TeeInput supports it,
but for a generic server supporting websocket type use cases, I'd add a
discardable buffer API too, so you can "hijack" the input stream and
release any stale resources.

> Now, I've read the rack specs and read about rewind(). To implement
> > rewind(), I would have to store the whole body, even when the upstream
> > application just calculates some kind of checksum on the body, or uploads
> > it to s3. What's the rational behind this part of the specification? Is
> it
> > possible to not implement rewind() and to tell applications that need
> > rewind(), to keep there own copy of the body, in case it is needed?
>
> I don't know the rationale, but I suspect it's to make life easier for
> application/API authors to know the data will exist for the lifetime
> of the request/response cycle.
>
> But I think having rewind as part of the spec sucks.


Agreed. I generally think a lot of concerns that used to be in middleware
should not be so (e.g. chunking and content-length), but this concern
actually could be handled by middleware so apps that want it can add it in
the appropriate place in the chain. This would remove the responsibility
from the server authors, which opens up a lot of potential optimizations
and flexibility. We also lack a lot of potentially useful security
considerations in this area (i.e. both static and dynamic configurable
limits).


>  I seem to recall
> there was hope of getting rid of it for Rack 2 (if it ever happens).
>

Yup.


> However, since I'm not sure if Rack 2 will happen, rewind can already
> be disabled and break spec in servers I implement:
>
> unicorn has a "rewindable_input <true|false>" option (default=true):
>         http://unicorn.bogomips.org/Unicorn/Configurator.html
>
> yahns is a tri-state: "input_buffering <:lazy|true|false>" option:
>         http://yahns.yhbt.net/yahns_config.txt (default=true)
>
> Fwiw, rewindable_input(true) in unicorn is equivalent to
> input_buffering(:lazy) in yahns.  This is because unicorn expects nginx
> to buffer for slow clients, whereas yahns does not require nginx and
> buffers asynchronously even with trickling clients.
>

This is the approach I recommend today.


>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "Rack Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to rack-devel+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 

--- 
You received this message because you are subscribed to the Google Groups "Rack Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rack-devel+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

[-- Attachment #2: Type: text/html, Size: 5522 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rational for rewind()
  2014-07-17 23:10   ` James Tucker
@ 2014-07-17 23:44     ` Eric Wong
  2014-07-18  0:00       ` James Tucker
  2014-07-19  9:55     ` Torsten Robitzki
  1 sibling, 1 reply; 11+ messages in thread
From: Eric Wong @ 2014-07-17 23:44 UTC (permalink / raw)
  To: rack-devel

James Tucker <jftucker@gmail.com> wrote:
> > Torsten Robitzki <Torsten@Robitzki.de> wrote:
> > > Hello,
> > > I'm implementing a C++ comet web server, that (tries) to implement rack
> > to
> > > adapt ruby applications. Currently I'm reading a body very naively put
> > the
> > > body into a ruby String and wrap it with a StringIO to provide the
> > > rack.input for the implementation. As I'm going to use the server for
> > > uploading images, I would like to implement a real, stream-like object to
> > > circumvent the need to buffer the POST body before handing it to the
> > > application.
> >
> > unicorn implements input like tee(1) doing lazy, rewindable buffering:
> >         http://unicorn.bogomips.org/Unicorn/TeeInput.html
> 
> 
> This is the approach I would take. I'm not sure if TeeInput supports it,
> but for a generic server supporting websocket type use cases, I'd add a
> discardable buffer API too, so you can "hijack" the input stream and
> release any stale resources.

I'm not completely sure what you mean[1], but both yahns and unicorn
support rack.hijack.  TeeInput cannot read beyond the current HTTP
request boundary, so I'm not sure there's anything that needs to change
in the HTTP servers.

If a client pipelines non-HTTP data after a normal HTTP request, that
would be a problem; but pipelining during a protocol change/negotiation
seems wrong to begin with.


[1] I've not tried rack.hijack with websockets, yet
    I just (hopefully) implemented it according to the Rack spec.
    GUI-oriented websocket things just do not interest me.

-- 

--- 
You received this message because you are subscribed to the Google Groups "Rack Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rack-devel+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rational for rewind()
  2014-07-17 23:44     ` Eric Wong
@ 2014-07-18  0:00       ` James Tucker
  2014-07-18  0:43         ` Eric Wong
  0 siblings, 1 reply; 11+ messages in thread
From: James Tucker @ 2014-07-18  0:00 UTC (permalink / raw)
  To: rack-devel

[-- Attachment #1: Type: text/plain, Size: 3064 bytes --]

On Thu, Jul 17, 2014 at 4:44 PM, Eric Wong <e@80x24.org> wrote:

> James Tucker <jftucker@gmail.com> wrote:
> > > Torsten Robitzki <Torsten@Robitzki.de> wrote:
> > > > Hello,
> > > > I'm implementing a C++ comet web server, that (tries) to implement
> rack
> > > to
> > > > adapt ruby applications. Currently I'm reading a body very naively
> put
> > > the
> > > > body into a ruby String and wrap it with a StringIO to provide the
> > > > rack.input for the implementation. As I'm going to use the server for
> > > > uploading images, I would like to implement a real, stream-like
> object to
> > > > circumvent the need to buffer the POST body before handing it to the
> > > > application.
> > >
> > > unicorn implements input like tee(1) doing lazy, rewindable buffering:
> > >         http://unicorn.bogomips.org/Unicorn/TeeInput.html
> >
> >
> > This is the approach I would take. I'm not sure if TeeInput supports it,
> > but for a generic server supporting websocket type use cases, I'd add a
> > discardable buffer API too, so you can "hijack" the input stream and
> > release any stale resources.
>
> I'm not completely sure what you mean[1], but both yahns and unicorn
> support rack.hijack.  TeeInput cannot read beyond the current HTTP
> request boundary, so I'm not sure there's anything that needs to change
> in the HTTP servers.
>

Right, I just mean "I own the socket now, throw away any buffers"

If a client pipelines non-HTTP data after a normal HTTP request, that
> would be a problem; but pipelining during a protocol change/negotiation
> seems wrong to begin with.
>

Yep, pipelining and upgrades with close semantics are evil. The correct
approach is to just discard any in-flight pipelined requests, and
technically they should have no side-effects due to the idempotence rule.
This is the important reason to strongly recommend using non-idempotent
HTTP methods for upgrade routes, as correct pipeline implementations should
serialize around those. All that said though, it's generally even more wise
to handle/split routing for these kinds of things at the load balancer
level, as they have totally different load semantics.


>
>
> [1] I've not tried rack.hijack with websockets, yet
>     I just (hopefully) implemented it according to the Rack spec.
>     GUI-oriented websocket things just do not interest me.
>

Totally fair :-)

I use SSE a lot more than websockets myself, as it's less complicated
across the whole stack.


>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "Rack Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to rack-devel+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 

--- 
You received this message because you are subscribed to the Google Groups "Rack Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rack-devel+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

[-- Attachment #2: Type: text/html, Size: 4668 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rational for rewind()
  2014-07-18  0:00       ` James Tucker
@ 2014-07-18  0:43         ` Eric Wong
  0 siblings, 0 replies; 11+ messages in thread
From: Eric Wong @ 2014-07-18  0:43 UTC (permalink / raw)
  To: rack-devel

James Tucker <jftucker@gmail.com> wrote:
> Right, I just mean "I own the socket now, throw away any buffers"

OK, so probably something like the following to remove references to the
HTTP parser and input object:

http://yhbt.net/yahns-public/m/20140718003320.GA14749@dcvr.yhbt.net.html

The Rack app is still expected to cleanup env itself.

-- 

--- 
You received this message because you are subscribed to the Google Groups "Rack Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rack-devel+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rational for rewind()
  2014-07-17 23:10   ` James Tucker
  2014-07-17 23:44     ` Eric Wong
@ 2014-07-19  9:55     ` Torsten Robitzki
  1 sibling, 0 replies; 11+ messages in thread
From: Torsten Robitzki @ 2014-07-19  9:55 UTC (permalink / raw)
  To: rack-devel

[-- Attachment #1: Type: text/plain, Size: 1696 bytes --]

Hello,

Am Freitag, 18. Juli 2014 01:10:03 UTC+2 schrieb raggi:
 

> Agreed. I generally think a lot of concerns that used to be in middleware 
> should not be so (e.g. chunking and content-length), but this concern 
> actually could be handled by middleware so apps that want it can add it in 
> the appropriate place in the chain. This would remove the responsibility 
> from the server authors, which opens up a lot of potential optimizations 
> and flexibility. We also lack a lot of potentially useful security 
> considerations in this area (i.e. both static and dynamic configurable 
> limits).
>

depending on how much middlewares need this feature, it might be more 
effective to implement the buffering in the server as this is the part of 
the stack that is nearest to the metal. 

Maybe we could propose an API for middle wares that need rewinding and then 
do a reference implementation that could be implemented naively in ruby and 
added onto of all existing server implementations. I think such an API 
needs to address:
- that in case that no middleware needs to rewind, the input needs not to 
be buffered
- in case the middlewares just need to peek into the beginning of the 
input, only that beginning of the stream have to be buffered.
- it should as backward compatible as possible. At least no middleware that 
does not use rewind() should see a difference.

regards,
Torsten
 

-- 

--- 
You received this message because you are subscribed to the Google Groups "Rack Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rack-devel+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

[-- Attachment #2: Type: text/html, Size: 2213 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2014-07-19  9:55 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-22 21:12 rational for rewind() Torsten Robitzki
2014-05-23 10:46 ` Magnus Holm
2014-05-24 12:35   ` Torsten Robitzki
2014-06-30 22:16     ` Daniel Doubrovkine
2014-07-15  4:30       ` James Tucker
2014-07-17 22:34 ` Eric Wong
2014-07-17 23:10   ` James Tucker
2014-07-17 23:44     ` Eric Wong
2014-07-18  0:00       ` James Tucker
2014-07-18  0:43         ` Eric Wong
2014-07-19  9:55     ` Torsten Robitzki

rack-devel archive mirror (unofficial) https://groups.google.com/group/rack-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://public-inbox.org/rack-devel

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V1 rack-devel rack-devel/ https://public-inbox.org/rack-devel \
		rack-devel@googlegroups.com
	public-inbox-index rack-devel

Example config snippet for mirrors.
Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.lang.ruby.rack.devel
	nntp://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/inbox.comp.lang.ruby.rack.devel
	nntp://news.gmane.io/gmane.comp.lang.ruby.rack.devel
 note: .onion URLs require Tor: https://www.torproject.org/

code repositories for project(s) associated with this inbox:

	https://80x24.org/mirrors/rack.git

AGPL code for this site: git clone https://public-inbox.org/public-inbox.git