source: contextchromeplugin/0.12/contextchrome/cors.py

Last change on this file was 13413, checked in by matobaa, 10 years ago

ContextChromePlugin: fix a bug for CORS - Cross Origin Resource Sharing
refs #6827

File size: 3.3 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#
4# Copyright (C) 2013 MATOBA Akihiro <matobaa+trac-hacks@gmail.com>
5# All rights reserved.
6#
7# This software is licensed as described in the file COPYING, which
8# you should have received as part of this distribution.
9
10# Tested on
11#  - Internet Explorer 10.0.9200.16618
12#  - Google Chrome 27.0.1453.110 m
13#  - Firefox 18.0.1
14
15from trac.core import Component, implements
16from trac.web.api import RequestDone
17from trac.config import Option
18
19try:
20    from tracrpc.api import IRPCProtocol, IXMLRPCHandler
21    from tracrpc.json_rpc import JsonRpcProtocol
22
23    class CrossOriginResourceSharingEnabler(Component):
24        """Enable CORS access from another site for XmlRpcPlugin; see: http://www.w3.org/TR/cors/"""
25        implements(IRPCProtocol, IXMLRPCHandler)
26
27        jsonrpc_origin = Option('rpc', 'jsonrpc_origin', '',
28        doc=u"""SP separated permitted origins;
29        Where do you want to permit requests from;
30        for jsonrpc Cross-Origin Resource Sharing.
31        http://example.com/path for specified, blank for nowhere,
32        {{{*}}}(asterisk) for anywhere to permit.
33        See: http://www.w3.org/TR/cors/, rfc:6454.
34        (Provided by !ContextChrome.!CrossOriginResourceSharingEnabler)""")
35
36        wrapped = None
37
38        # IRPCProtocol methods
39        def rpc_info(self):
40            return 'CORS', 'Cross Origin Resource Sharing Enabler'
41
42        def rpc_match(self):
43            if not self.wrapped:
44                self.wrap()
45            yield ('jsonrpc', 'text/plain')
46
47        def parse_rpc_request(self, req, content_type):
48            return {'method': 'CORS.dummy'}
49
50        def send_rpc_result(self, req, result):
51            jsonrpc_origin = self.config.get('rpc', 'jsonrpc_origin')
52            req.send_response(200)
53            req.send_header('Content-Length', 0)
54            req.send_header('Access-Control-Allow-Origin', jsonrpc_origin)  # req.get_header('Origin'))
55            req.send_header('Access-Control-Allow-Headers', 'Content-Type')
56            req.end_headers()
57            req.write('\n')
58            raise RequestDone()
59
60        def send_rpc_error(self, req, e):
61            req.send_response(500)
62            req.send_header('Content-Length', 0)
63            req.end_headers()
64            req.write('\n')
65            raise RequestDone()
66
67        #IXMLRPCHandler methods
68        def xmlrpc_namespace(self):
69            return 'CORS'
70
71        def xmlrpc_methods(self):
72            yield ('TICKET_VIEW', ((None,),), lambda req: None, 'dummy')
73
74        def wrap(self):
75            jsonRpcProtocol = self.compmgr[JsonRpcProtocol]
76            if not jsonRpcProtocol:
77                self.wrapped = 1  # avoid to wrap again
78                return
79
80            def _send_response(*args, **kwargs):  # hook method
81                jsonrpc_origin = self.config.get('rpc', 'jsonrpc_origin')
82                args[0].send_header('Access-Control-Allow-Origin', jsonrpc_origin)  # args[0].get_header('Origin'))
83                return self.wrapped(*args, **kwargs)
84            self.wrapped = jsonRpcProtocol._send_response
85            jsonRpcProtocol._send_response = _send_response
86
87except:
88    class CrossOriginResourceSharingEnabler(Component):
89        """(Disabled; XmlRpcPlugin required. See http://trac-hacks.org/wiki/XmlRpcPlugin.)"""
90        pass
Note: See TracBrowser for help on using the repository browser.