Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

merged from default

changeset:   2318:5f526ab13f38
parent:      2316:a719acf41723
user:        Chris AtLee <catlee@mozilla.com>
date:        Fri Dec 02 16:03:39 2011 -0500
summary:     Bug 509158: Signing support in build factories. r=bhearsum

changeset:   2319:202dfd424ea1
user:        Rail Aliiev <rail@mozilla.com>
date:        Fri Dec 02 16:07:07 2011 -0500
summary:     Bug 706832 - Implement master side token generation for signing on demand. r=catlee,bhearsum

changeset:   2320:c6f4f75908cb
user:        Chris Cooper <ccooper@deadsquid.com>
date:        Fri Dec 02 16:14:16 2011 -0500
summary:     Bug 671450 - Try different sources for revision in log_uploader - r=nthomas

changeset:   2321:a92845bec18e
user:        Ben Hearsum <bhearsum@mozilla.com>
date:        Fri Dec 02 17:01:44 2011 -0500
summary:     bug 509158: Sign builds as part of the build process: enable signing server for debug builds; disable pre-signed updater on elm. r=rail/catlee

changeset:   2322:d61c24d02d97
tag:         tip
user:        Chris AtLee <catlee@mozilla.com>
date:        Sun Dec 04 14:22:24 2011 -0500
summary:     Bug 509158: Don't enable signing for l10n check steps. r=rail

--HG--
branch : production-0.8
  • Loading branch information...
commit 2fbdfdd4275f6bcf6c61b0f6de60171860f92137 2 parents 9518530 + 3a1f902
Chris AtLee authored December 05, 2011
9  bin/log_uploader.py
@@ -294,10 +294,17 @@ def formatLog(tmpdir, build, builder_suffix=''):
294 294
                         uploadArgs['to_shadow'] = False
295 295
                         uploadArgs['to_tinderbox_dated'] = True
296 296
 
  297
+                props = build.getProperties()
  298
+                if props.getProperty('got_revision') is not None:
  299
+                    revision=props['got_revision']
  300
+                elif props.getProperty('revision') is not None:
  301
+                    revision=props['revision']
  302
+                else:
  303
+                    revision=None
297 304
                 uploadArgs.update(dict(
298 305
                     to_try=False,
299 306
                     who=None,
300  
-                    revision=None,
  307
+                    revision=revision,
301 308
                     buildid=buildid,
302 309
                     ))
303 310
             post_upload_cmd = postUploadCmdPrefix(**uploadArgs)
