0

Over the weekend chrome seems to have updated and now blocks my cross-domain requests:

I have one server, two domains, and a shared web icon font on one that needs to load on the other. I'd rather not force cherrypy to be aware of which domain it is serving (the mirror or the main one), because for that effort I might as well clone all the code.

My chrome console.log error message is:

Font from origin 'http://djotjog.com' has been blocked from loading by Cross-Origin Resource Sharing policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://storylearning.org' is therefore not allowed access. 

In cherrypy I tried to enable this but the docs are sketchy. Here is what I tried:

class root:
def stest(self, **kw):
    cherrypy.response.headers['Content-Type'] = 'text/html'
    cherrypy.response.headers["Access-Control-Allow-Origin"] = "*"
    html = some_function()
    return html

def CORS():
    cherrypy.response.headers["Access-Control-Allow-Origin"] = "*" 
if __name__=="__main__":
    cherrypy.tools.CORS = cherrypy.Tool('before_handler', CORS)  

cherrypy.config.update({
'environment': 'production',
'log.screen': False,
'log.error_file':'cperror.log',
'server.socket_host': '127.0.0.1',
'server.socket_port': 15722,
'server.thread_pool': 2,
'server.thread_pool_max': 2

So what is the right way to handle cross-domain requests on cherrypy?

Marc Maxmeister
  • 4,191
  • 4
  • 40
  • 54

1 Answers1

1

First, it's quite unclear why do have the issue if you say it's a mirror. If it's really a mirror then you would just need to refer to your font file with a relative URL (/path/to/your/font.otf).

Second, web fonts were subject to CORS since 2010 at least in FF and IE (see bugreport). And the behaviour is actually by design (see spec). So if you ever tested your site in these browsers you should be seeing the same thing.

Third, if you're talking of partial mirrors, then the following should serve your need.

app.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-


import os

import cherrypy
from cherrypy.lib import static


path   = os.path.abspath(os.path.dirname(__file__))
config = {
  'global' : {
    'server.socket_host' : '127.0.0.1',
    'server.socket_port' : 8080,
    'server.thread_pool' : 8
  },
  '/font' : {
    'tools.corsstaticdir.on'  : True,
    'tools.corsstaticdir.dir' : os.path.join(path, 'font'),
    # This is a workaround for CherryPy flaw  where they set ``section`` 
    # tool config variable in ``cherrypy._cpdispatch.Dispatcher.set_conf`` 
    # exclusivety for ``staticdir`` tool (http://goo.gl/EGIIvA).
    'tools.corsstaticdir.section' : '/font',    
  }  
}


def corsstaticdir(section, dir, root = '', match = '', content_types = None, index = '', debug = False):
  cherrypy.response.headers['Access-Control-Allow-Origin'] = '*'
  return static.staticdir(section, dir, root, match, content_types, index, debug)

cherrypy.tools.corsstaticdir = cherrypy._cptools.HandlerTool(corsstaticdir)


class App:

  @cherrypy.expose
  def index(self):
    return static.serve_file(os.path.join(path, 'index.html')) 


if __name__ == '__main__':
  cherrypy.quickstart(App(), '/', config)

index.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv='content-type' content='text/html; charset=utf-8'/>
<title>CORS font</title>
<style type='text/css'>
  @font-face {
    font-family : YourFontRegular;
    font-weight : normal;
    font-style  : normal;      
    src         : url('http://anotherdomain/font/Quicksand-Regular.otf');
  }
  p {
    font-family : YourFontRegular;
  }
</style>
</head>
<body>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam placerat lacinia tortor. Nulla viverra, dolor nec malesuada congue, lectus quam dictum tellus, at malesuada nisl tortor quis ligula. Donec aliquam id arcu quis consectetur. Sed vitae turpis quis metus consequat vulputate.</p>
</body>
</html>
saaj
  • 23,253
  • 3
  • 104
  • 105
  • Thanks. Since the specs say, "fonts will typically not be loaded cross-origin unless authors specifically takes steps to permit cross-origin loads." -- I need to know how to enable this. I have two cherrypy instances on two domains, and a static server that has the font file on one domain. You suggest I set up the other domain to have that static server as the identical relative link to avoid this, right? That may be tricky. The relative maps are not identical. – Marc Maxmeister Sep 09 '14 at 18:34
  • I've already written that if these two domains are not full mirrors, which is true at least because you say the relative paths are not the same, just use the tool, ``corsstaticdir``, I contributed. Put the fonts in a directory, configure the tool to use the directory, and you're ready to go. – saaj Sep 10 '14 at 08:53
  • I will give it a try later. For now I've fixed the relative paths to match so I can just use relative links, and that fixes the CORS error message for now. Took a lot less time (5min after an hour of trying to enable CRS) – Marc Maxmeister Sep 10 '14 at 18:16