def test_get_requested_mimetype_with_unsupported_mimetype(self): """Testing djblets.http.get_requested_mimetype with unsupported mimetype """ self.assertEqual( get_http_requested_mimetype(self.request, ['text/plain']), None) self.assertEqual( get_http_requested_mimetype(self.request, ['foo/bar']), None)
def test_get_requested_mimetype_with_unsupported_mimetype(self): """Testing djblets.http.get_requested_mimetype with unsupported mimetype""" self.assertEqual( get_http_requested_mimetype(self.request, ['text/plain']), None) self.assertEqual( get_http_requested_mimetype(self.request, ['foo/bar']), None)
def test_get_requested_mimetype_with_supported_mimetype(self): """Testing djblets.http.get_requested_mimetype with supported mimetype """ self.assertEqual(get_http_requested_mimetype(self.request, ["foo/bar", "application/json"]), "application/json") self.assertEqual(get_http_requested_mimetype(self.request, ["application/xml"]), "application/xml") self.assertEqual( get_http_requested_mimetype(self.request, ["application/json", "application/xml"]), "application/xml" )
def test_get_requested_mimetype_with_supported_mimetype(self): """Testing djblets.http.get_requested_mimetype with supported mimetype""" self.assertEqual( get_http_requested_mimetype(self.request, ['foo/bar', 'application/json']), 'application/json') self.assertEqual( get_http_requested_mimetype(self.request, ['application/xml']), 'application/xml') self.assertEqual( get_http_requested_mimetype( self.request, ['application/json', 'application/xml']), 'application/xml')
def test_get_requested_mimetype_with_supported_mimetype(self): """Testing djblets.http.get_requested_mimetype with supported mimetype""" self.assertEqual( get_http_requested_mimetype(self.request, ['foo/bar', 'application/json']), 'application/json') self.assertEqual( get_http_requested_mimetype(self.request, ['application/xml']), 'application/xml') self.assertEqual( get_http_requested_mimetype(self.request, ['application/json', 'application/xml']), 'application/xml')
def get(self, request, *args, **kwargs): """Returns the information or contents on a particular diff. The output varies by mimetype. If :mimetype:`application/json` or :mimetype:`application/xml` is used, then the fields for the diff are returned, like with any other resource. If :mimetype:`text/x-patch` is used, then the actual diff file itself is returned. This diff should be as it was when uploaded originally, with potentially some extra SCM-specific headers stripped. The contents will contain that of all per-file diffs that make up this diff. """ mimetype = get_http_requested_mimetype( request, [ mimetype['item'] for mimetype in self.allowed_mimetypes ]) if mimetype == 'text/x-patch': return self._get_patch(request, *args, **kwargs) else: return super(DiffResource, self).get(request, *args, **kwargs)
def test_get_requested_mimetype_with_wildcard_supported_mimetype(self): """Testing get_requested_mimetype with supported */* mimetype""" self.request.META['HTTP_ACCEPT'] = '*/*' self.assertEqual( get_http_requested_mimetype( self.request, ['application/json', 'application/xml']), 'application/json')
def test_get_requested_mimetype_with_wildcard_supported_mimetype(self): """Testing get_requested_mimetype with supported */* mimetype""" self.request.META['HTTP_ACCEPT'] = '*/*' self.assertEqual( get_http_requested_mimetype(self.request, ['application/json', 'application/xml']), 'application/json')
def get(self, request, *args, **kwargs): """Return information about a commit. If the :mimetype:`text/x-patch` mimetype is requested, the contents of the patch will be returned. Otherwise, metadata about the commit (such as author name, author date, etc.) will be returned. """ mimetype = get_http_requested_mimetype( request, [mimetype['item'] for mimetype in self.allowed_mimetypes]) if mimetype != 'text/x-patch': return super(DiffCommitResource, self).get(request, *args, **kwargs) try: review_request = resources.review_request.get_object( request, *args, **kwargs) commit = self.get_object(request, *args, **kwargs) except ObjectDoesNotExist: return DOES_NOT_EXIST if not self.has_access_permissions(request, commit, *args, **kwargs): return self.get_no_access_error(request) tool = review_request.repository.get_scmtool() data = tool.get_parser('').raw_diff(commit) rsp = HttpResponse(data, content_type=mimetype) rsp['Content-Disposition'] = ('inline; filename=%s.patch' % commit.commit_id) set_last_modified(rsp, commit.last_modified) return rsp
def get(self, request, *args, **kwargs): """Returns the information or contents on a particular diff. The output varies by mimetype. If :mimetype:`application/json` or :mimetype:`application/xml` is used, then the fields for the diff are returned, like with any other resource. If :mimetype:`text/x-patch` is used, then the actual diff file itself is returned. This diff should be as it was when uploaded originally, with potentially some extra SCM-specific headers stripped. The contents will contain that of all per-file diffs that make up this diff. """ mimetype = get_http_requested_mimetype( request, [ mimetype['item'] for mimetype in self.allowed_mimetypes ]) if mimetype == 'text/x-patch': return self._get_patch(request, *args, **kwargs) else: return super(DiffResource, self).get(request, *args, **kwargs)
def _build_error_mimetype(self, request): mimetype = get_http_requested_mimetype( request, WebAPIResponse.supported_mimetypes) if self.mimetype_vendor: mimetype = self._build_vendor_mimetype(mimetype, 'error') return mimetype
def _build_error_mimetype(self, request): mimetype = get_http_requested_mimetype( request, WebAPIResponse.supported_mimetypes) if self.mimetype_vendor: mimetype = self._build_vendor_mimetype(mimetype, 'error') return mimetype
def test_get_requested_mimetype_with_wildcard_supported_mimetype(self): """Testing djblets.http.get_requested_mimetype with supported */* mimetype """ self.request = HttpRequest() self.request.META["HTTP_ACCEPT"] = "*/*" self.assertEqual( get_http_requested_mimetype(self.request, ["application/json", "application/xml"]), "application/json" )
def test_get_requested_mimetype_with_no_consensus(self): """Testing djblets.http.get_requested_mimetype with no consensus between client and server""" self.request = HttpRequest() self.request.META['HTTP_ACCEPT'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' self.assertEqual( get_http_requested_mimetype(self.request, ['application/json', 'application/x-foo']), 'application/json')
def test_get_requested_mimetype_with_no_consensus(self): """Testing djblets.http.get_requested_mimetype with no consensus between client and server""" self.request = HttpRequest() self.request.META['HTTP_ACCEPT'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' self.assertEqual( get_http_requested_mimetype(self.request, ['application/json', 'application/x-foo']), 'application/json')
def __init__(self, request, obj={}, stat='ok', api_format=None, status=200, headers={}, encoders=[], mimetype=None, supported_mimetypes=None): if not api_format: if request.method == 'GET': api_format = request.GET.get('api_format', None) else: api_format = request.POST.get('api_format', None) if not supported_mimetypes: supported_mimetypes = self.supported_mimetypes if not mimetype: if not api_format: mimetype = get_http_requested_mimetype(request, supported_mimetypes) elif api_format == "json": mimetype = 'application/json' elif api_format == "xml": mimetype = 'application/xml' if not mimetype: self.status_code = 400 self.content_set = True return if not request.is_ajax() and request.FILES: # When uploading a file using AJAX to a webapi view, # we must set the mimetype to text/plain. If we use # application/json instead, the browser will ask the user # to save the file. It's not great, but it's what we must do. mimetype = 'text/plain' super(WebAPIResponse, self).__init__(content_type=mimetype, status=status) self.request = request self.callback = request.GET.get('callback', None) self.api_data = {'stat': stat} self.api_data.update(obj) self.content_set = False self.mimetype = mimetype self.encoders = encoders or get_registered_encoders() for header, value in six.iteritems(headers): self[header] = value # Prevent IE8 from trying to download some AJAX responses as if they # were files. self['X-Content-Type-Options'] = 'nosniff'
def __init__(self, request, obj={}, stat='ok', api_format=None, status=200, headers={}, encoders=[], encoder_kwargs={}, mimetype=None, supported_mimetypes=None): if not api_format: if request.method == 'GET': api_format = request.GET.get('api_format', None) else: api_format = request.POST.get('api_format', None) if not supported_mimetypes: supported_mimetypes = self.supported_mimetypes if not mimetype: if not api_format: mimetype = get_http_requested_mimetype(request, supported_mimetypes) elif api_format == "json": mimetype = 'application/json' elif api_format == "xml": mimetype = 'application/xml' if not mimetype: self.status_code = 400 self.content_set = True return if not request.is_ajax() and request.FILES: # When uploading a file using AJAX to a webapi view, # we must set the mimetype to text/plain. If we use # application/json instead, the browser will ask the user # to save the file. It's not great, but it's what we must do. mimetype = 'text/plain' super(WebAPIResponse, self).__init__(content_type=mimetype, status=status) self.request = request self.callback = request.GET.get('callback', None) self.api_data = {'stat': stat} self.api_data.update(obj) self.content_set = False self.mimetype = mimetype self.encoders = encoders or get_registered_encoders() self.encoder_kwargs = encoder_kwargs for header, value in six.iteritems(headers): self[header] = value # Prevent IE8 from trying to download some AJAX responses as if they # were files. self['X-Content-Type-Options'] = 'nosniff'
def __init__(self, request, obj={}, stat='ok', api_format=None, status=200, headers={}, encoders=[]): if not api_format: if request.method == 'GET': api_format = request.GET.get('api_format', None) else: api_format = request.POST.get('api_format', None) if not api_format: mimetype = get_http_requested_mimetype(request, self.supported_mimetypes) elif api_format == "json": mimetype = 'application/json' elif api_format == "xml": mimetype = 'application/xml' else: mimetype = None if not mimetype: self.status_code = 400 self.content_set = True return if mimetype == 'application/json' and request.FILES: # When uploading a file using AJAX to a webapi view, # we must set the mimetype to text/plain. If we use # application/json instead, the browser will ask the user # to save the file. It's not great, but it's what we must do. mimetype = 'text/plain' super(WebAPIResponse, self).__init__(mimetype=mimetype, status=status) self.request = request self.callback = request.GET.get('callback', None) self.api_data = {'stat': stat} self.api_data.update(obj) self.content_set = False self.mimetype = mimetype self.encoders = encoders or get_registered_encoders() for header, value in headers.iteritems(): self[header] = value
def __init__(self, request, obj={}, stat='ok', api_format=None, status=200, headers={}, encoders=[], encoder_kwargs={}, mimetype=None, supported_mimetypes=None): if not api_format: if request.method == 'GET': api_format = request.GET.get('api_format', None) else: api_format = request.POST.get('api_format', None) if not supported_mimetypes: supported_mimetypes = self.supported_mimetypes if not mimetype: if not api_format: mimetype = get_http_requested_mimetype(request, supported_mimetypes) elif api_format == "json": mimetype = 'application/json' elif api_format == "xml": mimetype = 'application/xml' if not mimetype: self.status_code = 400 self.content_set = True return super(WebAPIResponse, self).__init__(content_type=mimetype, status=status) self.request = request self.callback = request.GET.get('callback', None) self.api_data = {'stat': stat} self.api_data.update(obj) self.content_set = False self.mimetype = mimetype self.encoders = encoders or get_registered_encoders() self.encoder_kwargs = encoder_kwargs for header, value in six.iteritems(headers): self[header] = value # Prevent IE8 from trying to download some AJAX responses as if they # were files. self['X-Content-Type-Options'] = 'nosniff'
def __init__(self, request, obj={}, stat='ok', api_format=None, status=200, headers={}, encoders=[]): if not api_format: if request.method == 'GET': api_format = request.GET.get('api_format', None) else: api_format = request.POST.get('api_format', None) if not api_format: mimetype = get_http_requested_mimetype(request, self.supported_mimetypes) elif api_format == "json": mimetype = 'application/json' elif api_format == "xml": mimetype = 'application/xml' else: mimetype = None if not mimetype: self.status_code = 400 self.content_set = True return if mimetype == 'application/json' and request.FILES: # When uploading a file using AJAX to a webapi view, # we must set the mimetype to text/plain. If we use # application/json instead, the browser will ask the user # to save the file. It's not great, but it's what we must do. mimetype = 'text/plain' super(WebAPIResponse, self).__init__(mimetype=mimetype, status=status) self.request = request self.callback = request.GET.get('callback', None) self.api_data = {'stat': stat} self.api_data.update(obj) self.content_set = False self.mimetype = mimetype self.encoders = encoders or get_registered_encoders() for header, value in headers.iteritems(): self[header] = value
def build_response_args(self, request): is_list = (request._djblets_webapi_method == 'GET' and not self.singleton and (self.uri_object_key is None or self.uri_object_key not in request._djblets_webapi_kwargs)) if is_list: key = 'list' else: key = 'item' supported_mimetypes = [ mime[key] for mime in self.allowed_mimetypes if mime[key] ] mimetype = get_http_requested_mimetype(request, supported_mimetypes) if (self.mimetype_vendor and mimetype in WebAPIResponse.supported_mimetypes): mimetype = self._build_resource_mimetype(mimetype, is_list) response_args = { 'supported_mimetypes': supported_mimetypes, 'mimetype': mimetype, } if is_list: for mimetype_pair in self.allowed_mimetypes: if (mimetype_pair['list'] == mimetype and mimetype_pair['item']): response_args['headers'] = { 'Item-Content-Type': mimetype_pair['item'], } break return response_args
def build_response_args(self, request): is_list = (request._djblets_webapi_method == 'GET' and not self.singleton and (self.uri_object_key is None or self.uri_object_key not in request._djblets_webapi_kwargs)) if is_list: key = 'list' else: key = 'item' supported_mimetypes = [ mime[key] for mime in self.allowed_mimetypes if mime.get(key) ] mimetype = get_http_requested_mimetype(request, supported_mimetypes) if (self.mimetype_vendor and mimetype in WebAPIResponse.supported_mimetypes): mimetype = self._build_resource_mimetype(mimetype, is_list) response_args = { 'supported_mimetypes': supported_mimetypes, 'mimetype': mimetype, } if is_list: for mimetype_pair in self.allowed_mimetypes: if (mimetype_pair.get('list') == mimetype and mimetype_pair.get('item')): response_args['headers'] = { 'Item-Content-Type': mimetype_pair['item'], } break return response_args
def build_response_args(self, request): is_list = (request._djblets_webapi_method == 'GET' and not self.singleton and (self.uri_object_key is None or self.uri_object_key not in request._djblets_webapi_kwargs)) if is_list: supported_mimetypes = self.allowed_list_mimetypes else: supported_mimetypes = self.allowed_item_mimetypes mimetype = get_http_requested_mimetype(request, supported_mimetypes) if (self.mimetype_vendor and mimetype in WebAPIResponse.supported_mimetypes): mimetype = self._build_resource_mimetype(mimetype, is_list) return { 'supported_mimetypes': supported_mimetypes, 'mimetype': mimetype, }
def get(self, request, *args, **kwargs): """Return information about a commit. If the :mimetype:`text/x-patch` mimetype is requested, the contents of the patch will be returned. Otherwise, metadata about the commit (such as author name, author date, etc.) will be returned. """ mimetype = get_http_requested_mimetype( request, [mimetype['item'] for mimetype in self.allowed_mimetypes]) if mimetype != 'text/x-patch': return super(DiffCommitResource, self).get(request, *args, **kwargs) try: review_request = resources.review_request.get_object( request, *args, **kwargs) commit = self.get_object(request, *args, **kwargs) except ObjectDoesNotExist: return DOES_NOT_EXIST if not self.has_access_permissions(request, commit, *args, **kwargs): return self.get_no_access_error(request) tool = review_request.repository.get_scmtool() data = tool.get_parser('').raw_diff(commit) rsp = HttpResponse(data, content_type=mimetype) rsp['Content-Disposition'] = ('inline; filename=%s.patch' % commit.commit_id) set_last_modified(rsp, commit.last_modified) return rsp
def get(self, request, *args, **kwargs): """Returns the information or contents on a per-file diff. The output varies by mimetype. If :mimetype:`application/json` or :mimetype:`application/xml` is used, then the fields for the diff are returned, like with any other resource. If :mimetype:`text/x-patch` is used, then the actual diff file itself is returned. This diff should be as it was when uploaded originally, for this file only, with potentially some extra SCM-specific headers stripped. If :mimetype:`application/vnd.reviewboard.org.diff.data+json` or :mimetype:`application/vnd.reviewboard.org.diff.data+xml` is used, then the raw diff data (lists of inserts, deletes, replaces, moves, header information, etc.) is returned in either JSON or XML. This contains nearly all of the information used to render the diff in the diff viewer, and can be useful for building a diff viewer that interfaces with Review Board. If ``?syntax-highlighting=1`` is passed, the rendered diff content for each line will contain HTML markup showing syntax highlighting. Otherwise, the content will be in plain text. The format of the diff data is a bit complex. The data is stored under a top-level ``diff_data`` element and contains the following information: .. list-table:: :header-rows: 1 :widths: 10 15 75 * - Field - Type - Description * - **binary** - Boolean - Whether or not the file is a binary file. Binary files won't have any diff content to display. * - **chunks** - List of Dictionary - A list of chunks. These are used to render the diff. See below. * - **changed_chunk_indexes** - List of Integer - The list of chunks in the diff that have actual changes (inserts, deletes, or replaces). * - **new_file** - Boolean - Whether or not this is a newly added file, rather than an existing file in the repository. * - **num_changes** - Integer - The number of changes made in this file (chunks of adds, removes, or deletes). Each chunk contains the following fields: .. list-table:: :header-rows: 1 :widths: 10 15 75 * - Field - Type - Description * - **change** - One of ``equal``, ``delete``, ``insert``, ``replace`` - The type of change on this chunk. The type influences what sort of information is available for the chunk. * - **collapsable** - Boolean - Whether or not this chunk is collapseable. A collapseable chunk is one that is hidden by default in the diff viewer, but can be expanded. These will always be ``equal`` chunks, but not every ``equal`` chunk is necessarily collapseable (as they may be there to provide surrounding context for the changes). * - **index** - Integer - The index of the chunk. This is 0-based. * - **lines** - List of List - The list of rendered lines for a side-by-side diff. Each entry in the list is itself a list with 8 items: 1. Row number of the line in the combined side-by-side diff. 2. The line number of the line in the left-hand file, as an integer (for ``replace``, ``delete``, and ``equal`` chunks) or an empty string (for ``insert``). 3. The text for the line in the left-hand file. 4. The indexes within the text for the left-hand file that have been replaced by text in the right-hand side. Each index is a list of ``start, end`` positions, 0-based. This is only available for ``replace`` lines. Otherwise the list is empty. 5. The line number of the line in the right-hand file, as an integer (for ``replace``, ``insert`` and ``equal`` chunks) or an empty string (for ``delete``). 6. The text for the line in the right-hand file. 7. The indexes within the text for the right-hand file that are replacements for text in the left-hand file. Each index is a list of ``start, end`` positions, 0-based. This is only available for ``replace`` lines. Otherwise the list is empty. 8. A boolean that indicates if the line contains only whitespace changes. * - **meta** - Dictionary - Additional information about the chunk. See below for more information. * - **numlines** - Integer - The number of lines in the chunk. A chunk's meta information contains: .. list-table:: :header-rows: 1 :widths: 25 15 60 * - Field - Type - Description * - **headers** - List of (String, String) - Class definitions, function definitions, or other useful headers that should be displayed before this chunk. This helps users to identify where in a file they are and what the current chunk may be a part of. * - **whitespace_chunk** - Boolean - Whether or not the entire chunk consists only of whitespace changes. * - **whitespace_lines** - List of (Integer, Integer) - A list of ``start, end`` row indexes in the lins that contain whitespace-only changes. These are 1-based. Other meta information may be available, but most is intended for internal use and shouldn't be relied upon. """ mimetype = get_http_requested_mimetype( request, [ mimetype['item'] for mimetype in self.allowed_mimetypes ]) if mimetype == 'text/x-patch': return self._get_patch(request, *args, **kwargs) elif mimetype.startswith(self.DIFF_DATA_MIMETYPE_BASE + "+"): return self._get_diff_data(request, mimetype, *args, **kwargs) else: return super(FileDiffResource, self).get(request, *args, **kwargs)
def test_get_requested_mimetype_with_unsupported_mimetype(self): """Testing get_requested_mimetype with unsupported mimetype""" self.assertIsNone(get_http_requested_mimetype(self.request, ['text/plain'])) self.assertIsNone(get_http_requested_mimetype(self.request, ['foo/bar']))
def test_get_requested_mimetype_with_unsupported_mimetype(self): """Testing get_requested_mimetype with unsupported mimetype""" self.assertIsNone( get_http_requested_mimetype(self.request, ['text/plain'])) self.assertIsNone( get_http_requested_mimetype(self.request, ['foo/bar']))
def get(self, request, *args, **kwargs): """Returns the information or contents on a per-file diff. The output varies by mimetype. If :mimetype:`application/json` or :mimetype:`application/xml` is used, then the fields for the diff are returned, like with any other resource. If :mimetype:`text/x-patch` is used, then the actual diff file itself is returned. This diff should be as it was when uploaded originally, for this file only, with potentially some extra SCM-specific headers stripped. If :mimetype:`application/vnd.reviewboard.org.diff.data+json` or :mimetype:`application/vnd.reviewboard.org.diff.data+xml` is used, then the raw diff data (lists of inserts, deletes, replaces, moves, header information, etc.) is returned in either JSON or XML. This contains nearly all of the information used to render the diff in the diff viewer, and can be useful for building a diff viewer that interfaces with Review Board. If ``?syntax-highlighting=1`` is passed, the rendered diff content for each line will contain HTML markup showing syntax highlighting. Otherwise, the content will be in plain text. The format of the diff data is a bit complex. The data is stored under a top-level ``diff_data`` element and contains the following information: .. webapi-resource-field-list:: .. webapi-resource-field:: :name: binary :type: bool Whether or not the file is a binary file. Binary files won't have any diff content to display. .. webapi-resource-field:: :name: changed_chunk_indexes :type: list[int] The list of chunks in the diff that have actual changes (inserts, deletes, or replaces). .. webapi-resource-field:: :name: chunks :type: list[dict] A list of chunks. These are used to render the diff. See below. .. webapi-resource-field:: :name: new_file :type: bool Whether or not this is a newly added file, rather than an existing file in the repository. .. webapi-resource-field:: :name: num_changes :type: int The number of changes made in this file (chunks of adds, removes, or deletes). Each chunk contains the following fields: .. webapi-resource-field-list:: .. webapi-resource-field:: :name: change :type: ('equal', 'delete', 'insert', 'replace') The type of change on this chunk. The type influences what sort of information is available for the chunk. .. webapi-resource-field:: :name: collapsable :type: bool Whether or not this chunk is collapseable. A collapseable chunk is one that is hidden by default in the diff viewer, but can be expanded. These will always be ``equal`` chunks, but not every ``equal`` chunk is necessarily collapseable (as they may be there to provide surrounding context for the changes). .. webapi-resource-field:: :name: index :type: int The index of the chunk. This is 0-based. .. webapi-resource-field:: :name: lines :type: list[list] The list of rendered lines for a side-by-side diff. Each entry in the list is itself a list with 8 items: 1. Row number of the line in the combined side-by-side diff. 2. The line number of the line in the left-hand file, as an integer (for ``replace``, ``delete``, and ``equal`` chunks) or an empty string (for ``insert``). 3. The text for the line in the left-hand file. 4. The indexes within the text for the left-hand file that have been replaced by text in the right-hand side. Each index is a list of ``start, end`` positions, 0-based. This is only available for ``replace`` lines. Otherwise the list is empty. 5. The line number of the line in the right-hand file, as an integer (for ``replace``, ``insert`` and ``equal`` chunks) or an empty string (for ``delete``). 6. The text for the line in the right-hand file. 7. The indexes within the text for the right-hand file that are replacements for text in the left-hand file. Each index is a list of ``start, end`` positions, 0-based. This is only available for ``replace`` lines. Otherwise the list is empty. 8. A boolean that indicates if the line contains only whitespace changes. .. webapi-resource-field:: :name: meta :type: dict Additional information about the chunk. See below for more information. .. webapi-resource-field:: :name: numlines :type: int The number of lines in the chunk. A chunk's meta information contains: .. webapi-resource-field-list:: .. webapi-resource-field:: :name: headers :type: list[[unicode, unicode]] Class definitions, function definitions, or other useful headers that should be displayed before this chunk. This helps users to identify where in a file they are and what the current chunk may be a part of. .. webapi-resource-field:: :name: whitespace_chunk :type: bool Whether or not the entire chunk consists only of whitespace changes. .. webapi-resource-field:: :name: whitespace_lines :type: list[[int, int]] A list of ``(start, end)`` row indexes in the lins that contain whitespace-only changes. These are 1-based. Other meta information may be available, but most is intended for internal use and shouldn't be relied upon. """ mimetype = get_http_requested_mimetype( request, [mimetype['item'] for mimetype in self.allowed_mimetypes]) if mimetype == 'text/x-patch': return self._get_patch(request, *args, **kwargs) elif mimetype.startswith(self.DIFF_DATA_MIMETYPE_BASE + "+"): return self._get_diff_data(request, mimetype, *args, **kwargs) else: return super(FileDiffResource, self).get(request, *args, **kwargs)