def post_object(global_id, container): """ Uploads an Object, must include a file with id=file_content and a header X-Password=global_id user's password :param global_id: user id :param container: container name :return: HTTP 201 if created """ password = request.headers.get('X-Password') user = StorageUser.objects(global_id=global_id, global_pwd=password).first() if user is not None: tenant_id = user.tenant_id fil = request.files.get('file_content') try: conn = swiftclient.Connection(auth_url, global_id, password, auth_version=auth_version, tenant_name=global_id, insecure=True) conn.put_object(container, fil.filename, fil.file) conn.close() # Save to Mongo obj = StorageObject(tenant_id=tenant_id, tenant_name=global_id, container_name=container, object_name=fil.filename, user=user) obj.save() return HTTPResponse(status=201) except ClientException: traceback.print_exc(sys.stderr) abort(500, "Could not upload file") except AttributeError: abort(400, "Request malformed, probably object is not sent with the file_content identifier") else: abort(401, 'Unknown user')
def delete_object(global_id, container, object_name): """ Deletes an Object :param global_id: user id :param container: container name :return: HTTP 201 if created """ password = request.headers.get('X-Password') user = StorageUser.objects(global_id=global_id, global_pwd=password).first() if user is not None: try: conn = swiftclient.Connection(auth_url, global_id, password, auth_version=auth_version, tenant_name=global_id, insecure=True) conn.delete_object(container, object_name) conn.close() # Delete entry from Mongo obj = StorageObject.objects(tenant_name=global_id, container_name=container, object_name=object_name).first() if obj is not None: obj.delete() return HTTPResponse(status=204) except ClientException: traceback.print_exc(sys.stderr) abort(500, "Could not delete file") except AttributeError: traceback.print_exc(sys.stderr) abort(400, "Request malformed") else: abort(401, 'Unknown user')
def cache_object(origin_address, user, container_name, object_name): """ Threaded internal method to retrieve object from origin and add it locally. :param origin_address: Address of the origin PoP of this user :param user: User object from mongoengine corresponding to global_id user :param container_name: container name :param object_name: object name """ # Download the object if not origin_address.startswith('http://'): origin_address = 'http://' + origin_address r = get("%s/%s/%s/%s" % (origin_address, user.global_id, container_name, object_name), stream=True) if r.status_code == 200: fname = store_path + "/" + user.global_id + "-" + object_name with open(fname, 'wb') as f: for chunk in r.iter_content(1024): f.write(chunk) # Check if container exists if not create it conn = swiftclient.Connection(auth_url, user.global_id, user.global_pwd, auth_version=auth_version, tenant_name=user.global_id, insecure=True) containers = conn.get_account()[1] for container in containers: if container['name'] == container_name: break else: # Container does not exist conn.put_container(container_name, {"X-Container-Read": ".r:*"}) # Add object conn.put_object(container_name, object_name, open(fname)) # Save to Mongo obj = StorageObject(tenant_id=user.tenant_id, tenant_name=user.global_id, container_name=container_name, object_name=object_name, user=user) obj.save()
def get_object(global_id, container_name, object_name): """ Redirects to an object already stored in Swift If object missing, raise 404 :param global_id: global user id :param container_name: container name :param object_name: file name :return: redirection (HTTP 303) to the actual object """ #if file exists obj = StorageObject.objects(tenant_name=global_id, container_name=container_name, object_name=object_name).first() if obj is not None: return redirect(swift_root + "%s/%s/%s" % (obj.tenant_id, container_name, object_name), 303) else: # let's try to retrieve it... if it exists # Before checking anything, verify that user global_id exists! usr = StorageUser.objects(global_id=global_id).first() if usr is not None and cdn_central_address is not None: # find origin for user from central or from the cache origin_object = StorageOrigin.objects(user=usr).first() origin_address = None if origin_object is not None: origin_address = origin_object.url else: r = get(cdn_central_address + '/origin/' + global_id) jresp = r.json() origin_address = jresp['origin_address'] # If current instance of cdnlocal IS the origin, then file does not exist, returns a 404 if origin_address == local_address or origin_address is None: return abort(404, 'File does not exist or is unavailable') # Cache object, but should redirect to origin this time so user does not wait for file retrieval t = Thread(target=cache_object, args=(origin_address, usr, container_name, object_name,)) t.start() print "redirect to: %s/%s/%s/%s" % (origin_address, global_id, container_name, object_name) return redirect("%s/%s/%s/%s" % (origin_address, global_id, container_name, object_name), 303) else: return abort(404, 'User does not exist or Central CDN server undefined')
def get_object(global_id, container_name, object_name): """ Redirects to an object already stored in Swift If object missing, raise 404 :param global_id: global user id :param container_name: container name :param object_name: file name :return: redirection (HTTP 303) to the actual object """ #if file exists obj = StorageObject.objects(tenant_name=global_id, container_name=container_name, object_name=object_name).first() if obj is not None: return redirect(swift_root + "%s/%s/%s" % (obj.tenant_id, container_name, object_name), 303) else: # let's try to retrieve it... if it exists # Before checking anything, verify that user global_id exists! usr = StorageUser.objects(global_id=global_id).first() if usr is not None and cdn_central_address is not None: # find origin for user from central or from the cache origin_object = StorageOrigin.objects(user=usr).first() origin_address = None if origin_object is not None: origin_address = origin_object.url else: r = get(cdn_central_address + '/origin/' + global_id) jresp = r.json() origin_address = jresp['origin_address'] # If current instance of cdnlocal IS the origin, then file does not exist, returns a 404 if origin_address == local_address or origin_address is None: return abort(404, 'File does not exist or is unavailable') # Cache object, but should redirect to origin this time so user does not wait for file retrieval t = Thread(target=cache_object, args=(origin_address, usr, container_name, object_name)) t.start() return redirect("%s/%s/%s/%s" % (origin_address, global_id, container_name, object_name), 303) else: return abort(404, 'User does not exist or Central CDN server undefined')