Example #1
0
    def __call__(self, request, *args, **kwargs):
        """
        NB: Sends a `Vary` header so we don't cache requests
        that are different (OAuth stuff in `Authorization` header.)
        """
        rm = request.method.upper()

        # Django's internal mechanism doesn't pick up
        # PUT request, so we trick it a little here.
        if rm == "PUT":
            coerce_put_post(request)

        actor, anonymous = self.authenticate(request, rm)

        if anonymous is CHALLENGE:
            return actor()
        else:
            handler = actor

        # Translate nested datastructs into `request.data` here.
        if rm in ('POST', 'PUT'):
            try:
                self.translate_mime(request)
            except MimerDataException:
                return rc.BAD_REQUEST
            if not hasattr(request, 'data'):
                if rm == 'POST':
                    request.data = request.POST
                else:
                    request.data = request.PUT

        if not rm in handler.allowed_methods:
            return HttpResponseNotAllowed(handler.allowed_methods)

        meth = getattr(handler, self.callmap.get(rm, ''), None)
        if not meth:
            raise Http404

        # Support emitter both through (?P<emitter_format>) and ?format=emitter.
        em_format = self.determine_emitter(request, *args, **kwargs)

        kwargs.pop('emitter_format', None)

        # Clean up the request object a bit, since we might
        # very well have `oauth_`-headers in there, and we
        # don't want to pass these along to the handler.
        request = self.cleanup_request(request)

        try:
            #result = transaction.commit_on_success(meth)(request, *args, **kwargs)
            result = self.trans_func(meth)(request, *args, **kwargs)
        except Exception, e:
            result = self.error_handler(e, request, meth, em_format)
Example #2
0
	def __call__(self, request, *args, **kwargs):
		"""Main request handler

		**File uploads**

		File uploads from ExtJS forms (with fileUpload: true) are not XHR - they are always POST and multipart/form-data.
		If such a request is detected, response type is changed from application/javasctript to text/html.
		If a pk is given in kwargs, it means that the request is an update and ``request.method`` is changed to PUT.

		**Request data preprocessing**

		Data from a request can be either directly in ``QueryDict`` (TODO forms only?) or as ``QueryDict.data`` (grids). Guess what it is and clean it up.
		If ``QueryDict.data`` exists, it is used for ``request.data`` and the rest of the ``QueryDict`` is ``request.params``, otherwise both ``request.data`` and ``request.params`` are set to ``QueryDict``.

		**IMPORTANT**

		Forms cannot contain fields named ``data`` (yet) because it'll confuse the code above and result in strange behavior.

		"""
		#check security
		#TODO for now only check security in handler
		if not self.handler.authorize(request): return rc.FORBIDDEN

		coerce_put_post(request)

		#detect file uploads
		#TODO use request.is_ajax()
		if request.method=='POST' and request.META['CONTENT_TYPE'].startswith('multipart/form-data'):
			#it's probably a submit from a form with fileUpload
			if self.handler.pkfield in kwargs:
				#it's an update, so make it a PUT
				setattr(request,'PUT',request.POST)
				request.method = 'PUT'
			extjs_file_post = True
		else:
			extjs_file_post = False

		if hasattr(request, 'data') and request.data == None: delattr(request, 'data')
		if request.method == 'GET':
			self.translate_mime(request)
			#request.data = dict([(k,v) for k,v in getattr(request,request.method).iteritems()])

			if '_dc' in request.data: del request.data['_dc']

		self.handler.success = True
		self.handler.message = None

		if not hasattr(request, 'params'): request.params = getattr(request,'data',{})

		response = super(ExtResource, self).__call__(request, *args, **kwargs)
		#if it's a file upload, it's not XHR, it's via a hidden iframe and so response type must be text/html, otherwise browser shows 'save as' dialog for file 'application/json'
		if extjs_file_post: response['content-type']=response['content-type'].replace('application/json','text/html')	#TODO swap any mime for this with re
		return response
