Example #1
0
 def _handle(self, req):
     crawl_delay = wiking.cfg.crawl_delay
     if crawl_delay is not None:
         data = ("User-agent: *\n" "Crawl-delay: %d\n" % crawl_delay)
         return wiking.Response(data, 'text/plain')
     else:
         raise NotFound()
Example #2
0
 def _handle(self, req):
     """Serve the resource from a file."""
     if len(req.unresolved_path) < 1 or '..' in req.unresolved_path:
         # Avoid direcory traversal attacks.
         raise Forbidden()
     filename = os.path.join(*req.unresolved_path)
     response = self._handle_resource(req, filename)
     if response.status_code() == http.client.OK and filename.endswith(
             '.css'):
         # Substitute the current color theme in stylesheets.
         theme, theme_mtime = self._theme(req)
         stylesheet_mtime = response.last_modified()
         if stylesheet_mtime and theme_mtime:
             mtime = max(stylesheet_mtime, theme_mtime)
             if req.cached_since(mtime):
                 raise wiking.NotModified()
         else:
             mtime = None
         data = response.data()
         if isinstance(data, (list, types.GeneratorType)):
             data = b''.join(data)
         if isinstance(data, bytes):
             data = str(data, 'utf-8')
         data = self._substitute(data, theme)
         response = wiking.Response(data,
                                    content_type=response.content_type(),
                                    last_modified=mtime,
                                    filename=response.filename(),
                                    headers=response.headers())
     max_age = wiking.cfg.resource_client_cache_max_age
     if ((max_age is not None and response.last_modified() is not None
          and 'Cache-Control' not in dict(response.headers()))):
         response.add_header('Cache-Control', 'max-age=%d' % max_age)
     return response
Example #3
0
File: web.py Project: cerha/pytis
 def _info(self, req, storage, filename):
     resource = storage.resource(filename)
     if resource:
         import json
         info = self._resource_info(resource)
         return wiking.Response(json.dumps(info), content_type='application/json')
     else:
         raise wiking.NotFound
Example #4
0
File: web.py Project: cerha/pytis
 def _update(self, req, storage, filename):
     import json
     values = json.loads(req.param('values'))
     try:
         storage.update(filename, values)
     except Exception as e:
         response = str(e)
     else:
         response = 'OK'
     return wiking.Response(response, content_type='text/plain')
Example #5
0
File: web.py Project: cerha/pytis
 def _retrieve(self, req, storage, filename):
     f = storage.retrieve(filename)
     if f:
         def proxy(f):
             try:
                 while True:
                     data = f.read(524288)
                     if not data:
                         break
                     yield data
             finally:
                 f.close()
         return wiking.Response(proxy(f), content_type='application/octet-stream')
     else:
         raise wiking.NotFound
Example #6
0
File: web.py Project: cerha/pytis
 def _list(self, req, storage):
     import json
     result = [[r.filename(), self._resource_info(r)] for r in storage.resources()]
     return wiking.Response(json.dumps(result), content_type='application/json')
Example #7
0
 def _handle(self, req):
     try:
         try:
             if wiking.cfg.maintenance and not req.uri().startswith('/_resources/'):
                 # TODO: excluding /_resources/ is here to make stylesheets
                 # available for the maintenance error page.  The URI is
                 # however not necassarily correct (application may change
                 # it).  Better would most likely be including some basic styles
                 # directly in MinimalExporter.
                 return self._handle_maintenance_mode(req)
             # Very basic CSRF prevention
             if req.param('submit') and req.header('Referer'):
                 referer = urllib.parse.urlparse(req.header('Referer'))
                 referer_uri = referer.scheme + '://' + referer.netloc
                 server_uri = req.server_uri(current=True)
                 if referer_uri != server_uri:
                     wiking.debug("Request rejected due to CSRF protection:", referer_uri, server_uri)
                     raise wiking.Redirect(req.server_uri(current=True))
             # Regular processing starts here.
             try:
                 result = self._application.handle(req)
             except wiking.Abort as abort:
                 result = abort.result()
             if isinstance(result, (tuple, list)):
                 # Temporary backwards compatibility conversion.
                 content_type, data = result
                 result = wiking.Response(data, content_type=content_type)
             if req.is_api_request() and isinstance(result, (lcg.Content, wiking.Document)):
                 # This is a very generic detection of invalid API
                 # requests.  We just assume, that the clients, which
                 # indicate that they accept JSON responses are API
                 # clients and they are not interested in responses, which
                 # display human readable content.
                 raise wiking.BadRequest(_("This URI does not belong to server API."))
             if isinstance(result, wiking.Document):
                 # Perform authentication here if it was not performed before
                 # to handle authentication exceptions now and prevent them in
                 # export time.  When the result is a Document, we will always
                 # need to know the authenticated user in order to display the
                 # login control at the top of the page.
                 user = req.user()
                 if user:
                     password_expiration = user.password_expiration()
                     password_change_uri = wiking.module.Application.password_change_uri(req)
                     if ((password_change_uri and password_expiration and
                          password_expiration <= datetime.date.today() and
                          req.uri() != password_change_uri)):
                         req.message(_("Your password expired."), req.ERROR)
                         req.message(_("Access to the application is now restricted "
                                       "until you change your password."))
                         raise wiking.Redirect(password_change_uri)
                 return self._serve_document(req, result)
             elif isinstance(result, lcg.Content):
                 return self._serve_content(req, result)
             elif isinstance(result, wiking.Response):
                 last_modified = result.last_modified()
                 if last_modified is not None and req.cached_since(last_modified):
                     raise wiking.NotModified()
                 for header, value in result.headers():
                     req.set_header(header, value)
                 filename = result.filename()
                 if filename:
                     # When the filename contains non-ascii characters, uwsgi raises:
                     # TypeError: http header must be encodable in latin1
                     # Some context at: https://stackoverflow.com/questions/93551/
                     try:
                         filename.encode('latin-1')
                     except UnicodeEncodeError:
                         filename_info = "filename*=UTF-8''" + urllib.parse.quote(filename)
                     else:
                         filename_info = 'filename="%s"' % filename
                     disposition = 'inline' if result.inline() else 'attachment'
                     req.set_header('Content-Disposition', disposition + '; ' + filename_info)
                 return req.send_response(result.data(), content_type=result.content_type(),
                                          content_length=result.content_length(),
                                          status_code=result.status_code(),
                                          last_modified=result.last_modified())
             else:
                 raise Exception('Invalid handler result: %s' % type(result))
         except wiking.NotModified as error:
             return req.send_response('', status_code=error.status_code(), content_type=None)
         except wiking.Redirect as r:
             return req.redirect(r.uri(), r.args(), status_code=r.status_code())
         except wiking.RequestError as error:
             # Try to authenticate now, but ignore all errors within authentication except
             # for AuthenticationError.
             try:
                 req.user()
             except wiking.RequestError:
                 pass
             except wiking.AuthenticationError as auth_error:
                 error = auth_error
             return self._handle_request_error(req, error)
         except wiking.ClosedConnection:
             return []
     except Exception:
         # Any other unhandled exception is an Internal Server Error.  It is
         # handled in a separate try/except block to chatch also errors in
         # except blocks of the inner level.
         return self._handle_request_error(req, wiking.InternalServerError())