anchor.diff:              report_error(Worker, HttpDb, Params, {code, Error})
           end;
       {ibrowse_async_response, ReqId, {error, _} = Error} ->
  -        maybe_retry(Error, Worker, HttpDb, Params, Callback)
  +        maybe_retry(Error, Worker, HttpDb, Params)
       after HttpDb#httpdb.timeout + 500 ->
           % Note: ibrowse should always reply with timeouts, but this doesn't
           % seem to be always true when there's a very high rate of requests
           % and many open connections.
  -        maybe_retry(timeout, Worker, HttpDb, Params, Callback)
  +        maybe_retry(timeout, Worker, HttpDb, Params)
       end.
   
   
  -clean_mailbox_req(ReqId) ->
  +% Only streaming HTTP requests send messages back from
  +% the ibrowse worker process. We can detect that based
  +% on the ibrowse_req_id format. This just drops all
  +% messages for the given ReqId on the floor since we're
  +% no longer in the HTTP request.
  +clean_mailbox({ibrowse_req_id, ReqId}) ->
       receive
       {ibrowse_async_response, ReqId, _} ->
  -        clean_mailbox_req(ReqId);
  +        clean_mailbox({ibrowse_req_id, ReqId});
       {ibrowse_async_response_end, ReqId} ->
  -        clean_mailbox_req(ReqId)
  +        clean_mailbox({ibrowse_req_id, ReqId})
       after 0 ->
           ok
  -    end.
  -
  -
  -release_worker(Worker, #httpdb{httpc_pool = Pool}) ->
  +    end;
  +clean_mailbox(_) ->
  +    ok.
  +
  +
  +release_worker(Worker, _, true) ->
  +    true = unlink(Worker),
  +    ibrowse_http_client:stop(Worker),
  +    receive
  +        {'EXIT', Worker, _} -> ok
  +        after 0 -> ok
  +    end;
  +release_worker(Worker, #httpdb{httpc_pool = Pool}, false) ->
       ok = couch_replicator_httpc_pool:release_worker(Pool, Worker).
   
   
  -maybe_retry(Error, Worker, #httpdb{retries = 0} = HttpDb, Params, _Cb) ->
  +maybe_retry(Error, Worker, #httpdb{retries = 0} = HttpDb, Params) ->
       report_error(Worker, HttpDb, Params, {error, Error});
   
  -maybe_retry(Error, Worker, #httpdb{retries = Retries, wait = Wait} = HttpDb,
  -    Params, Cb) ->
  -    release_worker(Worker, HttpDb),
  +maybe_retry(Error, _Worker, #httpdb{retries = Retries, wait = Wait} = HttpDb,
  +    Params) ->
       Method = string:to_upper(atom_to_list(get_value(method, Params, get))),
       Url = couch_util:url_strip_password(full_url(HttpDb, Params)),
       couch_log:notice("Retrying ~s request to ~s in ~p seconds due to error ~s",
           [Method, Url, Wait / 1000, error_cause(Error)]),
       ok = timer:sleep(Wait),
       Wait2 = erlang:min(Wait * 2, ?MAX_WAIT),
  -    send_req(HttpDb#httpdb{retries = Retries - 1, wait = Wait2}, Params, Cb).
  -
  -
  -report_error(Worker, HttpDb, Params, Error) ->
  +    NewHttpDb = HttpDb#httpdb{retries = Retries - 1, wait = Wait2},
  +    throw({retry, NewHttpDb, Params}).
  +
  +
  +report_error(_Worker, HttpDb, Params, Error) ->
       Method = string:to_upper(atom_to_list(get_value(method, Params, get))),
       Url = couch_util:url_strip_password(full_url(HttpDb, Params)),
       do_report_error(Url, Method, Error),
  -    release_worker(Worker, HttpDb),
       exit({http_request_failed, Method, Url, Error}).
   
   
  
positive.code:             ibrowse:stream_next(ReqId),
              try
                  Ret = Callback(Ok, Headers, StreamDataFun),
                  release_worker(Worker, HttpDb),
                  clean_mailbox_req(ReqId),
                  Ret
              catch throw:{maybe_retry_req, Err} ->
                  clean_mailbox_req(ReqId),
                  maybe_retry(Err, Worker, HttpDb, Params, Callback)
              end;
          R when R =:= 301 ; R =:= 302 ; R =:= 303 ->
              do_redirect(Worker, R, Headers, HttpDb, Params, Callback);
  
negative.code:     R when R =:= 301 ; R =:= 302 ; R =:= 303 ->
          do_redirect(Worker, R, Headers, HttpDb, Params, Callback);
      Error ->
          maybe_retry({code, Error}, Worker, HttpDb, Params)
      end;
  
  process_response(Error, Worker, HttpDb, Params, _Callback) ->
      maybe_retry(Error, Worker, HttpDb, Params).
  
  
  process_stream_response(ReqId, Worker, HttpDb, Params, Callback) ->
  