Example #1
0
 def _transform(self, resource, reverse, path=[]):
     if isinstance(resource, dict):
         if '!type' not in resource:
             if reverse:
                 raise HTTPReturn(http.INTERNAL_SERVER_ERROR,
                                  reason='Resource does not specify !type')
             elif len(path) == 0:
                 type = collection.contains
             else:
                 type = self.hints.get(path).get('type')
                 if type is None:
                     raise HTTPReturn(http.BAD_REQUEST,
                                      reason='No type hint for resource.')
             resource['!type'] = type
         path.append(None)
         for key, value in resource.items():
             path[-1] = key
             resource[key] = self._transform(value, reverse, path)
         del path[-1]
         proc = self._get_transform(resource, reverse)
         if proc:
             if reverse:
                 resource = proc.process_reverse(resource)
             else:
                 resource = proc.process(resource)
     elif isinstance(resource, list):
         for ix, elem in enumerate(resource):
             resource[ix] = self._transform(resource[ix], reverse, path)
     return resource
Example #2
0
 def filter(self, output):
     if output:
         raise HTTPReturn(
             http.INTERNAL_SERVER_ERROR,
             reason='Not expecting any output for "delete" action')
     response.status = http.NO_CONTENT
     return ''
Example #3
0
 def parse(self, input, encoding):
     """Parse a JSON entity."""
     try:
         parsed = json.loads(input, encoding)
     except ValueError, err:
         raise HTTPReturn(http.BAD_REQUEST,
                          reason='JSON parsing error: %s' % str(err))
Example #4
0
 def format(self, object, encoding=None):
     """Format a resource as YAML under the specified encoding."""
     try:
         output = yaml.dump(object,
                            default_flow_style=False,
                            version=(1, 1),
                            encoding=encoding)
     except YAMLError, e:
         raise HTTPReturn(http.INTERNAL_SERVER_ERROR,
                          reason='YAML dump error: %s' % str(e))
Example #5
0
 def parse(self, input, encoding=None):
     """Parse a YAML entity."""
     # We can ignore the encoding as the YAML spec mandates either UTF-8
     # or UTF-16 with a BOM, which can be autodetected.
     # We use a Loader that turns unrecognized !tags into Resources.
     try:
         parsed = yaml.load(input)
     except YAMLError, e:
         raise HTTPReturn(http.BAD_REQUEST,
                          reason='YAML load error: %s' % str(e))
Example #6
0
 def handle(self, exception):
     if not isinstance(exception, ArgProcError):
         return exception
     format = FormatEntity()
     error = Resource('error')
     error['id'] = 'rest.entity_error'
     error['message'] = str(exception)
     body = format.filter(error)
     headers = response.headers
     raise HTTPReturn(http.BAD_REQUEST, headers=headers, body=body)
Example #7
0
 def parse(self, input, encoding=None):
     """Parse XML from `input' according to `encoding'."""
     if encoding and self._re_preamble_start.match(input):
         # The encoding from the HTTP header takes precedence. The preamble
         # is the only way in which we can pass it on to ElementTree.
         preamble = '<?xml version="1.0" encoding="%s" ?>' % encoding
         mobj = self._re_preamble_end.search(input)
         if mobj == None:
             raise HTTPReturn(http.BAD_REQUEST, reason='Illegal XML input')
         input = input[mobj.end() + 1:]
     elif not encoding and not self._re_preamble_start.match(input):
         # RFC2616 section 3.7.1
         preamble = '<?xml version="1.0" encoding="utf-8" ?>'
     else:
         preamble = ''
     try:
         root = etree.fromstring(preamble + input)
     except ExpatError, err:
         raise HTTPReturn(http.BAD_REQUEST,
                          reason='XML Error: %s' % str(err))
Example #8
0
 def format(self, object):
     """Format an entity."""
     if not isinstance(object, dict) and not isinstance(object, list):
         return object
     accept = request.header('Accept', '*/*')
     ctype = http.select_content_type(self.formatters.keys(), accept)
     if not ctype:
         raise HTTPReturn(http.NOT_ACCEPTABLE,
                          reason='No acceptable content-type in: %s' %
                          accept)
     accept = request.header('Accept-Charset', '*')
     charset = http.select_charset(('utf-8', ), accept)
     if not charset:
         raise HTTPReturn(http.NOT_ACCEPTABLE,
                          reason='No acceptable charset in: %s' % accept)
     formatter = self.formatters[ctype]
     output = formatter.format(object, charset)
     response.set_header('Content-Type',
                         '%s; charset=%s' % (ctype, charset))
     response.set_header('Content-Length', str(len(output)))
     return output
Example #9
0
 def parse(self, input):
     """Parse an entity."""
     ctype = request.header('Content-Type')
     if not ctype:
         raise HTTPReturn(http.BAD_REQUEST,
                          reason='Missing Content-Type header')
     try:
         type, subtype, options = http.parse_content_type(ctype)
     except ValueError:
         raise HTTPReturn(http.BAD_REQUEST,
                          reason='Illegal Content-Type header [%s]' % ctype)
     ctype = '%s/%s' % (type, subtype)
     encoding = options.get('charset')
     if not len(input):
         raise HTTPReturn(http.BAD_REQUEST,
                          reason='No request entity provided')
     if ctype not in self.parsers:
         raise HTTPReturn(http.UNSUPPORTED_MEDIA_TYPE,
                          reason='Content-Type not supported [%s]' % ctype)
     parser = self.parsers[ctype]
     parsed = parser.parse(input, encoding)
     return parsed
Example #10
0
 def _get_detail(self):
     for i in range(4):
         ctypes.append('text/xml; detail=%s' % i)
         ctypes.append('text/yaml; detail=%s' % i)
     ctype = request.preferred_content_type(ctypes)
     if ctype is None:
         return
     sub, subtype, params = http.parse_content_type(ctype)
     try:
         detail = int(params['detail'])
     except ValueError:
         raise HTTPReturn(http.NOT_ACCEPTABLE,
                          reason='Non-integer "detail" in Accept header.')
     return detail
Example #11
0
 def read(self, size=None):
     """Read from the request."""
     if self.content_length is None:
         encoding = self.header('Transfer-Encoding', 'identity')
         if encoding != 'identity':
             raise HTTPReturn(http.NOT_IMPLEMENTED,
                              reason='Unsupported transfer encoding [%s]' %
                              encoding)
         self.content_length = int(self.header('Content-Length', '0'))
     # Make sure we never attempt to read beyond Content-Length, as some
     # WSGI servers will block instead of returning EOF (which is allowed
     # by PEP-333).
     bytes_left = self.content_length - self.bytes_read
     if size is None or size > bytes_left:
         size = bytes_left
     input = self.environ['wsgi.input']
     data = input.read(size)
     self.bytes_read += len(data)
     return data
Example #12
0
 def filter(self, input):
     if input:
         reason = 'Action does not accept any input.'
         raise HTTPReturn(http.BAD_REQUEST, reason=reason)
     return input
Example #13
0
 def filter(self, input):
     if request.match.get('action') == '_method_not_allowed':
         headers = [('Allowed', ', '.join(mapper.methods_for(request.path)))
                    ]
         raise HTTPReturn(http.METHOD_NOT_ALLOWED, headers)
     return input