We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Scrapy 1.1.0 RC3 - exception thrown with invalid ssl certificate
Hello,

I am crawling sometimes websites with an invalid ssl certificate. For example, Scrapy 1.1.0 RC3 fails to open when I do:

> scrapy shell https://www.directoriosanitario.com/directorio
> or
> scrapy shell https://saobinv.5go.cc/top/

and throws the following exception:

> twisted.web._newclient.ResponseNeverReceived: [<twisted.python.failure.Failure service_identity.exceptions.VerificationError: VerificationError(errors=[DNSMismatch(mismatched_id=DNS_ID(hostname=b'www.directoriosanitario.com'))])>]

I tried it with Scrapy 1.0.5 on python 2.7 and the spider opens but warns with: 

> AttributeError: 'NoneType' object has no attribute 'failVerification'

Is there a way to force the spider to open with Scrapy 1.1.0 RC3?


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `scrapy/core/downloader/tls.py`
Content:
```
1 from OpenSSL import SSL
2 
3 
4 METHOD_SSLv3 = 'SSLv3'
5 METHOD_TLS = 'TLS'
6 METHOD_TLSv10 = 'TLSv1.0'
7 METHOD_TLSv11 = 'TLSv1.1'
8 METHOD_TLSv12 = 'TLSv1.2'
9 
10 openssl_methods = {
11     METHOD_TLS:    SSL.SSLv23_METHOD,                   # protocol negotiation (recommended)
12     METHOD_SSLv3:  SSL.SSLv3_METHOD,                    # SSL 3 (NOT recommended)
13     METHOD_TLSv10: SSL.TLSv1_METHOD,                    # TLS 1.0 only
14     METHOD_TLSv11: getattr(SSL, 'TLSv1_1_METHOD', 5),   # TLS 1.1 only
15     METHOD_TLSv12: getattr(SSL, 'TLSv1_2_METHOD', 6),   # TLS 1.2 only
16 }
17
```