Example #3
0
    def __call__(self, request, *args, **kwargs):
        """
        NB: Sends a `Vary` header so we don't cache requests
        that are different (OAuth stuff in `Authorization` header.)
        """
        rm = request.method.upper()

        # Django's internal mechanism doesn't pick up
        # PUT request, so we trick it a little here.
        if rm == "PUT":
            coerce_put_post(request)

        actor, anonymous = self.authenticate(request, rm)

        if anonymous is CHALLENGE:
            return actor()
        else:
            handler = actor

        # Translate nested datastructs into `request.data` here.
        if rm in ('POST', 'PUT'):
            try:
                translate_mime(request)
            except MimerDataException:
                return rc.BAD_REQUEST
            if not hasattr(request, 'data'):
                if rm == 'POST':
                    request.data = request.POST
                else:
                    request.data = request.PUT

        if not rm in handler.allowed_methods:
            return HttpResponseNotAllowed(handler.allowed_methods)

        meth = getattr(handler, self.callmap.get(rm, ''), None)
        if not meth:
            raise Http404

        # Support emitter both through (?P<emitter_format>) and ?format=emitter.
        em_format = self.determine_emitter(request, *args, **kwargs)

        kwargs.pop('emitter_format', None)

        # Clean up the request object a bit, since we might
        # very well have `oauth_`-headers in there, and we
        # don't want to pass these along to the handler.
        request = self.cleanup_request(request)

        try:
            result = meth(request, *args, **kwargs)
        except Exception, e:
            result = self.error_handler(e, request, meth, em_format)
Example #4
0
    def __call__(self, request, *args, **kwargs):
        rm = request.method.upper()

        if rm == "PUT":
            coerce_put_post(request)

        actor, anonymous = self.authenticate(request, rm)

        if anonymous is CHALLENGE:
            return actor()
        else:
            handler = actor

        if rm in ('POST', 'PUT'):
            try:
                translate_mime(request)
            except MimerDataException:
                return rc.BAD_REQUEST
            if not hasattr(request, 'data'):
                if rm == 'POST':
                    request.data = request.POST
                else:
                    request.data = request.PUT

        if not rm in handler.allowed_methods:
            return HttpResponseNotAllowed(handler.allowed_methods)

        meth = getattr(handler, self.callmap.get(rm, ''), None)
        if not meth:
            raise Http404

        em_format = self.determine_emitter(request, *args, **kwargs)
        kwargs.pop('emitter_format', None)

        request = self.cleanup_request(request)

        try:
            result = meth(request, *args, **kwargs)
        except ValueError:
            result = rc.BAD_REQUEST
            result.content = 'Invalid arguments'

        try:
            emitter, ct = Emitter.get(em_format)
            fields = handler.fields
            if hasattr(handler, 'list_fields') and isinstance(
                    result, (list, tuple, QuerySet)):
                fields = handler.list_fields
        except ValueError:
            result = rc.BAD_REQUEST
            result.content = "Invalid output format specified '%s'." % em_format
            return result

        status_code = 200

        if isinstance(result, HttpResponse) and not result._is_string:
            status_code = result.status_code
            result = result._container

        srl = emitter(result, typemapper, handler, fields, anonymous)

        try:
            if self.stream: stream = srl.stream_render(request)
            else: stream = srl.render(request)

            if not isinstance(stream, HttpResponse):
                resp = HttpResponse(stream, mimetype=ct, status=status_code)
            else:
                resp = stream
            resp.streaming = self.stream
            return resp
        except HttpStatusCode, e:
            return e.response
Example #5
0
    def ___call__(self, request, *args, **kwargs):
        """
        NB: Sends a `Vary` header so we don't cache requests
        that are different (OAuth stuff in `Authorization` header.)
        """
        # from ipdb import set_trace; set_trace()
        rm = request.method.upper()

        # Django's internal mechanism doesn't pick up
        # PUT request, so we trick it a little here.
        if rm == "PUT":
            coerce_put_post(request)

        if not self.authentication.is_authenticated(request):
            if (
                hasattr(self.handler, "anonymous")
                and callable(self.handler.anonymous)
                and rm in self.handler.anonymous.allowed_methods
            ):

                handler = self.handler.anonymous()
                anonymous = True
            else:
                return self.authentication.challenge()
        else:
            handler = self.handler
            anonymous = handler.is_anonymous

        # Translate nested datastructs into `request.data` here.
        if rm in ("POST", "PUT"):
            try:
                # from ipdb import set_trace; set_trace()
                translate_mime(request)
            except MimerDataException:
                pass
                # print "Error de Mime"
                # return rc.BAD_REQUEST

        if not rm in handler.allowed_methods:
            return HttpResponseNotAllowed(handler.allowed_methods)

        meth = getattr(handler, self.callmap.get(rm), None)

        if not meth:
            raise Http404

        # Support emitter both through (?P<emitter_format>) and ?format=emitter.
        em_format = self.determine_emitter(request, *args, **kwargs)

        kwargs.pop("emitter_format", None)

        # Clean up the request object a bit, since we might
        # very well have `oauth_`-headers in there, and we
        # don't want to pass these along to the handler.
        request = self.cleanup_request(request)

        try:
            result = meth(request, *args, **kwargs)
        except FormValidationError, e:
            # TODO: Use rc.BAD_REQUEST here
            return HttpResponse("Bad Request: %s" % e.form.errors, status=400)