def _rewriter_middleware(request_rewriter_chain, response_rewriter_chain,
                         application, environ, start_response):
  response_dict = {'headers_sent': False}
  write_body = cStringIO.StringIO()

  def wrapped_start_response(status, response_headers, exc_info=None):
    if exc_info and response_dict['headers_sent']:
      # Headers have already been sent. PEP 333 mandates that this is an error.
      raise exc_info[0], exc_info[1], exc_info[2]

    response_dict['status'] = status
    response_dict['response_headers'] = response_headers
    return write_body.write

  for rewriter in request_rewriter_chain:
    rewriter(environ)

  response_body = iter(application(environ, wrapped_start_response))

  # Get the first non-empty string from the application's response. This ensures
  # that the application has called wrapped_start_response, and allows us to
  # treat future calls to wrapped_start_response as errors.
  first = write_body.getvalue()
  while not first:
    try:
      first = response_body.next()
    except StopIteration:
      break

  # A conformant application must have called wrapped_start_response by this
  # point, and should not call it again unless there is an unrecoverable error.
  response_dict['headers_sent'] = True

  try:
    status = response_dict['status']
    response_headers = response_dict['response_headers']
  except KeyError:
    raise AssertionError('Application yielded before calling start_response.')

  # Prepend first onto response_body.
  def reconstructed_body():
    yield first
    for string in response_body:
      yield string
  body = reconstructed_body()

  state = RewriterState(environ, status, response_headers, body)
  for rewriter in response_rewriter_chain:
    rewriter(state)
  start_response(state.status, state.headers.items())
  return state.body
Constructs a :class:`PreparedRequest <PreparedRequest>` for
dataset/ETHPy150Open AppScale/appscale/AppServer/google/appengine/tools/devappserver2/request_rewriter.py/_rewriter_middleware--crossover with--dataset/ETHPy150Open BergWerkGIS/QGIS-CKAN-Browser/CKAN-Browser/request/sessions.py/Session.prepare_request