Revision a4e9c19c

b/snf-cyclades-app/synnefo/plankton/views.py
35 35

  
36 36
from logging import getLogger
37 37
from string import punctuation
38
from urllib import unquote
38
from urllib import unquote, quote
39 39

  
40 40
from django.conf import settings
41 41
from django.http import HttpResponse
42
from django.utils.encoding import smart_unicode
42
from django.utils.encoding import smart_unicode, smart_str
43 43

  
44 44
from snf_django.lib import api
45 45
from snf_django.lib.api import faults
......
81 81

  
82 82

  
83 83
def _create_image_response(image):
84
    """Encode the image parameters to HTTP Response Headers.
85

  
86
    Headers are encoded to UTF-8 then quoted.
87

  
88
    """
84 89
    response = HttpResponse()
90
    encode_header = lambda x: quote(smart_str(x, encoding='utf-8'))
85 91

  
86 92
    for key in DETAIL_FIELDS:
87 93
        if key == 'properties':
88
            for k, v in image.get('properties', {}).items():
89
                name = 'x-image-meta-property-' + k.replace('_', '-')
90
                response[name] = smart_unicode(v, encoding="utf-8")
94
            for pkey, pval in image.get('properties', {}).items():
95
                pkey = 'http-x-image-meta-property-' + pkey.replace('_', '-')
96
                pkey = quote(smart_str(pkey, encoding='utf-8'))
97
                pval = quote(smart_str(pval, encoding='utf-8'))
98
                response[encode_header(pkey)] = encode_header(pval)
91 99
        else:
92
            name = 'x-image-meta-' + key.replace('_', '-')
93
            response[name] = smart_unicode(image.get(key, ''), encoding="utf-8")
100
            key = 'http-x-image-meta-' + key.replace('_', '-')
101
            val = image.get('key', '')
102
            response[encode_header(key)] = encode_header(val)
94 103

  
95 104
    return response
96 105

  
97 106

  
98
def _get_image_headers(request):
107
def headers_to_image_params(request):
108
    """Decode the HTTP request headers to the acceptable image parameters.
109

  
110
    Get image properties from the corresponding headers of the HTTP request.
111
    Image headers are unquoted and then decoded to Unicode using UTF-8
112
    encoding. Image headers keys are lowered and all punctation characters
113
    are replaced with underscore.
114

  
115
    """
116

  
99 117
    def normalize(s):
100 118
        return ''.join('_' if c in punctuation else c.lower() for c in s)
101 119

  
......
104 122
    META_PROPERTY_PREFIX = 'HTTP_X_IMAGE_META_PROPERTY_'
105 123
    META_PROPERTY_PREFIX_LEN = len(META_PROPERTY_PREFIX)
106 124

  
107
    headers = {'properties': {}}
125
    decode_header = lambda x: smart_unicode(unquote(x), encoding="utf-8")
126
    is_img_property = lambda x: x.startswith(META_PROPERTY_PREFIX)
127
    is_img_param = lambda x: x.startswith(META_PREFIX)
108 128

  
129
    params = {}
130
    properties = {}
109 131
    for key, val in request.META.items():
110
        if key.startswith(META_PROPERTY_PREFIX):
111
            name = normalize(key[META_PROPERTY_PREFIX_LEN:])
112
            headers['properties'][unquote(name)] = unquote(val)
113
        elif key.startswith(META_PREFIX):
114
            name = normalize(key[META_PREFIX_LEN:])
115
            headers[unquote(name)] = unquote(val)
116

  
117
    is_public = headers.get('is_public', None)
118
    if is_public is not None:
119
        headers['is_public'] = True if is_public.lower() == 'true' else False
132
        if isinstance(val, basestring):
133
            val = decode_header(val)
134
        if is_img_property(key):
135
            key = decode_header(key[META_PROPERTY_PREFIX_LEN:])
136
            properties[normalize(key)] = val
137
        elif is_img_param(key):
138
            key = decode_header(key[META_PREFIX_LEN:])
139
            params[normalize(key)] = val
120 140

  
121
    if not headers['properties']:
122
        del headers['properties']
141
    if properties:
142
        params['properties'] = properties
123 143

  
124
    return headers
144
    return params
125 145

  
126 146

  
127 147
@api.api_method(http_method="POST", user_required=True, logger=log)
......
143 163
        instead of uploading the data.
144 164
    """
145 165

  
146
    params = _get_image_headers(request)
166
    params = headers_to_image_params(request)
147 167
    log.debug('add_image %s', params)
148 168

  
149 169
    if not set(params.keys()).issubset(set(ADD_FIELDS)):
......
378 398
        and status.
379 399
    """
380 400

  
381
    meta = _get_image_headers(request)
401
    meta = headers_to_image_params(request)
382 402
    log.debug('update_image %s', meta)
383 403

  
384 404
    if not set(meta.keys()).issubset(set(UPDATE_FIELDS)):

Also available in: Unified diff