21  misc.py
@@ -550,7 +550,7 @@ def generateCCTestBuilder(config, branch_name, platform, name_prefix,
550 550
     return builders
551 551
 
552 552
 
553  
-def generateBranchObjects(config, name):
  553
+def generateBranchObjects(config, name, secrets=None):
554 554
     """name is the name of branch which is usually the last part of the path
555 555
        to the repository. For example, 'mozilla-central', 'mozilla-aurora', or
556 556
        'mozilla-1.9.1'.
@@ -567,6 +567,8 @@ def generateBranchObjects(config, name):
567 567
         'schedulers': [],
568 568
         'status': []
569 569
     }
  570
+    if secrets is None:
  571
+        secrets = {}
570 572
     builders = []
571 573
     unittestBuilders = []
572 574
     triggeredUnittestBuilders = []
@@ -1124,6 +1126,7 @@ def generateBranchObjects(config, name):
1124 1126
                 'l10nCheckTest': pf.get('l10n_check_test', False),
1125 1127
                 'android_signing': pf.get('android_signing', False),
1126 1128
                 'post_upload_include_platform': pf.get('post_upload_include_platform', False),
  1129
+                'signingServers': secrets.get(pf.get('dep_signing_servers')),
1127 1130
                 'baseMirrorUrls': config.get('base_mirror_urls'),
1128 1131
                 'baseBundleUrls': config.get('base_bundle_urls'),
1129 1132
                 'mozillaDir': config.get('mozilla_dir', None),
@@ -1381,6 +1384,7 @@ def generateBranchObjects(config, name):
1381 1384
                 l10nCheckTest=pf.get('l10n_check_test', False),
1382 1385
                 android_signing=pf.get('android_signing', False),
1383 1386
                 post_upload_include_platform=pf.get('post_upload_include_platform', False),
  1387
+                signingServers=secrets.get(pf.get('nightly_signing_servers')),
1384 1388
                 baseMirrorUrls=config.get('base_mirror_urls'),
1385 1389
                 baseBundleUrls=config.get('base_bundle_urls'),
1386 1390
                 **nightly_kwargs
@@ -1407,14 +1411,11 @@ def generateBranchObjects(config, name):
1407 1411
                 if platform in config['l10n_platforms']:
1408 1412
                     # TODO Linux and mac are not working with mozconfig at this point
1409 1413
                     # and this will disable it for now. We will fix this in bug 518359.
1410  
-                    env = {}
1411  
-                    if 'HG_SHARE_BASE_DIR' in platform_env:
1412  
-                        env['HG_SHARE_BASE_DIR'] = platform_env['HG_SHARE_BASE_DIR']
1413 1414
                     objdir = ''
1414 1415
                     mozconfig = None
1415 1416
 
1416 1417
                     mozilla2_l10n_nightly_factory = NightlyRepackFactory(
1417  
-                        env=env,
  1418
+                        env=platform_env,
1418 1419
                         objdir=objdir,
1419 1420
                         platform=platform,
1420 1421
                         hgHost=config['hghost'],
@@ -1447,6 +1448,7 @@ def generateBranchObjects(config, name):
1447 1448
                         buildSpace=l10nSpace,
1448 1449
                         clobberURL=config['base_clobber_url'],
1449 1450
                         clobberTime=clobberTime,
  1451
+                        signingServers=secrets.get(pf.get('nightly_signing_servers')),
1450 1452
                         baseMirrorUrls=config.get('base_mirror_urls'),
1451 1453
                     )
1452 1454
                     mozilla2_l10n_nightly_builder = {
@@ -1498,7 +1500,7 @@ def generateBranchObjects(config, name):
1498 1500
                     buildSpace=buildSpace,
1499 1501
                     clobberURL=config['base_clobber_url'],
1500 1502
                     clobberTime=clobberTime,
1501  
-                    buildsBeforeReboot=pf['builds_before_reboot']
  1503
+                    buildsBeforeReboot=pf['builds_before_reboot'],
1502 1504
                 )
1503 1505
                 mozilla2_shark_builder = {
1504 1506
                     'name': '%s shark' % pf['base_name'],
@@ -1543,11 +1545,8 @@ def generateBranchObjects(config, name):
1543 1545
         # We still want l10n_dep builds if nightlies are off
1544 1546
         if config['enable_l10n'] and platform in config['l10n_platforms'] and \
1545 1547
            config['enable_l10n_onchange']:
1546  
-            env = {}
1547  
-            if 'HG_SHARE_BASE_DIR' in platform_env:
1548  
-                env['HG_SHARE_BASE_DIR'] = platform_env['HG_SHARE_BASE_DIR']
1549 1548
             mozilla2_l10n_dep_factory = NightlyRepackFactory(
1550  
-                env=env,
  1549
+                env=platform_env,
1551 1550
                 platform=platform,
1552 1551
                 hgHost=config['hghost'],
1553 1552
                 tree=config['l10n_tree'],
@@ -1567,6 +1566,7 @@ def generateBranchObjects(config, name):
1567 1566
                 buildSpace=l10nSpace,
1568 1567
                 clobberURL=config['base_clobber_url'],
1569 1568
                 clobberTime=clobberTime,
  1569
+                signingServers=secrets.get(pf.get('dep_signing_servers')),
1570 1570
                 baseMirrorUrls=config.get('base_mirror_urls'),
1571 1571
             )
1572 1572
             mozilla2_l10n_dep_builder = {
@@ -1750,6 +1750,7 @@ def generateBranchObjects(config, name):
1750 1750
                  clobberTime=clobberTime,
1751 1751
                  buildsBeforeReboot=pf['builds_before_reboot'],
1752 1752
                  packageSDK=True,
  1753
+                 signingServers=secrets.get(pf.get('nightly_signing_servers')),
1753 1754
              )
1754 1755
              mozilla2_xulrunner_builder = {
1755 1756
                  'name': '%s xulrunner' % pf['base_name'],
93  process/factory.py
@@ -26,6 +26,7 @@
26 26
 import buildbotcustom.steps.updates
27 27
 import buildbotcustom.steps.talos
28 28
 import buildbotcustom.steps.unittest
  29
+import buildbotcustom.steps.signing
29 30
 import buildbotcustom.env
30 31
 import buildbotcustom.misc_scheduler
31 32
 import build.paths
@@ -42,6 +43,7 @@
42 43
 reload(buildbotcustom.steps.updates)
43 44
 reload(buildbotcustom.steps.talos)
44 45
 reload(buildbotcustom.steps.unittest)
  46
+reload(buildbotcustom.steps.signing)
45 47
 reload(buildbotcustom.env)
46 48
 reload(build.paths)
47 49
 reload(release.info)
@@ -64,6 +66,7 @@
64 66
 from buildbotcustom.steps.transfer import MozillaStageUpload
65 67
 from buildbotcustom.steps.updates import CreateCompleteUpdateSnippet, \
66 68
   CreatePartialUpdateSnippet
  69
+from buildbotcustom.steps.signing import SigningServerAuthenication
67 70
 from buildbotcustom.env import MozillaEnvironments
68 71
 from buildbotcustom.common import getSupportedPlatforms, getPlatformFtpDir, \
69 72
   genBuildID, reallyShort
@@ -82,14 +85,19 @@
82 85
 hg_l10n_lock = locks.MasterLock("hg_l10n_lock", maxCount=20)
83 86
 
84 87
 class DummyFactory(BuildFactory):
85  
-    def __init__(self):
  88
+    def __init__(self, delay=5, triggers=None):
86 89
         BuildFactory.__init__(self)
87  
-        self.addStep(Dummy())
  90
+        self.addStep(Dummy(delay))
  91
+        if triggers:
  92
+            self.addStep(Trigger(
  93
+                schedulerNames=triggers,
  94
+                waitForFinish=False,
  95
+                ))
88 96
 
89  
-def makeDummyBuilder(name, slaves, category=None):
  97
+def makeDummyBuilder(name, slaves, category=None, delay=0, triggers=None):
90 98
     builder = {
91 99
             'name': name,
92  
-            'factory': DummyFactory(),
  100
+            'factory': DummyFactory(delay, triggers),
93 101
             'builddir': name,
94 102
             'slavenames': slaves,
95 103
             }
@@ -689,6 +697,7 @@ def __init__(self, env, objdir, platform, configRepoPath, configSubDir,
689 697
                  multiLocaleScript=None,
690 698
                  multiLocaleConfig=None,
691 699
                  mozharnessMultiOptions=None,
  700
+                 signingServers=None,
692 701
                  **kwargs):
693 702
         MozillaBuildFactory.__init__(self, **kwargs)
694 703
 
@@ -754,6 +763,7 @@ def __init__(self, env, objdir, platform, configRepoPath, configSubDir,
754 763
         self.useSharedCheckouts = useSharedCheckouts
755 764
         self.testPrettyNames = testPrettyNames
756 765
         self.l10nCheckTest = l10nCheckTest
  766
+        self.signingServers = signingServers
757 767
 
758 768
         if self.uploadPackages:
759 769
             assert productName and stageServer and stageUsername
@@ -838,6 +848,17 @@ def __init__(self, env, objdir, platform, configRepoPath, configSubDir,
838 848
             self.logBaseUrl = 'http://%s/pub/mozilla.org/%s/%s' % \
839 849
                         ( self.stageServer, self.stageProduct, self.logUploadDir)
840 850
 
  851
+        if signingServers:
  852
+            cmd = [
  853
+                env.get('PYTHON26', 'python'), "%(toolsdir)s/release/signing/signtool.py",
  854
+                "-t", "%(basedir)s/build/token",
  855
+                "-n", "%(basedir)s/build/nonce",
  856
+                "-c", "%(toolsdir)s/release/signing/host.cert",
  857
+                ]
  858
+            for ss, user, passwd in signingServers:
  859
+                cmd.extend(['-H', ss])
  860
+            self.env['MOZ_SIGN_CMD'] = WithProperties(" ".join(cmd))
  861
+
841 862
         # Need to override toolsdir as set by MozillaBuildFactory because
842 863
         # we need Windows-style paths.
843 864
         if self.platform.startswith('win'):
@@ -967,6 +988,8 @@ def addBuildSteps(self):
967 988
         self.addSourceSteps()
968 989
         self.addConfigSteps()
969 990
         self.addDoBuildSteps()
  991
+        if self.signingServers:
  992
+            self.addGetTokenSteps()
970 993
         if self.doBuildAnalysis:
971 994
             self.addBuildAnalysisSteps()
972 995
 
@@ -1095,6 +1118,26 @@ def addConfigSteps(self):
1095 1118
          command=['cat', '.mozconfig'],
1096 1119
         ))
1097 1120
 
  1121
+    def addGetTokenSteps(self):
  1122
+        server_cert = os.path.join(
  1123
+            os.path.dirname(build.paths.__file__),
  1124
+            '../../../release/signing/host.cert')
  1125
+        token = "build/token"
  1126
+        nonce = "build/nonce"
  1127
+        self.addStep(ShellCommand(
  1128
+            command=['rm', '-f', nonce],
  1129
+            workdir='.',
  1130
+            name='rm_nonce',
  1131
+            description=['remove', 'old', 'nonce'],
  1132
+        ))
  1133
+        self.addStep(SigningServerAuthenication(
  1134
+            servers=self.signingServers,
  1135
+            server_cert=server_cert,
  1136
+            slavedest=token,
  1137
+            workdir='.',
  1138
+            name='download_token',
  1139
+        ))
  1140
+
1098 1141
     def addDoBuildSteps(self):
1099 1142
         workdir=WithProperties('%(basedir)s/build')
1100 1143
         if self.platform.startswith('win'):
@@ -1351,11 +1394,18 @@ def addCheckTestSteps(self):
1351 1394
         )
1352 1395
 
1353 1396
     def addL10nCheckTestSteps(self):
  1397
+        # We override MOZ_SIGN_CMD here because it's not necessary
  1398
+        # Disable signing for l10n check steps
  1399
+        env = self.env
  1400
+        if 'MOZ_SIGN_CMD' in env:
  1401
+            env = env.copy()
  1402
+            del env['MOZ_SIGN_CMD']
  1403
+
1354 1404
         self.addStep(ShellCommand(
1355 1405
          name='make l10n check',
1356 1406
          command=['make', 'l10n-check'],
1357 1407
          workdir='build/%s' % self.objdir,
1358  
-         env=self.env,
  1408
+         env=env,
1359 1409
          haltOnFailure=False,
1360 1410
          flunkOnFailure=False,
1361 1411
          warnOnFailure=True,
@@ -1389,13 +1439,19 @@ def addCreateUpdateSteps(self):
1389 1439
         )
1390 1440
 
1391 1441
     def addTestPrettyNamesSteps(self):
  1442
+        # Disable signing for l10n check steps
  1443
+        env = self.env
  1444
+        if 'MOZ_SIGN_CMD' in env:
  1445
+            env = env.copy()
  1446
+            del env['MOZ_SIGN_CMD']
  1447
+
1392 1448
         if 'mac' in self.platform:
1393 1449
             # Need to run this target or else the packaging targets will
1394 1450
             # fail.
1395 1451
             self.addStep(ShellCommand(
1396 1452
              name='postflight_all',
1397 1453
              command=['make', '-f', 'client.mk', 'postflight_all'],
1398  
-             env=self.env,
  1454
+             env=env,
1399 1455
              haltOnFailure=False,
1400 1456
              flunkOnFailure=False,
1401 1457
              warnOnFailure=False,
@@ -1407,7 +1463,7 @@ def addTestPrettyNamesSteps(self):
1407 1463
             self.addStep(ShellCommand(
1408 1464
              name='make %s pretty' % t,
1409 1465
              command=['make', t, 'MOZ_PKG_PRETTYNAMES=1'],
1410  
-             env=self.env,
  1466
+             env=env,
1411 1467
              workdir='build/%s' % self.objdir,
1412 1468
              haltOnFailure=False,
1413 1469
              flunkOnFailure=False,
@@ -1418,7 +1474,7 @@ def addTestPrettyNamesSteps(self):
1418 1474
              command=['make', '-C',
1419 1475
                       '%s/tools/update-packaging' % self.mozillaObjdir,
1420 1476
                       'MOZ_PKG_PRETTYNAMES=1'],
1421  
-             env=self.env,
  1477
+             env=env,
1422 1478
              haltOnFailure=False,
1423 1479
              flunkOnFailure=False,
1424 1480
              warnOnFailure=True,
@@ -1428,7 +1484,7 @@ def addTestPrettyNamesSteps(self):
1428 1484
                  name='make l10n check pretty',
1429 1485
                 command=['make', 'l10n-check', 'MOZ_PKG_PRETTYNAMES=1'],
1430 1486
                 workdir='build/%s' % self.objdir,
1431  
-                env=self.env,
  1487
+                env=env,
1432 1488
                 haltOnFailure=False,
1433 1489
                 flunkOnFailure=False,
1434 1490
                 warnOnFailure=True,
@@ -2562,7 +2618,8 @@ def addUploadSnippetsSteps(self):
2562 2618
 class ReleaseBuildFactory(MercurialBuildFactory):
2563 2619
     def __init__(self, env, version, buildNumber, brandName=None,
2564 2620
             unittestMasters=None, unittestBranch=None, talosMasters=None,
2565  
-            usePrettyNames=True, enableUpdatePackaging=True, **kwargs):
  2621
+            usePrettyNames=True, enableUpdatePackaging=True,
  2622
+            signingFormats=None, **kwargs):
2566 2623
         self.version = version
2567 2624
         self.buildNumber = buildNumber
2568 2625
 
@@ -2795,7 +2852,7 @@ def __init__(self, project, appName, l10nRepoPath,
2795 2852
                  mozconfig=None, configRepoPath=None, configSubDir=None,
2796 2853
                  tree="notset", mozillaDir=None, l10nTag='default',
2797 2854
                  mergeLocales=True, mozconfigBranch="production", 
2798  
-                 testPrettyNames=False, **kwargs):
  2855
+                 testPrettyNames=False, signingServers=None, **kwargs):
2799 2856
         MozillaBuildFactory.__init__(self, **kwargs)
2800 2857
 
2801 2858
         self.env = env.copy()
@@ -2815,6 +2872,7 @@ def __init__(self, project, appName, l10nRepoPath,
2815 2872
         self.mozconfig = mozconfig
2816 2873
         self.mozconfigBranch = mozconfigBranch
2817 2874
         self.testPrettyNames = testPrettyNames
  2875
+        self.signingServers = signingServers
2818 2876
 
2819 2877
         # WinCE is the only platform that will do repackages with
2820 2878
         # a mozconfig for now. This will be fixed in bug 518359
@@ -2825,6 +2883,17 @@ def __init__(self, project, appName, l10nRepoPath,
2825 2883
             self.configRepo = self.getRepository(self.configRepoPath,
2826 2884
                                              kwargs['hgHost'])
2827 2885
 
  2886
+        if signingServers:
  2887
+            cmd = [
  2888
+                env.get('PYTHON26', 'python'), "%(toolsdir)s/release/signing/signtool.py",
  2889
+                "-t", "%(basedir)s/build/token",
  2890
+                "-n", "%(basedir)s/build/nonce",
  2891
+                "-c", "%(toolsdir)s/release/signing/host.cert",
  2892
+                ]
  2893
+            for ss, user, passwd in signingServers:
  2894
+                cmd.extend(['-H', ss])
  2895
+            self.env['MOZ_SIGN_CMD'] = WithProperties(" ".join(cmd))
  2896
+
2828 2897
         self.addStep(SetBuildProperty(
2829 2898
          property_name='tree',
2830 2899
          value=self.tree,
@@ -2911,6 +2980,8 @@ def __init__(self, project, appName, l10nRepoPath,
2911 2980
         self.tinderboxPrintRevisions()
2912 2981
         self.compareLocalesSetup()
2913 2982
         self.compareLocales()
  2983
+        if self.signingServers:
  2984
+            self.addGetTokenSteps()
2914 2985
         self.doRepack()
2915 2986
         self.doUpload()
2916 2987
         if self.testPrettyNames:
121  steps/signing.py
... ...
@@ -0,0 +1,121 @@
  1
+from urllib import urlencode
  2
+
  3
+from OpenSSL.SSL import Context, TLSv1_METHOD, VERIFY_PEER,\
  4
+     VERIFY_FAIL_IF_NO_PEER_CERT, OP_NO_SSLv2
  5
+from OpenSSL.crypto import load_certificate, FILETYPE_PEM
  6
+
  7
+from twisted.python.urlpath import URLPath
  8
+from twisted.internet.ssl import ContextFactory
  9
+from twisted.web.client import getPage
  10
+from twisted.python.failure import Failure
  11
+from twisted.internet import reactor
  12
+from buildbot.steps.transfer import StringDownload
  13
+
  14
+
  15
+class HTTPSVerifyingContextFactory(ContextFactory):
  16
+    isClient = True
  17
+
  18
+    def __init__(self, hostname, certfile):
  19
+        self.hostname = hostname
  20
+        data = open(certfile).read()
  21
+        self.cert = load_certificate(FILETYPE_PEM, data)
  22
+
  23
+    def getContext(self):
  24
+        ctx = Context(TLSv1_METHOD)
  25
+        store = ctx.get_cert_store()
  26
+        store.add_cert(self.cert)
  27
+        ctx.set_verify(VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT,
  28
+                       self.verifyHostname)
  29
+        ctx.set_options(OP_NO_SSLv2)
  30
+        return ctx
  31
+
  32
+    def verifyHostname(self, connection, x509, errno, depth, preverifyOK):
  33
+        if preverifyOK:
  34
+            if self.hostname == x509.get_subject().commonName:
  35
+                return False
  36
+        return preverifyOK
  37
+
  38
+
  39
+class SigningServerAuthenication(StringDownload):
  40
+    current_attempt = 0
  41
+    stdio_log = None
  42
+    uri = None
  43
+    username = None
  44
+    password = None
  45
+    d = None
  46
+    interrupted = False
  47
+
  48
+    def __init__(self, servers, server_cert, duration=6*3600, attempts=5,
  49
+                 sleeptime=60, **kwargs):
  50
+        kwargs['s'] = ''
  51
+        StringDownload.__init__(self, **kwargs)
  52
+        self.addFactoryArguments(servers=servers, server_cert=server_cert,
  53
+                                 duration=duration)
  54
+        self.servers = list(servers)
  55
+        self.server_cert = server_cert
  56
+        self.duration = duration
  57
+        self.attempts = attempts
  58
+        self.sleeptime = sleeptime
  59
+
  60
+    def generateHeaders(self, method, credentials):
  61
+        headers = {}
  62
+        if method == 'POST':
  63
+            headers['Content-Type'] = 'application/x-www-form-urlencoded'
  64
+        base64string = '%s:%s' % (credentials[0], credentials[1])
  65
+        base64string = base64string.encode("base64").strip()
  66
+        headers['Authorization'] = 'Basic %s' % base64string
  67
+        return headers
  68
+
  69
+    def start(self):
  70
+        if self.interrupted:
  71
+            self.failed(Failure(Exception('Interrupted')))
  72
+            return
  73
+
  74
+        self.current_attempt += 1
  75
+
  76
+        if self.current_attempt > self.attempts:
  77
+            if len(self.servers) < 1:
  78
+                self.failed(Failure(Exception(
  79
+                    'No more signing servers to try.')))
  80
+            else:
  81
+                self.current_attempt = 1
  82
+
  83
+        if self.current_attempt == 1:
  84
+            uri, self.username, self.password = self.servers.pop()
  85
+            self.uri = 'https://%s/token' % uri
  86
+
  87
+        slaveName = self.getSlaveName()
  88
+        slaveIP = self.buildslave.slave.broker.transport.getPeer().host
  89
+
  90
+        if not self.stdio_log:
  91
+            self.stdio_log = self.addLog('output')
  92
+            self.stdio_log.addHeader("Slave: %s\n" % slaveName)
  93
+            self.stdio_log.addHeader("IP: %s\n" % slaveIP)
  94
+            self.stdio_log.addHeader("Duration: %s\n" % self.duration)
  95
+        self.stdio_log.addStdout("URI: %s\n" % self.uri)
  96
+
  97
+        method = 'POST'
  98
+        postdata = {
  99
+            'slave_ip': slaveIP,
  100
+            'duration': self.duration,
  101
+        }
  102
+        headers = self.generateHeaders(
  103
+            method=method,
  104
+            credentials=(self.username, self.password))
  105
+        contextFactory = HTTPSVerifyingContextFactory(
  106
+            URLPath(self.uri).netloc, self.server_cert)
  107
+        d = getPage(self.uri, method=method, headers=headers,
  108
+                    postdata=urlencode(postdata), contextFactory=contextFactory)
  109
+        d.addCallbacks(
  110
+            self.downloadSignature,
  111
+            lambda e: reactor.callLater(self.sleeptime, self.start)
  112
+        )
  113
+
  114
+    def downloadSignature(self, res):
  115
+        self.s = res
  116
+        StringDownload.start(self)
  117
+
  118
+    def interrupt(self, reason='Interrupted'):
  119
+        if not self.interrupted:
  120
+            self.interrupted = True
  121
+            StringDownload.interrupt(self, 'Interrupted')

0 notes on commit 2fbdfdd

Please sign in to comment.
Something went wrong with that request. Please try again.