def store_blob_and_transform_request(self, environ):
    """Stores a blob in response to a WSGI request and transforms environ.

    environ is modified so that it is suitable for forwarding to the user's
    application.

    Args:
      environ: An environ dict for the current request as defined in PEP-333.

    Raises:
      webob.exc.HTTPException: The upload failed.
    """
    # Only permit POST.
    if environ['REQUEST_METHOD'].lower() != 'post':
      self.abort(405)

    url_match = _UPLOAD_URL_PATTERN.match(environ['PATH_INFO'])
    if not url_match:
      self.abort(404)
    upload_key = url_match.group(1)

    # Retrieve upload session.
    try:
      upload_session = datastore.Get(upload_key)
    except datastore_errors.EntityNotFoundError:
      detail = 'No such upload session: %s' % upload_key
      logging.error(detail)
      self.abort(404, detail=detail)

    success_path = upload_session['success_path'].encode('ascii')
    max_bytes_per_blob = upload_session['max_bytes_per_blob']
    max_bytes_total = upload_session['max_bytes_total']
    bucket_name = upload_session.get('gs_bucket_name', None)

    upload_form = cgi.FieldStorage(fp=environ['wsgi.input'],
                                   environ=environ)

    # Generate debug log message
    logstrings = []
    for k in sorted(upload_form):
      vs = upload_form[k]
      if not isinstance(vs, list):
        vs = [vs]
      for v in vs:
        if v.filename:
          logstrings.append('%s=%s' % (k, v.filename))
    logging.debug('Received blobstore upload: %s', ', '.join(logstrings))

    # It's ok to read the whole string in memory because the content is
    # merely a reference to the blob, not the blob itself.
    content_type, content_text = self.store_and_build_forward_message(
        upload_form,
        max_bytes_per_blob=max_bytes_per_blob,
        max_bytes_total=max_bytes_total,
        bucket_name=bucket_name)

    datastore.Delete(upload_session)

    # Ensure that certain HTTP_ variables are not forwarded.
    for name in _STRIPPED_ENVIRON:
      if name in environ:
        del environ[name]

    # Replace some HTTP headers in the forwarded environ.
    environ['CONTENT_TYPE'] = content_type
    environ['CONTENT_LENGTH'] = str(len(content_text))

    # Forward on to success_path. Like production, only the path and query
    # matter.
    parsed_url = urlparse.urlsplit(success_path)
    environ['PATH_INFO'] = parsed_url.path
    if parsed_url.query:
      environ['QUERY_STRING'] = parsed_url.query

    # The user is always an administrator for the forwarded request.
    environ[constants.FAKE_IS_ADMIN_HEADER] = '1'

    # Set the wsgi variables
    environ['wsgi.input'] = cStringIO.StringIO(content_text)
dataset/ETHPy150Open AppScale/appscale/AppServer/google/appengine/tools/devappserver2/blob_upload.py/Application.store_blob_and_transform_request/original