Files
glance/glance/api/middleware/gzip.py
T
Ian CordascoandHemanth Makkapati 7a843f7e1f Fix incompatibilities with WebOb 1.7
WebOb 1.7 changed [0] how request bodies are determined to be
readable. Prior to version 1.7, the following is how WebOb
determined if a request body is readable:
  #1 Request method is one of POST, PUT or PATCH
  #2 ``content_length`` length is set
  #3 Special flag ``webob.is_body_readable`` is set

The special flag ``webob.is_body_readable`` was used to signal
WebOb to consider a request body readable despite the content length
not being set. #1 above is how ``chunked`` Transfer Encoding was
supported implicitly in WebOb < 1.7.

Now with WebOb 1.7, a request body is considered readable only if
``content_length`` is set and it's non-zero [1]. So, we are only left
with #2 and #3 now. This drops implicit support for ``chunked``
Transfer Encoding Glance relied on. Hence, to emulate #1, Glance must
set the the special flag upon checking the HTTP methods that may have
bodies. This is precisely what this patch attemps to do.

[0] https://github.com/Pylons/webob/pull/283
[1] https://github.com/Pylons/webob/pull/283/files#diff-706d71e82f473a3b61d95c2c0d833b60R894

Closes-bug: #1657459
Closes-bug: #1657452
Co-Authored-By: Hemanth Makkapati <hemanth.makkapati@rackspace.com>
Change-Id: I19f15165a3d664d5f3a361f29ad7000ba2465a85
2017-03-27 22:03:36 -05:00

66 lines
2.2 KiB
Python

# Copyright 2013 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
Use gzip compression if the client accepts it.
"""
import re
from oslo_log import log as logging
from glance.common import wsgi
from glance.i18n import _LI
LOG = logging.getLogger(__name__)
class GzipMiddleware(wsgi.Middleware):
re_zip = re.compile(r'\bgzip\b')
def __init__(self, app):
LOG.info(_LI("Initialized gzip middleware"))
super(GzipMiddleware, self).__init__(app)
def process_response(self, response):
request = response.request
accept_encoding = request.headers.get('Accept-Encoding', '')
if self.re_zip.search(accept_encoding):
# NOTE(flaper87): Webob removes the content-md5 when
# app_iter is called. We'll keep it and reset it later
checksum = response.headers.get("Content-MD5")
# NOTE(flaper87): We'll use lazy for images so
# that they can be compressed without reading
# the whole content in memory. Notice that using
# lazy will set response's content-length to 0.
content_type = response.headers.get("Content-Type", "")
lazy = content_type == "application/octet-stream"
# NOTE(flaper87): Webob takes care of the compression
# process, it will replace the body either with a
# compressed body or a generator - used for lazy com
# pression - depending on the lazy value.
#
# Webob itself will set the Content-Encoding header.
response.encode_content(lazy=lazy)
if checksum:
response.headers['Content-MD5'] = checksum
return response