কিছু সাইটগুলিতে পাইথন এইচটিটিপিএস অনুরোধ (urllib2) প্রুসি ছাড়াই উবুন্টু 12.04 এ ব্যর্থ


23

পাইথনে আমার লেখা একটি ছোট অ্যাপ্লিকেশন রয়েছে এবং এটি গতকাল পর্যন্ত ... এটি হঠাৎ এইচটিটিপিএস সংযোগে আমাকে ত্রুটি দেওয়া শুরু করেছিল work আমার কোনও আপডেট আছে কিনা মনে নেই তবে পাইথন 2.7.3rc2 এবং পাইথন 3.2 উভয়ই একই রকম ব্যর্থ হচ্ছে।

আমি এটি গুগল করে জানতে পেরেছিলাম যে যখন লোকেরা প্রক্সিের পিছনে থাকে, তবে আমি নই (এবং আমার নেটওয়ার্কে এটি শেষবারের মতো কাজ করার সময় থেকে কোনও পরিবর্তন হয়নি)। আমার সিস্টার কম্পিউটারে চলমান উইন্ডোজ এবং পাইথন ২.7.২ এর কোনও সমস্যা নেই (একই নেটওয়ার্কে)।

>>> url = 'https://www.mediafire.com/api/user/get_session_token.php'
>>> response = urllib2.urlopen(url).read()
  File "/usr/lib/python2.7/urllib2.py", line 126, in urlopen
    return _opener.open(url, data, timeout)
  File "/usr/lib/python2.7/urllib2.py", line 400, in open
    response = self._open(req, data)
  File "/usr/lib/python2.7/urllib2.py", line 418, in _open
    '_open', req)
  File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 1215, in https_open
    return self.do_open(httplib.HTTPSConnection, req)
  File "/usr/lib/python2.7/urllib2.py", line 1177, in do_open
    raise URLError(err)
urllib2.URLError: <urlopen error [Errno 8] _ssl.c:504: EOF occurred in violation of protocol>

কোনো সমস্যা? কোন সাহায্য প্রশংসা করা হয়।

পিএস .: পুরানো অজগর সংস্করণগুলি আমার সিস্টেমে এবং ইউএসবি থেকে কোনও লাইভ সেশনে নয়, তবে উবুন্টু ১১.১০ লাইভ সেশনে কাজ করবেন।


1
আপনি যে সকল এসএসএল সাইটের সাথে যোগাযোগের চেষ্টা করছেন তার জন্য এটি ঘটেছে, বা কেবল একটির জন্য? যদি এটি প্রতিটি সাইটের জন্য না ঘটে তবে আপনি কি আমাদের বলতে পারবেন কোন সাইটটি সমস্যার সৃষ্টি করছে?
জেমস হেনস্ট্রিজ

ঠিক আছে, আমি নিজেই একজন অভিজ্ঞ প্রোগ্রামার নই, এবং আমি কোনও সাইটের এপিআই থেকে একটি পৃষ্ঠা পড়ার চেষ্টা করছি এবং এটিই কেবলমাত্র কল যেটির জন্য এসএসএল প্রয়োজন, তাই আমি জানি না যে আমি এটি ঠিক জায়গায় করছি কিনা । আমি এটিকে একটি সাধারণ urllib.urlopen (url)। Read () কলের মতো ব্যবহার করছি এবং এটি কাজ করছে। আপনি কি আমাকে অন্য সাইটের ঠিকানা বা একটি অজগর স্ক্রিপ্ট দিতে পারেন যা এই প্রশ্নের উত্তর দেবে?
পাবলো

ওহ, আমি উল্লেখ করতে ভুলে গেছি: সাইটটি মিডিয়াফায়ার। এটি এর get_session_ টোকেন কল যা সমস্যার সৃষ্টি করছে।
পাবলো

আমি সেই সাইটটির সাথে এটি পুনরুত্পাদন করতে সক্ষম হয়েছি। প্রশ্নে সাইটটি অন্তর্ভুক্ত করতে আমি আপনার প্রশ্ন আপডেট করেছি। আমি সন্দেহ করি যে এটি ওপেনএসএসএলে একটি সমস্যা, যেহেতু উইজেটও ব্যর্থ হয়।
জেমস হেনস্ট্রিজ

এটি লেখার সময় স্ট্রিম.টুইটার.কমের সাথে আমার ঘটেছিল।
MarkR

উত্তর:


15

এটি 12.04-তে পাওয়া ওপেনএসএসএল সংস্করণে টিএলএস 1.1 এবং 1.2 সমর্থন যোগ করার সাথে সম্পর্কিত বলে মনে হচ্ছে। সংযোগ ব্যর্থতা ওপেনএসএসএল কমান্ড লাইন সরঞ্জাম দিয়ে পুনরুত্পাদন করা যেতে পারে:

