17 Commits

Author SHA1 Message Date
Josh Cheek
fc4cec558e Env stored on middleware response has reference to the response
Synopsis
--------

The `Env` that gets stored on the `Response` does not contain
a reference to that response. This env is a copy of the env that
was passed through the middleware stack. Thus if the env
passed to `app.call` is used, it has the response, but if the one
from the `Response` is used, then it does not. This happens when,
for example, you invoke the `on_complete` hook on the response,
after it has finished.

Fixes Longstanding VCR issue
----------------------------

Fixes https://github.com/vcr/vcr/issues/386

A longstanding issue in VCR's integration with v0.9.x
It was worked around in this commit: https://github.com/vcr/vcr/pull/439
And is merged into master, but is not released.
Merging this will fix the issue, without the changes to VCR needing to
be released.

The old code, which is currently released, and gets its env from the
Request can be seen
[here](cb9696c44d%5E/lib/vcr/middleware/faraday.rb#L99-105)

Fixes Faraday Issue
-------------------

Fixes https://github.com/lostisland/faraday/issues/441
which identifies this same problem.

Closes Faraday PR
-----------------

I'm going to recommend closing https://github.com/lostisland/faraday/pull/360/files
as the issue was probably introduced
[here](04a8514cba (diff-fc9726b31994223d11a212b5169100fdL68))
when `Response#finish` changed from storing the `env` directly,
to storing a copy:

```
- @env = env
+ @env = Env.from(env)
```

Presumably this behaviour is still desired, but the mentioned pull
essentially undoes this by returning the same `env` from `Env.from`

The commit that introduced the issue is probably good, but is called by
the app in the middleware stack that creates the response, before it
sets the rsponse onto the env. This means that the copy does not have
the link to the response.

81f16593a0/lib/faraday/rack_builder.rb (L152-155)

Not sure about the test name/location
-------------------------------------

I had difficulty figuring out where to put this test, and what to name
it. I eventually went with the test on the `middleware_stack_test.rb`,
because it deals with the `RackBuilder`, but if there's a better place,
or a better name, let me know and I'll update it.

One other weird thing
---------------------

Depending on when the `Request#on_complete` callback is invoked,
you're either getting the original env, or the copy:

81f16593a0/lib/faraday/response.rb (L64-65)
2015-05-05 00:52:04 -06:00
Erik Michaels-Ober
edcd7d61f3 Make formatting of then, yield, and super consistent 2014-01-09 02:59:12 +01:00
Erik Michaels-Ober
faab1b08cd Replace test-unit with minitest 2012-12-16 20:22:03 -08:00
technoweenie
77d7546d6d Builder => RackBuilder 2012-10-28 11:00:33 -06:00
technoweenie
bbc69369e5 merge 2012-10-27 10:27:50 -06:00
technoweenie
fa397470e2 simplify test requires 2012-10-21 10:25:34 -06:00
technoweenie
497caa3c5e add some autoloading abilities to MiddlewareRegistry 2012-10-20 17:30:05 -06:00
technoweenie
a6c6f1612c remove Faraday::Error module, add Faraday::Error base class 2012-10-20 17:11:54 -06:00
technoweenie
14b458a9c9 remove Faraday.register_middleware 2012-10-20 16:58:06 -06:00
Mislav Marohnić
b179fb5ed1 don't try to predict exact load error messages for various rubies 2012-01-24 23:37:41 +01:00
Mislav Marohnić
394c62cd36 raise exception if initializing middleware with missing dependencies
Previously it would just try to use the middleware and it would result
in unexplained errors when making requests.
2012-01-24 22:56:16 +01:00
Mislav Marohnić
a81b7052cc add Faraday.register_middleware
Allows 3rd-party libraries to register named shortcuts to resolve to
fully qualified constant names for specific middleware.

Usage:
  Faraday.register_middleware :aloha => MyModule::Aloha
  Faraday.register_middleware :response, :boom => MyModule::Boom
  Faraday.register_middleware :lazy => lambda { MyModule::LazyLoaded }

Those shortcuts are then available in Builder:
  builder.use :aloha
  builder.response :boom
2012-01-02 15:47:52 +01:00
Mislav Marohnić
f7e80bf4ce fix Builder::Handler comparison to another Handler 2011-05-13 10:24:56 -07:00
Mislav Marohnić
b47fb2922f cache middleware stack instead of rebuilding it on every request
The downside is, middleware can't be modified after making the first request:

  conn.use MyMiddleware       # => OK
  conn.get('/')
  conn.use AnotherMiddleware  # => raises a Builder::StackLocked error

On the plus side, the middleware stack is built only once and then cached as
the Connection#app object.

The Connection instance can always be "forked off" with the `dup` method and
modified as if it were fresh.
2011-05-08 14:20:51 -07:00
Mislav Marohnić
419ba4eaa4 optimize request/response cycle for parallel (asynchronous) mode
Changes:
 - there is no `env[:response]` during the request phase
 - middleware should attach `on_complete` handlers to the response object
   returned from `@app.call(env)` call
 - `on_complete` handlers execute immediately if the request is finished
 - Builder doesn't have the `run` method anymore
 - the default stack is now setup as soon as the Builder object has been initialized
 - the inner app for the stack is set when creating the request
2011-03-26 21:23:18 +01:00
Mislav Marohnić
d6d86dd043 extract multipart stuff from Adapter to Request::Multipart middleware 2011-03-26 21:20:21 +01:00
Mislav Marohnić
198546900c refactored builder so that middleware stack is more hackable
The problem with the old builder is that it was hard to see which middleware
is on the stack (it was stored in lambdas) and even harder to add new middleware
at arbitrary positions.

Incompatible changes:
 - `Builder.create` shouldn't be called without a block anymore
 - `Builder#run` doesn't push middleware to the stack anymore.
    Instead, it sets the inner app (overrides the default).
 - `Builder#handlers` are now stored in natural order
 - Handlers are no longer stored as lambdas. Instead, they are
   stored as lightweight `Handler` objects for easier inspection.
 - Inner app is no longer present among handlers.

Enhancements:
 - It's easy to see what's on the stack: `builder.handlers.inspect`
 - It's possible to edit the stack:
   - builder.insert_before(ExistingHandler, NewHandler)
   - builder.insert_after(...)
   - builder.swap(HandlerToReplace, NewHandler)
   - builder.delete(HandlerToDelete)
2011-03-26 21:16:42 +01:00