أتلقى الخطأ حاليًا ، socket.error: [Errno 54] Connection reset by peer
عندما أستخدم requests.get(url, params=kwargs)
و params
يحتوي على نصوص كبيرة. إذا قمت باقتطاع النصين الكبيرين إلى أقل من 2900 حرف لكل منهما ، فهذا يعمل. إذا قمت بتشغيل نفس طلب الحصول من سطر الأوامر باستخدام curl
فإنه يعمل. أنا أستخدم إصدار الطلبات 0.6.1 الذي قمت بتثبيته باستخدام ، pip install python-requests
.
لست متأكدًا من كيفية إخبارك بتكرار المشكلة لأنني أستخدم مكتبة
للاختبار من سطر الأوامر باستخدام curl ، قمت بإنشاء ملفين يحتوي كل منهما على نص عادي ونص html تم ترميزه باستخدام urlencoder . ثم قمت بتشغيل الأمر التالي.
export IDENTITY='<my identity number>'
export API_KEY='<my smtp password>'
export API_USER='<my smtp username>'
export NAME='<My Urlencoded Newsletter Name>'
export SUBJECT='<My Urlencoded Newsletter Subject>'
TEXT=`cat urlencoded.txt`; HTML=`cat urlencoded.html`; curl -d "api_user=$API_USER&api_key=$API_KEY&identity=$IDENTITY&name=$NAME&subject=$SUBJECT&text=$TEXT&html=$HTML" https://sendgrid.com/api/newsletter/newsletter/add.json
حسنًا ، ممتع. إذا كان هذا هو الخطأ الذي يتم طرحه ، فليس لدي سبب وجيه للاعتقاد بأن الخادم _ليس _ في الواقع يعيد تعيين الاتصال.
هل يتوفر لديك وكيل HTTP مثل Charles؟ قد يساعد ذلك في إلقاء بعض الضوء على ما يحدث بالفعل.
عذرا ، لقد نسيت تقديم التتبع الكامل. هذا هو traceback الذي أحصل عليه عندما أحصل على الخطأ. أيضًا ، لا أفهم كيفية استخدام وكيل HTTP ولماذا قد يحدث فرقًا عندما يعمل من سطر الأوامر مع curl.
Traceback (most recent call last):
File "/Users/oconnor/.virtualenvs/emails/bin/django-admin.py", line 5, in <module>
management.execute_from_command_line()
File "/Users/oconnor/.virtualenvs/emails/lib/python2.7/site-packages/django/core/management/__init__.py", line 429, in execute_from_command_line
utility.execute()
File "/Users/oconnor/.virtualenvs/emails/lib/python2.7/site-packages/django/core/management/__init__.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Users/oconnor/.virtualenvs/emails/lib/python2.7/site-packages/django/core/management/base.py", line 191, in run_from_argv
self.execute(*args, **options.__dict__)
File "/Users/oconnor/.virtualenvs/emails/lib/python2.7/site-packages/django/core/management/base.py", line 220, in execute
output = self.handle(*args, **options)
File "/Users/oconnor/Sites/wenworld/emails/emails/management/commands/ww_daily_headlines_send.py", line 114, in handle
self.add_newsletter_to_sendgrid(sendgrid_newsletter_name, NEWSLETTER_SLUG)
File "/Users/oconnor/Sites/wenworld/emails/emails/management/commands/ww_daily_headlines_send.py", line 94, in add_newsletter_to_sendgrid
html=email.html
File "/Users/oconnor/.virtualenvs/emails/src/sendgrid/src/sendgrid/__init__.py", line 67, in newsletter_add
subject=subject, text=text, html=html)
File "/Users/oconnor/.virtualenvs/emails/src/sendgrid/src/sendgrid/__init__.py", line 157, in get
return self.call(method, **kwargs)
File "/Users/oconnor/.virtualenvs/emails/src/sendgrid/src/sendgrid/__init__.py", line 56, in call
result_json = json.loads(response.content)
File "/Users/oconnor/.virtualenvs/emails/lib/python2.7/site-packages/requests/models.py", line 429, in __getattr__
self._content = self.read()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 351, in read
data = self._sock.recv(rbufsize)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 553, in read
s = self.fp.read(amt)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 1276, in read
return s + self._file.read(amt - len(s))
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 380, in read
data = self._sock.recv(left)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 219, in recv
return self.read(buflen)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 138, in read
return self._sslobj.read(len)
socket.error: [Errno 54] Connection reset by peer
الرد الذي أحصل عليه من جيثب هو ...
<html>
<head><title>414 Request-URI Too Large</title></head>
<body bgcolor="white">
<center><h1>414 Request-URI Too Large</h1></center>
<hr><center>nginx/0.7.65</center>
</body>
</html>
وهو أمر غريب لأنه ، كما ذكرت من قبل ، يعمل مع curl
.
إذا كنت تأخذ الوقت الكافي لإلقاء نظرة على الطلبين من خلال Charles (أو ما شابه) ، فأنا متأكد من أنك سترى المشكلة بسرعة كبيرة.
كما يوضح الخطأ ، فإن Request-URI كبير جدًا بحيث يتعذر على الخادم معالجته ، لذلك يقوم بإلغاء الاتصال.
باستخدام الطلبات ، تقوم بإرسال جميع البيانات كسلسلة استعلام ضخمة في عنوان URI للطلب ، والمعروفة باسم معلمة GET. عندما تستخدم curl ، فأنت تقوم بتحميل البيانات المشفرة بالنموذج إلى نص الطلب ، والمعروفة باسم بيانات POST.
لقد حاولت استخدام كل من requests.get(url, params=kwargs)
و requests.post(url, params=kwargs)
وكلاهما يُرجع الخطأ نفسه. لسبب ما ، لا يقوم تشارلز بالتقاط الطلبات من curl وهو فقط يلتقط الطلبات من المتصفح الخاص بي ونص سطر أوامر python الذي يستخدم طلبات python.
لا داعى للقلق.
params
لسلاسل الاستعلام ، data
لبيانات POST.
عمل حلو! التبديل من requests.get(url, params=kwargs)
إلى requests.post(url, data=kwargs)
إصلاحه! آسف لإزعاجك بهذا وشكرا للمساعدة!
لا تقلق إطلاقا :)
من الغريب أن أحصل على نفس الخطأ مع بيانات متشابهة ، والفرق الوحيد هو أنه في حالتي ليس لدي قائمة كبيرة أو حجم من المعلمات. نفس الطلب المقدم عبر CURL يعمل بشكل جيد ولكن عبر الطلبات يعطيني هذا الخطأ.
request.exceptions.ConnectionError: HTTPSConnectionPool (host = 'sbarnea.com'، port = 443): تم تجاوز الحد الأقصى لإعادة المحاولات بعنوان url: / jira / rest / api / 2 / group؟ groupname = jira -ministrators & expand = users (تسببها
والأكثر إثارة للاهتمام ، يبدو أن الطلب لا يصل حتى إلى خادم الويب.
أي فكرة عما يمكن أن يكون السبب؟
ssbarnea هذه المشكلة
والأفضل من ذلك ، لا تفتح مشكلة ، وانتقل إلى StackOverflow ، فأنت تطرح سؤالاً وليس لديك سبب للاعتقاد بأنها مشكلة تتعلق بكيفية تصرف الطلبات. تجزئة التفاصيل على StackOverflow ومن ثم يمكننا تقديم تقرير خطأ (إذا لزم الأمر).
إنه سلوك غريب للغاية ولدي أسباب للاعتقاد بأنه ليس خطأً في الطلبات ، ولهذا السبب فتحت خطأً جديدًا. ما زلت أحقق في سبب ذلك ، يحدث ذلك فقط من جهازي ، ولكن الجزء الأكثر إثارة للاهتمام هو أن CURL يعمل (والمتصفحات أيضًا). شكرا لك.
آسف للاحتفاظ بهذا هنا ولكني وجدت سبب هذا:
# resolver 127.0.0.1;
# ssl_protocols TLSv1.2 TLSv1.1 ; # TLSv1
# ssl_stapling on;
# ssl_stapling_verify on;
# ssl_session_cache builtin:1000;
# ssl_session_timeout 30m;
# ssl_ciphers HIGH:!RC4:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
من خلال تعطيل هذه التوليفات على خادم nginx ، بدأت في العمل مع الطلبات ، ومن الواضح أن أحدها يسبب العطل.
تضمين التغريدة
من المحتمل أن يكون خادم عربات التي تجرها الدواب يقوم بأشياء خاطئة عند التحدث إليه في إصدارات SSL / TLS محددة كما هو موضح في # 1567 (والعديد من الإصدارات الأخرى).
حاول فرض إصدار مختلف كما هو موضح هنا (بعض التنويه إلىLukasa)
والفائز (الخاسر) هو ssl_protocols TLSv1.2 TLSv1.1;
يبدو أن إزالة TLSv1
من البروتوكولات المدعومة على الخادم تمنع الطلبات من العمل.
الآن ، يمكنني تسمية هذا خطأ في الطلبات أو مكتبة أساسية؟
ملاحظة: يوصى بإزالة TLSv1 بسبب مخاوف أمنية ، فهناك ثغرات في ذلك.
ssbarnea ستجد أن القيد ليس في الطلبات ولكن في Python. لا توجد حاليًا إصدارات مشحونة من Python تدعم أي إصدار من TLS أحدث من V1.0 كما ترون في الجدول هنا .
تسمح Python 3.4 (لم يتم شحنها بعد ، ولا توجد ضمانات بأن الطلبات متوافقة معها) بدعم TLS1.2 و TLS1.1 ، لذا يمكنك تجربة ذلك. وإلا ، فسيتعين عليك السماح لـ TLSv1 للسماح بمرور الطلبات.
لا يزال هناك شيء غريب: في كلتا الحالتين ، استخدمت Python ، عندما تم اختبارها من OS X ، فشلت ، عند اختبارها من Ubuntu ، نجحت.
عادةً لن أتطرق إلى الإعدادات الافتراضية لـ SSL ، لكنني قمت بتشغيل تقرير SSL وحاولت حل معظم التحذيرات:
يتطلب FIPS: تعطيل SSL v2 و SSL v3 (فقط بروتوكولات إصدار TLS قيد الاستخدام)
اقرأ أيضًا عن هجمات BEAST.
تحقق منه هنا:
https://sslcheck.globalsign.com/en_US/sslcheck/؟host=sbarnea.com
لذا ، أتساءل عما إذا كان من الممكن إصلاح هذا ، من الواضح أنه إذا كان يعمل مع Python على Ubuntu ، فلا يمكن أن يكون محددًا لجميع إصدارات python.
مم ، للأسف يمكن ذلك. تعتمد الميزات النسبية للدعم ssl
الذي تحصل عليه على إصدار OpenSSL الذي قمت بتثبيته. قارن بين النسختين. =)
فقط لإعطاء القليل من الختام حول هذا الموضوع. إذا كان خادم الويب الخاص بك لا يسمح TLSv1 ، فستحصل على TLSv1.1 و 1.2 مع python 2.7.9 (من المقرر إصداره في ديسمبر 2014). ومع ذلك ، يمكنك أيضًا تثبيت PYOpenSSL وحقن ذلك في urrlib3 (http://urllib3.readthedocs.org/en/latest/security.html#openssl-pyopenssl) والذي يبدو أنه يسمح باستخدام الطلبات لخادم الويب الذي عطّل TLSv1 مع python 2.7.6 (وربما أخرى).
import urllib3.contrib.pyopenssl
urllib3.contrib.pyopenssl.inject_into_urllib3()
لكن في الحقيقة ، ربما لا ينبغي لخادم الويب أن يستنكر شيئًا يجبر الناس على القفز من خلال العديد من الأطواق الغريبة.
التعليق الأكثر فائدة
عمل حلو! التبديل من
requests.get(url, params=kwargs)
إلىrequests.post(url, data=kwargs)
إصلاحه! آسف لإزعاجك بهذا وشكرا للمساعدة!