$ openssl s_client -connect www.mediafire.com:443
CONNECTED(00000003)
140491065808544:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 320 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---

যদি আমি -tls1কমান্ড লাইন আর্গুমেন্টের সাথে সংযোগটি টিএলএস 1.0 ব্যবহার করতে বাধ্য করি তবে সংযোগটি সফল হয় ।

আমি আপনাকে এই সমস্যা সম্পর্কে একটি বাগ রিপোর্ট ফাইল করার পরামর্শ দিচ্ছি:

https://bugs.launchpad.net/ubuntu/+filebug


2
ধন্যবাদ! আমি একটি বাগ রিপোর্ট করেছি। দয়া করে দেখুন, আপনি এটিতে কোনও প্রাসঙ্গিক তথ্য যুক্ত করতে পারেন কিনা: bugs.launchpad.net/ubuntu/+source/openssl/+bug/965371
পাবলো ২

1
এটি কীভাবে পাইথনের সমস্যার আশপাশে কাজ করতে সহায়তা করে?
সেরিন

2
@ সেরিন: এটি পাইথনের কোনও কিছুর চেয়ে ওপেনএসএসএল বাগ হিসাবে সমস্যাটি বিচ্ছিন্ন করেছে এবং তাকে বাগ ট্র্যাকার ব্যবহারের নির্দেশ দিয়েছে। সেই সমস্যাটি তখন থেকেই ঠিক হয়ে গেছে।
জেমস হেনস্ট্রিজ

12

আমার মতো অজগর নবীনদের জন্য, এখানে সবচেয়ে সহজ উপায়টি হল httplibকে ওভাররাইড করার উপায়। আপনার অজগর স্ক্রিপ্টের শীর্ষে, এই লাইনগুলি অন্তর্ভুক্ত করুন:


import httplib
from httplib import HTTPConnection, HTTPS_PORT
import ssl

class HTTPSConnection(HTTPConnection):
    "This class allows communication via SSL."
    default_port = HTTPS_PORT

    def __init__(self, host, port=None, key_file=None, cert_file=None,
            strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
            source_address=None):
        HTTPConnection.__init__(self, host, port, strict, timeout,
                source_address)
        self.key_file = key_file
        self.cert_file = cert_file

    def connect(self):
        "Connect to a host on a given (SSL) port."
        sock = socket.create_connection((self.host, self.port),
                self.timeout, self.source_address)
        if self._tunnel_host:
            self.sock = sock
            self._tunnel()
        # this is the only line we modified from the httplib.py file
        # we added the ssl_version variable
        self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version=ssl.PROTOCOL_TLSv1)

#now we override the one in httplib
httplib.HTTPSConnection = HTTPSConnection
# ssl_version corrections are done

এখান থেকে, আপনি urlib বা আপনি যা ব্যবহার করেন তা আপনার নিজের মতো করে ব্যবহার করতে পারেন।

দ্রষ্টব্য: এটি অজগর ২.7 এর জন্য। অজগর 3.x সমাধানের জন্য, আপনাকে http.client এ পাওয়া HTTPSConnication শ্রেণিকে ওভাররাইড করতে হবে। আমি পাঠকের জন্য একটি অনুশীলন হিসাবে এটি ছেড়ে। :-)


2
আমি এই সমাধানটি সত্যিই পছন্দ করি, এটি কোনও সিস্টেমের লাইব্রেরি বা অন্যান্য হ্যাকারি সংশোধন করা এড়িয়ে যায়।
MarkR

4
উবুন্টু 12.04-তে পাইথন ২.7.৪ ব্যবহার করতে ব্যর্থ হয়েছে: নামের ত্রুটি: নাম 'সকেট' সংজ্ঞায়িত হয়নি। --- আপনার পাশাপাশি "আমদানি সকেট" যুক্ত করতে হবে।
বেন ওয়ালথের

উবুন্টু 13.04 এ দুর্দান্ত কাজ করে। ধন্যবাদ!
ধর্মটেক

2
কেবল প্যাচ করার কোনও কারণ নেই httplib। লোকেরা অন্য এসএসএল সকেট ব্যবহার করতে পারে। sslনীচে আমার উত্তর মত পরিবর্তে একটি প্যাচ পারে ।
temoto

এটি আমাকে ত্রুটি দেয়BadStatusLine: ''
Cerin

8

আপনি আপনার এইচটিটিপিএস সংযোগ অবজেক্টটি সংশোধন করে httplib.py ফাইল পরিবর্তন করতে পারবেন:

import httplib, ssl, socket

conn = httplib.HTTPSConnection(URL.hostname)
sock = socket.create_connection((conn.host, conn.port), conn.timeout, conn.source_address)
conn.sock = ssl.wrap_socket(sock, conn.key_file, conn.cert_file, ssl_version=ssl.PROTOCOL_TLSv1)
conn.request('POST', URL.path + URL.query)

