145 строки
4.4 KiB
Python
145 строки
4.4 KiB
Python
import re
|
|
import sys
|
|
from collections import defaultdict
|
|
from email.Utils import formatdate
|
|
from string import Template
|
|
from time import time
|
|
from urlparse import parse_qsl
|
|
|
|
import jinja2
|
|
|
|
import olympia.core.logger
|
|
|
|
from utils import log_configure
|
|
|
|
# This has to be imported after the settings so statsd knows where to log to.
|
|
from django_statsd.clients import statsd
|
|
|
|
JAVA_PLUGIN_SUMO_URL = (
|
|
'https://support.mozilla.org/'
|
|
'kb/use-java-plugin-to-view-interactive-content')
|
|
|
|
|
|
# Go configure the log.
|
|
log_configure()
|
|
|
|
error_log = olympia.core.logger.getLogger('z.pfs')
|
|
|
|
xml_template = """\
|
|
<?xml version="1.0"?>
|
|
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
xmlns:pfs="http://www.mozilla.org/2004/pfs-rdf#">
|
|
|
|
<RDF:Description about="urn:mozilla:plugin-results:$mimetype">
|
|
<pfs:plugins><RDF:Seq>
|
|
<RDF:li resource="urn:mozilla:plugin"/>
|
|
</RDF:Seq></pfs:plugins>
|
|
</RDF:Description>
|
|
|
|
<RDF:Description about="urn:mozilla:plugin">
|
|
<pfs:updates><RDF:Seq>
|
|
<RDF:li resource="urn:mozilla:plugin:updates"/>
|
|
</RDF:Seq></pfs:updates>
|
|
</RDF:Description>
|
|
|
|
<RDF:Description about="urn:mozilla:plugin:updates">
|
|
<pfs:name>$name</pfs:name>
|
|
<pfs:requestedMimetype>$mimetype</pfs:requestedMimetype>
|
|
<pfs:manualInstallationURL>$manualInstallationURL</pfs:manualInstallationURL>
|
|
</RDF:Description>
|
|
|
|
</RDF:RDF>
|
|
"""
|
|
|
|
quicktime_re = re.compile(
|
|
r'^image/(pict|png|tiff|x-(macpaint|pict|png|quicktime|sgi|targa|tiff))$')
|
|
java_re = re.compile(r'^application/x-java-.*$')
|
|
|
|
|
|
def get_output(data):
|
|
g = defaultdict(str, [(k, jinja2.escape(v)) for k, v in data.iteritems()])
|
|
|
|
required = ['mimetype', 'appID', 'appVersion', 'clientOS', 'chromeLocale']
|
|
|
|
# Some defaults we override depending on what we find below.
|
|
plugin = dict(mimetype='-1', name='-1',
|
|
manualInstallationURL='')
|
|
|
|
# Special case for mimetype if they are provided.
|
|
plugin['mimetype'] = g['mimetype'] or '-1'
|
|
|
|
output = Template(xml_template)
|
|
|
|
for s in required:
|
|
if s not in data:
|
|
# A sort of 404, matching what was returned in the original PHP.
|
|
return output.substitute(plugin)
|
|
|
|
# Figure out what plugins we've got, and what plugins we know where
|
|
# to get.
|
|
|
|
# Begin our huge and embarrassing if-else statement.
|
|
if g['mimetype'] in ['application/x-shockwave-flash',
|
|
'application/futuresplash']:
|
|
# Tell the user where they can go to get the installer.
|
|
|
|
plugin.update(
|
|
name='Adobe Flash Player',
|
|
manualInstallationURL='https://get.adobe.com/flashplayer/')
|
|
|
|
elif g['mimetype'] == 'application/x-director':
|
|
plugin.update(
|
|
name='Adobe Shockwave Player',
|
|
manualInstallationURL='https://get.adobe.com/shockwave/')
|
|
elif quicktime_re.match(g['mimetype']):
|
|
# Well, we don't have a plugin that can handle any of those
|
|
# mimetypes, but the Apple Quicktime plugin can. Point the user to
|
|
# the Quicktime download page.
|
|
|
|
plugin.update(
|
|
name='Apple Quicktime',
|
|
InstallerShowsUI='true',
|
|
manualInstallationURL='https://www.apple.com/quicktime/download/')
|
|
|
|
elif java_re.match(g['mimetype']):
|
|
# We don't want to link users directly to the Java plugin because
|
|
# we want to warn them about ongoing security problems first. Link
|
|
# to SUMO.
|
|
plugin.update(
|
|
name='Java Runtime Environment',
|
|
manualInstallationURL=JAVA_PLUGIN_SUMO_URL)
|
|
|
|
# End ridiculously huge and embarrassing if-else block.
|
|
return output.substitute(plugin)
|
|
|
|
|
|
def format_date(secs):
|
|
return '%s GMT' % formatdate(time() + secs)[:25]
|
|
|
|
|
|
def get_headers(length):
|
|
return [('Content-Type', 'text/xml; charset=utf-8'),
|
|
('Cache-Control', 'public, max-age=3600'),
|
|
('Last-Modified', format_date(0)),
|
|
('Expires', format_date(3600)),
|
|
('Content-Length', str(length))]
|
|
|
|
|
|
def log_exception(data):
|
|
(typ, value, traceback) = sys.exc_info()
|
|
error_log.error(u'Type: %s, %s. Query: %s' % (typ, value, data))
|
|
|
|
|
|
def application(environ, start_response):
|
|
status = '200 OK'
|
|
|
|
with statsd.timer('services.pfs'):
|
|
data = dict(parse_qsl(environ['QUERY_STRING']))
|
|
try:
|
|
output = get_output(data).encode('utf-8')
|
|
start_response(status, get_headers(len(output)))
|
|
except Exception:
|
|
log_exception(data)
|
|
raise
|
|
return [output]
|