Path: `scrapy/core/downloader/contextfactory.py`
Content:
```
1 from OpenSSL import SSL
2 from twisted.internet.ssl import ClientContextFactory
3 
4 try:
5 
6     from zope.interface.declarations import implementer
7 
8     # the following should be available from Twisted 14.0.0
9     from twisted.internet.ssl import optionsForClientTLS, CertificateOptions, platformTrust
10     from twisted.internet._sslverify import ClientTLSOptions
11     from twisted.web.client import BrowserLikePolicyForHTTPS
12     from twisted.web.iweb import IPolicyForHTTPS
13 
14     @implementer(IPolicyForHTTPS)
15     class ScrapyClientContextFactory(BrowserLikePolicyForHTTPS):
16         """
17         Non-peer-certificate verifying HTTPS context factory
18 
19         Default OpenSSL method is TLS_METHOD (also called SSLv23_METHOD)
20         which allows TLS protocol negotiation
21 
22         'A TLS/SSL connection established with [this method] may
23          understand the SSLv3, TLSv1, TLSv1.1 and TLSv1.2 protocols.'
24         """
25 
26         def __init__(self, method=SSL.SSLv23_METHOD, *args, **kwargs):
27             super(ScrapyClientContextFactory, self).__init__(*args, **kwargs)
28             self._ssl_method = method
29 
30         def getCertificateOptions(self):
31             # setting verify=True will require you to provide CAs
32             # to verify against; in other words: it's not that simple
33 
34             # backward-compatible SSL/TLS method:
35             #
36             # * this will respect `method` attribute in often recommended
37             #   `ScrapyClientContextFactory` subclass
38             #   (https://github.com/scrapy/scrapy/issues/1429#issuecomment-131782133)
39             #
40             # * getattr() for `_ssl_method` attribute for context factories
41             #   not calling super(..., self).__init__
42             return CertificateOptions(verify=False,
43                         method=getattr(self, 'method',
44                                        getattr(self, '_ssl_method', None)))
45 
46         # kept for old-style HTTP/1.0 downloader context twisted calls,
47         # e.g. connectSSL()
48         def getContext(self, hostname=None, port=None):
49             return self.getCertificateOptions().getContext()
50 
51         def creatorForNetloc(self, hostname, port):
52             return ClientTLSOptions(hostname.decode("ascii"), self.getContext())
53 
54 
55     @implementer(IPolicyForHTTPS)
56     class BrowserLikeContextFactory(ScrapyClientContextFactory):
57         """
58         Twisted-recommended context factory for web clients.
59 
60         Quoting http://twistedmatrix.com/documents/current/api/twisted.web.client.Agent.html:
61         "The default is to use a BrowserLikePolicyForHTTPS,
62         so unless you have special requirements you can leave this as-is."
63 
64         creatorForNetloc() is the same as BrowserLikePolicyForHTTPS
65         except this context factory allows setting the TLS/SSL method to use.
66 
67         Default OpenSSL method is TLS_METHOD (also called SSLv23_METHOD)
68         which allows TLS protocol negotiation.
69         """
70         def creatorForNetloc(self, hostname, port):
71 
72             # trustRoot set to platformTrust() will use the platform's root CAs.
73             #
74             # This means that a website like https://www.cacert.org will be rejected
75             # by default, since CAcert.org CA certificate is seldom shipped.
76             return optionsForClientTLS(hostname.decode("ascii"),
77                                        trustRoot=platformTrust(),
78                                        extraCertificateOptions={
79                                             'method': self._ssl_method,
80                                        })
81 
82 except ImportError:
83 
84     class ScrapyClientContextFactory(ClientContextFactory):
85         "A SSL context factory which is more permissive against SSL bugs."
86         # see https://github.com/scrapy/scrapy/issues/82
87         # and https://github.com/scrapy/scrapy/issues/26
88         # and https://github.com/scrapy/scrapy/issues/981
89 
90         def __init__(self, method=SSL.SSLv23_METHOD):
91             self.method = method
92 
93         def getContext(self, hostname=None, port=None):
94             ctx = ClientContextFactory.getContext(self)
95             # Enable all workarounds to SSL bugs as documented by
96             # http://www.openssl.org/docs/ssl/SSL_CTX_set_options.html
97             ctx.set_options(SSL.OP_ALL)
98             return ctx
99
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/scrapy/core/downloader/contextfactory.py b/scrapy/core/downloader/contextfactory.py
--- a/scrapy/core/downloader/contextfactory.py
+++ b/scrapy/core/downloader/contextfactory.py
@@ -6,11 +6,16 @@
     from zope.interface.declarations import implementer
 
     # the following should be available from Twisted 14.0.0
-    from twisted.internet.ssl import optionsForClientTLS, CertificateOptions, platformTrust
-    from twisted.internet._sslverify import ClientTLSOptions
+    from twisted.internet.ssl import (optionsForClientTLS,
+                                      CertificateOptions,
+                                      platformTrust)
+
     from twisted.web.client import BrowserLikePolicyForHTTPS
     from twisted.web.iweb import IPolicyForHTTPS
 
+    from scrapy.core.downloader.tls import ScrapyClientTLSOptions
+
+
     @implementer(IPolicyForHTTPS)
     class ScrapyClientContextFactory(BrowserLikePolicyForHTTPS):
         """
@@ -49,7 +54,7 @@
             return self.getCertificateOptions().getContext()
 
         def creatorForNetloc(self, hostname, port):
-            return ClientTLSOptions(hostname.decode("ascii"), self.getContext())
+            return ScrapyClientTLSOptions(hostname.decode("ascii"), self.getContext())
 
 
     @implementer(IPolicyForHTTPS)
diff --git a/scrapy/core/downloader/tls.py b/scrapy/core/downloader/tls.py
--- a/scrapy/core/downloader/tls.py
+++ b/scrapy/core/downloader/tls.py
@@ -1,6 +1,9 @@
+import logging
 from OpenSSL import SSL
 
 
+logger = logging.getLogger(__name__)
+
 METHOD_SSLv3 = 'SSLv3'
 METHOD_TLS = 'TLS'
 METHOD_TLSv10 = 'TLSv1.0'
@@ -14,3 +17,36 @@
     METHOD_TLSv11: getattr(SSL, 'TLSv1_1_METHOD', 5),   # TLS 1.1 only
     METHOD_TLSv12: getattr(SSL, 'TLSv1_2_METHOD', 6),   # TLS 1.2 only
 }
+
+# ClientTLSOptions requires a recent-enough version of Twisted
+try:
+
+    # taken from twisted/twisted/internet/_sslverify.py
+    try:
+        from OpenSSL.SSL import SSL_CB_HANDSHAKE_DONE, SSL_CB_HANDSHAKE_START
+    except ImportError:
+        SSL_CB_HANDSHAKE_START = 0x10
+        SSL_CB_HANDSHAKE_DONE = 0x20
+
+    from twisted.internet._sslverify import (ClientTLSOptions,
+                                             _maybeSetHostNameIndication,
+                                             verifyHostname,
+                                             VerificationError)
+
+    class ScrapyClientTLSOptions(ClientTLSOptions):
+        # same as Twisted's ClientTLSOptions,
+        # except that VerificationError is caught
+        # and doesn't close the connection
+        def _identityVerifyingInfoCallback(self, connection, where, ret):
+            if where & SSL_CB_HANDSHAKE_START:
+                _maybeSetHostNameIndication(connection, self._hostnameBytes)
+            elif where & SSL_CB_HANDSHAKE_DONE:
+                try:
+                    verifyHostname(connection, self._hostnameASCII)
+                except VerificationError as e:
+                    logger.warning(e)
+
+except ImportError:
+    # ImportError should not matter for older Twisted versions
+    # as the above is not used in the fallback ScrapyClientContextFactory
+    pass

{"golden_diff": "diff --git a/scrapy/core/downloader/contextfactory.py b/scrapy/core/downloader/contextfactory.py\n--- a/scrapy/core/downloader/contextfactory.py\n+++ b/scrapy/core/downloader/contextfactory.py\n@@ -6,11 +6,16 @@\n     from zope.interface.declarations import implementer\n \n     # the following should be available from Twisted 14.0.0\n-    from twisted.internet.ssl import optionsForClientTLS, CertificateOptions, platformTrust\n-    from twisted.internet._sslverify import ClientTLSOptions\n+    from twisted.internet.ssl import (optionsForClientTLS,\n+                                      CertificateOptions,\n+                                      platformTrust)\n+\n     from twisted.web.client import BrowserLikePolicyForHTTPS\n     from twisted.web.iweb import IPolicyForHTTPS\n \n+    from scrapy.core.downloader.tls import ScrapyClientTLSOptions\n+\n+\n     @implementer(IPolicyForHTTPS)\n     class ScrapyClientContextFactory(BrowserLikePolicyForHTTPS):\n         \"\"\"\n@@ -49,7 +54,7 @@\n             return self.getCertificateOptions().getContext()\n \n         def creatorForNetloc(self, hostname, port):\n-            return ClientTLSOptions(hostname.decode(\"ascii\"), self.getContext())\n+            return ScrapyClientTLSOptions(hostname.decode(\"ascii\"), self.getContext())\n \n \n     @implementer(IPolicyForHTTPS)\ndiff --git a/scrapy/core/downloader/tls.py b/scrapy/core/downloader/tls.py\n--- a/scrapy/core/downloader/tls.py\n+++ b/scrapy/core/downloader/tls.py\n@@ -1,6 +1,9 @@\n+import logging\n from OpenSSL import SSL\n \n \n+logger = logging.getLogger(__name__)\n+\n METHOD_SSLv3 = 'SSLv3'\n METHOD_TLS = 'TLS'\n METHOD_TLSv10 = 'TLSv1.0'\n@@ -14,3 +17,36 @@\n     METHOD_TLSv11: getattr(SSL, 'TLSv1_1_METHOD', 5),   # TLS 1.1 only\n     METHOD_TLSv12: getattr(SSL, 'TLSv1_2_METHOD', 6),   # TLS 1.2 only\n }\n+\n+# ClientTLSOptions requires a recent-enough version of Twisted\n+try:\n+\n+    # taken from twisted/twisted/internet/_sslverify.py\n+    try:\n+        from OpenSSL.SSL import SSL_CB_HANDSHAKE_DONE, SSL_CB_HANDSHAKE_START\n+    except ImportError:\n+        SSL_CB_HANDSHAKE_START = 0x10\n+        SSL_CB_HANDSHAKE_DONE = 0x20\n+\n+    from twisted.internet._sslverify import (ClientTLSOptions,\n+                                             _maybeSetHostNameIndication,\n+                                             verifyHostname,\n+                                             VerificationError)\n+\n+    class ScrapyClientTLSOptions(ClientTLSOptions):\n+        # same as Twisted's ClientTLSOptions,\n+        # except that VerificationError is caught\n+        # and doesn't close the connection\n+        def _identityVerifyingInfoCallback(self, connection, where, ret):\n+            if where & SSL_CB_HANDSHAKE_START:\n+                _maybeSetHostNameIndication(connection, self._hostnameBytes)\n+            elif where & SSL_CB_HANDSHAKE_DONE:\n+                try:\n+                    verifyHostname(connection, self._hostnameASCII)\n+                except VerificationError as e:\n+                    logger.warning(e)\n+\n+except ImportError:\n+    # ImportError should not matter for older Twisted versions\n+    # as the above is not used in the fallback ScrapyClientContextFactory\n+    pass\n", "issue": "Scrapy 1.1.0 RC3 - exception thrown with invalid ssl certificate\nHello,\n\nI am crawling sometimes websites with an invalid ssl certificate. For example, Scrapy 1.1.0 RC3 fails to open when I do:\n\n> scrapy shell https://www.directoriosanitario.com/directorio\n> or\n> scrapy shell https://saobinv.5go.cc/top/\n\nand throws the following exception:\n\n> twisted.web._newclient.ResponseNeverReceived: [<twisted.python.failure.Failure service_identity.exceptions.VerificationError: VerificationError(errors=[DNSMismatch(mismatched_id=DNS_ID(hostname=b'www.directoriosanitario.com'))])>]\n\nI tried it with Scrapy 1.0.5 on python 2.7 and the spider opens but warns with: \n\n> AttributeError: 'NoneType' object has no attribute 'failVerification'\n\nIs there a way to force the spider to open with Scrapy 1.1.0 RC3?\n\n", "before_files": [{"content": "from OpenSSL import SSL\n\n\nMETHOD_SSLv3 = 'SSLv3'\nMETHOD_TLS = 'TLS'\nMETHOD_TLSv10 = 'TLSv1.0'\nMETHOD_TLSv11 = 'TLSv1.1'\nMETHOD_TLSv12 = 'TLSv1.2'\n\nopenssl_methods = {\n    METHOD_TLS:    SSL.SSLv23_METHOD,                   # protocol negotiation (recommended)\n    METHOD_SSLv3:  SSL.SSLv3_METHOD,                    # SSL 3 (NOT recommended)\n    METHOD_TLSv10: SSL.TLSv1_METHOD,                    # TLS 1.0 only\n    METHOD_TLSv11: getattr(SSL, 'TLSv1_1_METHOD', 5),   # TLS 1.1 only\n    METHOD_TLSv12: getattr(SSL, 'TLSv1_2_METHOD', 6),   # TLS 1.2 only\n}\n", "path": "scrapy/core/downloader/tls.py"}, {"content": "from OpenSSL import SSL\nfrom twisted.internet.ssl import ClientContextFactory\n\ntry:\n\n    from zope.interface.declarations import implementer\n\n    # the following should be available from Twisted 14.0.0\n    from twisted.internet.ssl import optionsForClientTLS, CertificateOptions, platformTrust\n    from twisted.internet._sslverify import ClientTLSOptions\n    from twisted.web.client import BrowserLikePolicyForHTTPS\n    from twisted.web.iweb import IPolicyForHTTPS\n\n    @implementer(IPolicyForHTTPS)\n    class ScrapyClientContextFactory(BrowserLikePolicyForHTTPS):\n        \"\"\"\n        Non-peer-certificate verifying HTTPS context factory\n\n        Default OpenSSL method is TLS_METHOD (also called SSLv23_METHOD)\n        which allows TLS protocol negotiation\n\n        'A TLS/SSL connection established with [this method] may\n         understand the SSLv3, TLSv1, TLSv1.1 and TLSv1.2 protocols.'\n        \"\"\"\n\n        def __init__(self, method=SSL.SSLv23_METHOD, *args, **kwargs):\n            super(ScrapyClientContextFactory, self).__init__(*args, **kwargs)\n            self._ssl_method = method\n\n        def getCertificateOptions(self):\n            # setting verify=True will require you to provide CAs\n            # to verify against; in other words: it's not that simple\n\n            # backward-compatible SSL/TLS method:\n            #\n            # * this will respect `method` attribute in often recommended\n            #   `ScrapyClientContextFactory` subclass\n            #   (https://github.com/scrapy/scrapy/issues/1429#issuecomment-131782133)\n            #\n            # * getattr() for `_ssl_method` attribute for context factories\n            #   not calling super(..., self).__init__\n            return CertificateOptions(verify=False,\n                        method=getattr(self, 'method',\n                                       getattr(self, '_ssl_method', None)))\n\n        # kept for old-style HTTP/1.0 downloader context twisted calls,\n        # e.g. connectSSL()\n        def getContext(self, hostname=None, port=None):\n            return self.getCertificateOptions().getContext()\n\n        def creatorForNetloc(self, hostname, port):\n            return ClientTLSOptions(hostname.decode(\"ascii\"), self.getContext())\n\n\n    @implementer(IPolicyForHTTPS)\n    class BrowserLikeContextFactory(ScrapyClientContextFactory):\n        \"\"\"\n        Twisted-recommended context factory for web clients.\n\n        Quoting http://twistedmatrix.com/documents/current/api/twisted.web.client.Agent.html:\n        \"The default is to use a BrowserLikePolicyForHTTPS,\n        so unless you have special requirements you can leave this as-is.\"\n\n        creatorForNetloc() is the same as BrowserLikePolicyForHTTPS\n        except this context factory allows setting the TLS/SSL method to use.\n\n        Default OpenSSL method is TLS_METHOD (also called SSLv23_METHOD)\n        which allows TLS protocol negotiation.\n        \"\"\"\n        def creatorForNetloc(self, hostname, port):\n\n            # trustRoot set to platformTrust() will use the platform's root CAs.\n            #\n            # This means that a website like https://www.cacert.org will be rejected\n            # by default, since CAcert.org CA certificate is seldom shipped.\n            return optionsForClientTLS(hostname.decode(\"ascii\"),\n                                       trustRoot=platformTrust(),\n                                       extraCertificateOptions={\n                                            'method': self._ssl_method,\n                                       })\n\nexcept ImportError:\n\n    class ScrapyClientContextFactory(ClientContextFactory):\n        \"A SSL context factory which is more permissive against SSL bugs.\"\n        # see https://github.com/scrapy/scrapy/issues/82\n        # and https://github.com/scrapy/scrapy/issues/26\n        # and https://github.com/scrapy/scrapy/issues/981\n\n        def __init__(self, method=SSL.SSLv23_METHOD):\n            self.method = method\n\n        def getContext(self, hostname=None, port=None):\n            ctx = ClientContextFactory.getContext(self)\n            # Enable all workarounds to SSL bugs as documented by\n            # http://www.openssl.org/docs/ssl/SSL_CTX_set_options.html\n            ctx.set_options(SSL.OP_ALL)\n            return ctx\n", "path": "scrapy/core/downloader/contextfactory.py"}], "after_files": [{"content": "import logging\nfrom OpenSSL import SSL\n\n\nlogger = logging.getLogger(__name__)\n\nMETHOD_SSLv3 = 'SSLv3'\nMETHOD_TLS = 'TLS'\nMETHOD_TLSv10 = 'TLSv1.0'\nMETHOD_TLSv11 = 'TLSv1.1'\nMETHOD_TLSv12 = 'TLSv1.2'\n\nopenssl_methods = {\n    METHOD_TLS:    SSL.SSLv23_METHOD,                   # protocol negotiation (recommended)\n    METHOD_SSLv3:  SSL.SSLv3_METHOD,                    # SSL 3 (NOT recommended)\n    METHOD_TLSv10: SSL.TLSv1_METHOD,                    # TLS 1.0 only\n    METHOD_TLSv11: getattr(SSL, 'TLSv1_1_METHOD', 5),   # TLS 1.1 only\n    METHOD_TLSv12: getattr(SSL, 'TLSv1_2_METHOD', 6),   # TLS 1.2 only\n}\n\n# ClientTLSOptions requires a recent-enough version of Twisted\ntry:\n\n    # taken from twisted/twisted/internet/_sslverify.py\n    try:\n        from OpenSSL.SSL import SSL_CB_HANDSHAKE_DONE, SSL_CB_HANDSHAKE_START\n    except ImportError:\n        SSL_CB_HANDSHAKE_START = 0x10\n        SSL_CB_HANDSHAKE_DONE = 0x20\n\n    from twisted.internet._sslverify import (ClientTLSOptions,\n                                             _maybeSetHostNameIndication,\n                                             verifyHostname,\n                                             VerificationError)\n\n    class ScrapyClientTLSOptions(ClientTLSOptions):\n        # same as Twisted's ClientTLSOptions,\n        # except that VerificationError is caught\n        # and doesn't close the connection\n        def _identityVerifyingInfoCallback(self, connection, where, ret):\n            if where & SSL_CB_HANDSHAKE_START:\n                _maybeSetHostNameIndication(connection, self._hostnameBytes)\n            elif where & SSL_CB_HANDSHAKE_DONE:\n                try:\n                    verifyHostname(connection, self._hostnameASCII)\n                except VerificationError as e:\n                    logger.warning(e)\n\nexcept ImportError:\n    # ImportError should not matter for older Twisted versions\n    # as the above is not used in the fallback ScrapyClientContextFactory\n    pass\n", "path": "scrapy/core/downloader/tls.py"}, {"content": "from OpenSSL import SSL\nfrom twisted.internet.ssl import ClientContextFactory\n\ntry:\n\n    from zope.interface.declarations import implementer\n\n    # the following should be available from Twisted 14.0.0\n    from twisted.internet.ssl import (optionsForClientTLS,\n                                      CertificateOptions,\n                                      platformTrust)\n\n    from twisted.web.client import BrowserLikePolicyForHTTPS\n    from twisted.web.iweb import IPolicyForHTTPS\n\n    from scrapy.core.downloader.tls import ScrapyClientTLSOptions\n\n\n    @implementer(IPolicyForHTTPS)\n    class ScrapyClientContextFactory(BrowserLikePolicyForHTTPS):\n        \"\"\"\n        Non-peer-certificate verifying HTTPS context factory\n\n        Default OpenSSL method is TLS_METHOD (also called SSLv23_METHOD)\n        which allows TLS protocol negotiation\n\n        'A TLS/SSL connection established with [this method] may\n         understand the SSLv3, TLSv1, TLSv1.1 and TLSv1.2 protocols.'\n        \"\"\"\n\n        def __init__(self, method=SSL.SSLv23_METHOD, *args, **kwargs):\n            super(ScrapyClientContextFactory, self).__init__(*args, **kwargs)\n            self._ssl_method = method\n\n        def getCertificateOptions(self):\n            # setting verify=True will require you to provide CAs\n            # to verify against; in other words: it's not that simple\n\n            # backward-compatible SSL/TLS method:\n            #\n            # * this will respect `method` attribute in often recommended\n            #   `ScrapyClientContextFactory` subclass\n            #   (https://github.com/scrapy/scrapy/issues/1429#issuecomment-131782133)\n            #\n            # * getattr() for `_ssl_method` attribute for context factories\n            #   not calling super(..., self).__init__\n            return CertificateOptions(verify=False,\n                        method=getattr(self, 'method',\n                                       getattr(self, '_ssl_method', None)))\n\n        # kept for old-style HTTP/1.0 downloader context twisted calls,\n        # e.g. connectSSL()\n        def getContext(self, hostname=None, port=None):\n            return self.getCertificateOptions().getContext()\n\n        def creatorForNetloc(self, hostname, port):\n            return ScrapyClientTLSOptions(hostname.decode(\"ascii\"), self.getContext())\n\n\n    @implementer(IPolicyForHTTPS)\n    class BrowserLikeContextFactory(ScrapyClientContextFactory):\n        \"\"\"\n        Twisted-recommended context factory for web clients.\n\n        Quoting http://twistedmatrix.com/documents/current/api/twisted.web.client.Agent.html:\n        \"The default is to use a BrowserLikePolicyForHTTPS,\n        so unless you have special requirements you can leave this as-is.\"\n\n        creatorForNetloc() is the same as BrowserLikePolicyForHTTPS\n        except this context factory allows setting the TLS/SSL method to use.\n\n        Default OpenSSL method is TLS_METHOD (also called SSLv23_METHOD)\n        which allows TLS protocol negotiation.\n        \"\"\"\n        def creatorForNetloc(self, hostname, port):\n\n            # trustRoot set to platformTrust() will use the platform's root CAs.\n            #\n            # This means that a website like https://www.cacert.org will be rejected\n            # by default, since CAcert.org CA certificate is seldom shipped.\n            return optionsForClientTLS(hostname.decode(\"ascii\"),\n                                       trustRoot=platformTrust(),\n                                       extraCertificateOptions={\n                                            'method': self._ssl_method,\n                                       })\n\nexcept ImportError:\n\n    class ScrapyClientContextFactory(ClientContextFactory):\n        \"A SSL context factory which is more permissive against SSL bugs.\"\n        # see https://github.com/scrapy/scrapy/issues/82\n        # and https://github.com/scrapy/scrapy/issues/26\n        # and https://github.com/scrapy/scrapy/issues/981\n\n        def __init__(self, method=SSL.SSLv23_METHOD):\n            self.method = method\n\n        def getContext(self, hostname=None, port=None):\n            ctx = ClientContextFactory.getContext(self)\n            # Enable all workarounds to SSL bugs as documented by\n            # http://www.openssl.org/docs/ssl/SSL_CTX_set_options.html\n            ctx.set_options(SSL.OP_ALL)\n            return ctx\n", "path": "scrapy/core/downloader/contextfactory.py"}]}