অনুরোধ পদ্ধতিটি কেবল নতুন সকেট তৈরি করে যদি সংযোগ.সোক সংজ্ঞায়িত না হয়। Ssl_version প্যারামিটার যুক্ত করে আপনার নিজের তৈরি করা অনুরোধের পদ্ধতিটি এটি ব্যবহার করে। তারপরে অন্য সব কিছুই যথারীতি কাজ করে।

আমার একই সমস্যা ছিল এবং এটি আমার পক্ষে কাজ করে।

শুভেচ্ছা সহ


7

সমস্যাটি রয়েছে ssl, HTTP এর সাথে এর কোনও সম্পর্ক নেই, তাই httplibযদি প্যাচ করতে পারেন তবে প্যাচিং কেন ssl। নীচের কোডটি পাইথন ২.6++ (অন্তর্নির্মিত ssl, চেষ্টা করে নি pyopenssl) সহ সমস্ত এসএসএল সকেটগুলি এইচটিটিপিএস সহ সীমাবদ্ধ করে তবে এটি সীমাবদ্ধ করা উচিত ।

import functools
import ssl

old_init = ssl.SSLSocket.__init__

@functools.wraps(old_init)
def ubuntu_openssl_bug_965371(self, *args, **kwargs):
  kwargs['ssl_version'] = ssl.PROTOCOL_TLSv1
  old_init(self, *args, **kwargs)

ssl.SSLSocket.__init__ = ubuntu_openssl_bug_965371

ভাল উত্তর. সমস্যাটি সমাধানের দুর্দান্ত, দুর্দান্ত উপায় way
chnrxn

3

সম্পাদনা করুন httplib.py (লিনাক্সে /usr/lib/pythonX.X/httplib.py)

এইচটিটিপিএস সংযোগের শ্রেণীর ঘোষণা দিন

  class HTTPSConnection(HTTPConnection):
....

শ্রেণীর কোড পরিবর্তন করুন লাইনের ভিতরে

self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file)

প্রতি

self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version=ssl.PROTOCOL_TLSv1)

তারপরে httplib HTTPS অনুরোধটি কাজ করা উচিত

import httplib
from urlparse import urlparse
url = XXX
URL = urlparse(url)
connection = httplib.HTTPSConnection(URL.hostname)
connection.request('POST', URL.path + URL.query)
response = connection.getresponse()

3
এটির মতো কোনও সিস্টেমের ফাইল সম্পাদনা করা সত্য নয়। পরিবর্তে, আপনার কোডে নতুন সংজ্ঞা দিয়ে যে কোনও সংজ্ঞা পরিবর্তন করতে হবে তা পুনরায় সংজ্ঞায়িত করুন ।
মনিকা পুনরায় ইনস্টল করুন - ζ--

2

SSLv2 ওয়েব সার্ভারে অক্ষম হওয়ার কারণে এই সমস্যাটি সম্ভবত রয়েছে তবে পাইথন ২.x ডিফল্টরূপে PROTOCOL_SSLv23 এর সাথে সংযোগ স্থাপনের চেষ্টা করে।

স্ট্যাক ওভারফ্লোতে অনুরূপ ইস্যুটির জন্য আমার উত্তরের লিঙ্কটি এখানে রয়েছে - /programming//a/24166498/41957

আপডেট: এটি উপরের @ টিমোটোর উত্তর হিসাবে কার্যত একই।


প্রকারের ত্রুটি: আনবাউন্ড পদ্ধতিতে __init __ () এসএসএলএসকেট উদাহরণের সাথে প্রথম যুক্তি হিসাবে কল করা উচিত (পরিবর্তে _সোক্টোবজেক্ট উদাহরণটি পেয়েছি)
sureshvv

হুম, আংশিক () শ্রেণিবদ্ধ পদ্ধতিতে কাজ করে না। শীঘ্রই আরও ভাল সমাধান পোস্ট করবে।
chnrxn

@ সুরেশভভ, আপনি যদি সমাধানটি পরীক্ষা করতে সহায়তা করতে পারেন তবে এটি প্রশংসা হবে।
chnrxn

@ টেমেটোর উত্তর কার্যকর হয়েছে।
sureshvv 12:58

1

একটি সাধারণ ফিক্স যা আমার পক্ষে কাজ করেছিল তা হ'ল এসএসএল এর ডিফল্ট প্রোটোকলটি ওভাররাইড করা হয়েছিল:

import ssl
ssl.PROTOCOL_SSLv23 = ssl.PROTOCOL_TLSv1

এটি হ্যাকিশ, তবে এটি আজকের প্রসঙ্গে ভালভাবে কাজ করে। যখনই পোডলের দুর্বলতা সন্ধান করা হয়েছে, তখন থেকেই টিএলএসভি 1 ইন্টারনেটে একমাত্র গ্রহণযোগ্য সংস্করণে পরিণত হয়েছে।
chnrxn
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.