2 # Copyright (c) 2011 Greek Research and Technology Network
\r
5 from django.http import HttpResponse
\r
6 from django.template.loader import render_to_string
\r
7 from django.utils import simplejson as json
\r
9 from pithos.api.faults import Fault, BadRequest, Unauthorized
\r
10 from pithos.api.util import api_method
\r
12 from pithos.backends.dummy_debug import *
\r
16 logging.basicConfig(level=logging.DEBUG)
\r
19 def authenticate(request):
\r
20 # Normal Response Codes: 204
\r
21 # Error Response Codes: serviceUnavailable (503),
\r
22 # unauthorized (401),
\r
25 x_auth_user = request.META.get('HTTP_X_AUTH_USER')
\r
26 x_auth_key = request.META.get('HTTP_X_AUTH_KEY')
\r
28 if not x_auth_user or not x_auth_key:
\r
29 raise BadRequest('Missing auth user or key.')
\r
31 response = HttpResponse(status = 204)
\r
32 response['X-Auth-Token'] = 'eaaafd18-0fed-4b3a-81b4-663c99ec1cbb'
\r
33 # TODO: Do we support redirections?
\r
34 #response['X-Storage-Url'] = 'https://storage.grnet.gr/pithos/v1.0/<some reference>'
\r
37 def account_demux(request, v_account):
\r
38 if request.method == 'HEAD':
\r
39 return account_meta(request, v_account)
\r
40 elif request.method == 'GET':
\r
41 return container_list(request, v_account)
\r
43 return method_not_allowed(request)
\r
45 def container_demux(request, v_account, v_container):
\r
46 if request.method == 'HEAD':
\r
47 return container_meta(request, v_account, v_container)
\r
48 elif request.method == 'GET':
\r
49 return object_list(request, v_account, v_container)
\r
50 elif request.method == 'PUT':
\r
51 return container_create(request, v_account, v_container)
\r
52 elif request.method == 'DELETE':
\r
53 return container_delete(request, v_account, v_container)
\r
55 return method_not_allowed(request)
\r
57 def object_demux(request, v_account, v_container, v_object):
\r
58 if request.method == 'HEAD':
\r
59 return object_meta(request, v_account, v_container, v_object)
\r
60 elif request.method == 'GET':
\r
61 return object_read(request, v_account, v_container, v_object)
\r
62 elif request.method == 'PUT':
\r
63 return object_write(request, v_account, v_container, v_object)
\r
64 elif request.method == 'POST':
\r
65 return object_update(request, v_account, v_container, v_object)
\r
66 elif request.method == 'DELETE':
\r
67 return object_delete(request, v_account, v_container, v_object)
\r
69 return method_not_allowed(request)
\r
72 def account_meta(request, v_account):
\r
73 # Normal Response Codes: 204
\r
74 # Error Response Codes: serviceUnavailable (503),
\r
75 # itemNotFound (404),
\r
76 # unauthorized (401),
\r
79 container_count, bytes_count = get_account_meta(request.user)
\r
81 response = HttpResponse(status = 204)
\r
82 response['X-Account-Container-Count'] = container_count
\r
83 response['X-Account-Total-Bytes-Used'] = bytes_count
\r
86 @api_method('GET', format_allowed = True)
\r
87 def container_list(request, v_account):
\r
88 # Normal Response Codes: 200, 204
\r
89 # Error Response Codes: serviceUnavailable (503),
\r
90 # unauthorized (401),
\r
93 marker = request.GET.get('marker')
\r
94 limit = request.GET.get('limit')
\r
101 containers = list_containers(request.user, marker, limit)
\r
102 if len(containers) == 0:
\r
103 return HttpResponse(status = 204)
\r
105 if request.serialization == 'xml':
\r
106 data = render_to_string('containers.xml', {'account': request.user, 'containers': containers})
\r
107 elif request.serialization == 'json':
\r
108 data = json.dumps(containers)
\r
110 data = '\n'.join(x['name'] for x in containers)
\r
112 return HttpResponse(data, status = 200)
\r
114 @api_method('HEAD')
\r
115 def container_meta(request, v_account, v_container):
\r
116 # Normal Response Codes: 204
\r
117 # Error Response Codes: serviceUnavailable (503),
\r
118 # itemNotFound (404),
\r
119 # unauthorized (401),
\r
122 object_count, bytes_count = get_container_meta(request.user, v_container)
\r
124 response = HttpResponse(status = 204)
\r
125 response['X-Container-Object-Count'] = object_count
\r
126 response['X-Container-Bytes-Used'] = bytes_count
\r
130 def container_create(request, v_account, v_container):
\r
131 # Normal Response Codes: 201, 202
\r
132 # Error Response Codes: serviceUnavailable (503),
\r
133 # itemNotFound (404),
\r
134 # unauthorized (401),
\r
137 if create_container(request.user, v_container):
\r
138 return HttpResponse(status = 201)
\r
140 return HttpResponse(status = 202)
\r
142 @api_method('DELETE')
\r
143 def container_delete(request, v_account, v_container):
\r
144 # Normal Response Codes: 204
\r
145 # Error Response Codes: serviceUnavailable (503),
\r
146 # itemNotFound (404),
\r
147 # unauthorized (401),
\r
150 object_count, bytes_count = get_container_meta(request.user, v_container)
\r
151 if object_count > 0:
\r
152 return HttpResponse(status = 409)
\r
154 delete_container(request.user, v_container)
\r
155 return HttpResponse(status = 204)
\r
157 @api_method('GET', format_allowed = True)
\r
158 def object_list(request, v_account, v_container):
\r
159 # Normal Response Codes: 200, 204
\r
160 # Error Response Codes: serviceUnavailable (503),
\r
161 # itemNotFound (404),
\r
162 # unauthorized (401),
\r
165 path = request.GET.get('path')
\r
166 prefix = request.GET.get('prefix')
\r
167 delimiter = request.GET.get('delimiter')
\r
168 logging.debug("path: %s", path)
\r
170 # Path overrides prefix and delimiter.
\r
175 if prefix and delimiter:
\r
176 prefix = prefix + delimiter
\r
178 marker = request.GET.get('marker')
\r
179 limit = request.GET.get('limit')
\r
186 objects = list_objects(request.user, v_container, prefix, delimiter, marker, limit)
\r
187 if len(objects) == 0:
\r
188 return HttpResponse(status = 204)
\r
190 if request.serialization == 'xml':
\r
191 data = render_to_string('objects.xml', {'container': v_container, 'objects': objects})
\r
192 elif request.serialization == 'json':
\r
193 data = json.dumps(objects)
\r
195 data = '\n'.join(x['name'] for x in objects)
\r
197 return HttpResponse(data, status = 200)
\r
199 @api_method('HEAD')
\r
200 def object_meta(request, v_account, v_container, v_object):
\r
201 # Normal Response Codes: 204
\r
202 # Error Response Codes: serviceUnavailable (503),
\r
203 # itemNotFound (404),
\r
204 # unauthorized (401),
\r
207 info = get_object_meta(request.user, v_container, v_object)
\r
209 response = HttpResponse(status = 204)
\r
210 response['ETag'] = info['hash']
\r
211 response['Content-Length'] = info['bytes']
\r
212 response['Content-Type'] = info['content_type']
\r
213 # TODO: Format time.
\r
214 response['Last-Modified'] = info['last_modified']
\r
215 for k, v in info['meta'].iteritems():
\r
216 response['X-Object-Meta-%s' % k.capitalize()] = v
\r
221 def object_read(request, v_account, v_container, v_object):
\r
222 return HttpResponse("object_read: %s %s %s" % (v_account, v_container, v_object))
\r
225 def object_write(request, v_account, v_container, v_object):
\r
226 return HttpResponse("object_write: %s %s %s" % (v_account, v_container, v_object))
\r
228 @api_method('POST')
\r
229 def object_update(request, v_account, v_container, v_object):
\r
230 # Normal Response Codes: 202
\r
231 # Error Response Codes: serviceUnavailable (503),
\r
232 # itemNotFound (404),
\r
233 # unauthorized (401),
\r
236 prefix = 'X-Object-Meta-'
\r
237 meta = dict([(k[len(prefix):].lower(), v) for k, v in request.POST.iteritems() if k.startswith(prefix)])
\r
239 update_object_meta(request.user, v_container, v_object, meta)
\r
240 return HttpResponse(status = 202)
\r
242 @api_method('DELETE')
\r
243 def object_delete(request, v_account, v_container, v_object):
\r
244 # Normal Response Codes: 204
\r
245 # Error Response Codes: serviceUnavailable (503),
\r
246 # itemNotFound (404),
\r
247 # unauthorized (401),
\r
250 delete_object(request.user, v_container, v_object)
\r
251 return HttpResponse(status = 204)
\r
254 def method_not_allowed(request):
\r
255 raise BadRequest('Method not allowed.')
\r