Access FTP URL with ftplib [duplicate] - python

This question already has an answer here:
Accessing FTP server with Python fails with "getaddrinfo" error
(1 answer)
Closed 2 years ago.
I am using python in Windows with ftplib to access a folder at ftp5.xyz.eu.
The folder is 'baz' in ftp5.xyz.eu in the folder 'foo bar'. So : ftp5.xyz.eu/foo bar/baz
I connect successfully at ftp5.xyz.eu but when i write the whole path to the folder it gives me an error:
from ftplib import FTP
#domain name or server ip:
ftp = FTP('ftp5.xyz.eu/foo%20bar')
...
ftp.dir()
error gived below:
File "C:\Users\mirel.voicu\AppData\Local\Programs\Python\Python37\lib\ftplib.py", line 117, in __init__
self.connect(host)
File "C:\Users\mirel.voicu\AppData\Local\Programs\Python\Python37\lib\ftplib.py", line 152, in connect
source_address=self.source_address)
File "C:\Users\mirel.voicu\AppData\Local\Programs\Python\Python37\lib\socket.py", line 707, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
File "C:\Users\mirel.voicu\AppData\Local\Programs\Python\Python37\lib\socket.py", line 748, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno 11001] getaddrinfo failed

This has nothing to do with the space. The first argument of FTP constructor is host – a hostname or an IP address – not an URL.
So it should be:
ftp = FTP('ftp5.xyz.eu')
If you want to list files in foo bar subfolder, either do:
ftp.cwd('foo bar')
ftp.dir()
or
ftp.dir('foo bar')

The error message is Python's slightly obtuse way of saying "there is no server with that name"; and indeed, the server name here is not valid. You are passing 'ftp5.xyz.eu/foo%20bar' where you should be passing in just 'ftp5.xyz.eu'.
FTP traditionally does not use URL addresses, and Python's ftplib has no support for parsing them. You will need to pick apart the URL using, oh, I guess urllib, and take it from there.
from ftplib import FTP
from urllib.parse import urlparse
parsed = urlparse('ftp://ftp5.xyz.eu/foo%20bar')
ftp = FTP(parsed.netloc)
ftp.login()
ftp.cwd(parsed.path)
ftp.dir()
The parsed parsed.path still uses %20 where probably the FTP server expects a literal space; maybe also do URL decoding (urllib.parse.unquote or maybe urlllib.parse.unquote_plus).

Related

TIme out error in python while sending email [duplicate]

I have tried to attached a file to the mail using python.
Code:
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from smtplib import SMTPException
def send_Email():
file1="abc.txt"
message = "Test mail"
msg = MIMEMultipart()
msg.attach(MIMEText(file(file1).read()))
try:
smtpObj = smtplib.SMTP('smtp server name',port)
smtpObj.sendmail(sender, EmailId, message, msg.as_string() )
print "Successfully sent email"
except SMTPException:
print "Error: unable to send email"
Bt I have get the error: socket.gaierror: [Errno 11001] getaddrinfo failed
full error message:
File "C:\Python27\lib\smtplib.py", line 249, in __init__
(code, msg) = self.connect(host, port)
File "C:\Python27\lib\smtplib.py", line 309, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "C:\Python27\lib\smtplib.py", line 284, in _get_socket
return socket.create_connection((port, host), timeout)
File "C:\Python27\lib\socket.py", line 553, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
socket.gaierror: [Errno 11001] getaddrinfo failed
I know for sure that gaierror comes up when you are working from behind proxy.
The problem is that the DNS lookup for 'smtp server name' is failing - if this is your exact code then you can see why - if not and you have the valid qualified name for the SMTP server then you may have issues with the firewall/internet connection, etc., also port has to be set to a valid value to match your servers SMTP configuration, (usually port 25 but not absolutely always).
The below answer may be quite irrelevant to the question. But,some users may have a different scenario.
If a server can be reached only through VPN and if we try to reach it with VPN disconnected, this error : "gaierror: [Errno 11001] getaddrinfo failed" crops up.
Connect to VPN and then executing the code should work good.
In my case was a host problem. Using debug mode, I spotted that in (host, port, 0, SOCK_STREAM) I got host=local and it should be host=localhost.
In the run.py I defined localhost and the file hosts (c:\windows\system32\drivers\etc\hosts) was defined local.
They have to be equal, otherwise you get the socket.gaieeror.
There seems to be a bug in urllib3 version 1.25.9 package. This produced "socket.gaierror: [Errno 11001] getaddrinfo failed" error for me (working from behind an authenticated proxy server).
Downgrading to urllib3 version 1.25.8 solved the problem.
you might did a little mistake in settings.py file..
check your code one more time in your settings file
settings.py:
EMAIL_BACKEND='django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'your_email'
EMAIL_HOST_PASSWORD = 'your_password'
EMAIL_PORT = 587
EMAIL_USE_TLS=True
I got this error when I tried using flask-mail
I just had to resend the message and it worked perfectly well.
I don't know why I got the error the first time perhaps it might be a bug in the library...
You need to login using your credential. Try:
smtpObj = smtplib.SMTP('smtp server name',port)
smtpObj .starttls()
smtpObj .login(email, password)
smtpObj.sendmail(sender, EmailId, message, msg.as_string() )
print "Successfully sent email"
I prefer u guys to run the file as administrator for eg
open cmd as administrator then
type
cd C:\into ur .py file path
and then type
python filename.py
it worked for me.
good luck
You need to activate IMAP/SMTP service active for your host mail.

Connecting with ftplib via FTP proxy in Python?

I am trying to download files from FTP. It works fine at home but it doesn't work when I run through company's network. I know there is something to do with proxy. I have looked at a few posts regarding the proxy issue in Python. I have tried to set up a connection to the proxy. It works ok for url but it failed when connecting to FTP. Does anyone know a way to do that? Thanks in advance.
Below is my code:
import os
import urllib
import ftplib
from ftplib import FTP
from getpass import getpass
from urllib.request import urlopen, ProxyHandler, HTTPHandler, HTTPBasicAuthHandler, \
build_opener, install_opener
user_proxy = "XXX"
pass_proxy = "YYY"
url_proxy = "ZZZ"
port_proxy = "89"
url_proxy = "ftp://%s:%s#%s:%s" % (user_proxy, pass_proxy, url_proxy, port_proxy)
authinfo = urllib.request.HTTPBasicAuthHandler()
proxy_support = urllib.request.ProxyHandler({"ftp" : url_proxy})
# build a new opener that adds authentication and caching FTP handlers
opener = urllib.request.build_opener(proxy_support, authinfo,
urllib.request.CacheFTPHandler)
# install it
urllib.request.install_opener(opener)
#url works ok
f = urllib.request.urlopen('http://www.google.com/')
print(f.read(500))
urllib.request.install_opener(opener)
#ftp is not working
ftp = ftplib.FTP('ftp:/ba1.geog.umd.edu', 'user', 'burnt_data')
The error message I got:
730 # and socket type values to enum constants.
731 addrlist = []
--> 732 for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
733 af, socktype, proto, canonname, sa = res
734 addrlist.append((_intenum_converter(af, AddressFamily),
gaierror: [Errno 11004] getaddrinfo failed
I can connect via the proxy using FileZilla by selecting custom FTP proxy with specification:
USER %u#%h %s
PASS %p
ACCT %w
FTP Proxy using FileZilla
You are connecting using an FTP proxy.
FTP proxy cannot work with HTTP, so your test against http:// URL to www.google.com is completely irrelevant and does not prove anything.
FTP proxy works as an FTP server. You connect to the proxy, instead of to the actual server. And then use some special syntax of a username (or other credentials) to specify your actual target FTP server and its credentials. In your case the special syntax of username is user#host user_proxy. Your proxy expects the proxy password in FTP ACCT command.
This should work for your specific case:
host_proxy = '192.168.149.50'
user_proxy = 'XXX'
pass_proxy = 'YYY'
user = 'user'
user_pass = 'burnt_data'
host = 'ba1.geog.umd.edu'
u = "%s#%s %s" % (user, host, user_proxy)
ftp = ftplib.FTP(host_proxy, u, user_pass, pass_proxy)
No other code should be needed (urllib or any other).
If the proxy uses a custom port (not 21), use this:
ftp = ftplib.FTP()
ftp.connect(host_proxy, port_proxy)
ftp.login(u, user_pass, pass_proxy)

troubleshooting python code

I am in my first steps in learning python so excuse my questions please. I want to run the code below (taken from: http://docs.python.org/library/ssl.html) :
import socket, ssl, pprint
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# require a certificate from the server
ssl_sock = ssl.wrap_socket(s,
ca_certs="F:/cert",
cert_reqs=ssl.CERT_REQUIRED)
ssl_sock.connect(('www.versign.com', 443))
print repr(ssl_sock.getpeername())
print ssl_sock.cipher()
print pprint.pformat(ssl_sock.getpeercert())
# Set a simple HTTP request -- use httplib in actual code.
ssl_sock.write("""GET / HTTP/1.0\r
Host: www.verisign.com\r\n\r\n""")
# Read a chunk of data. Will not necessarily
# read all the data returned by the server.
data = ssl_sock.read()
# note that closing the SSLSocket will also close the underlying socket
ssl_sock.close()
I got the following errors:
Traceback (most recent call last):
File "C:\Users\e\workspace\PythonTesting\source\HelloWorld.py", line 38, in
ssl_sock.connect(('www.versign.com', 443))
File "C:\Python27\lib\ssl.py", line 331, in connect
self._real_connect(addr, False)
File "C:\Python27\lib\ssl.py", line 314, in _real_connect
self.ca_certs, self.ciphers)
ssl.SSLError: [Errno 185090050] _ssl.c:340: error:0B084002:x509 certificate routines:X509_load_cert_crl_file:system lib
The error reporting in python does not look guiding to find the source of the problem. i might be mistaken. Can anybody help in telling me what is the problem in the code ?
This is one area where the Python standard library is known to be difficult to use. Instead you may want to use the requests library. Documentation on sending certificates is available at: http://docs.python-requests.org/en/latest/user/advanced/#ssl-cert-verification
Your code is referring to a certificate file on drive 'F:' (using the ca_certs parameter), which is not found during execution -- is there one?
See the relevant documentation:
The ca_certs file contains a set of concatenated “certification
authority” certificates, which are used to validate certificates
passed from the other end of the connection.
Does the certificate referenced exist on your filesystem? I think that error is in response to invalid cert from this code:
ssl_sock = ssl.wrap_socket(s,ca_certs="F:/cert",cert_reqs=ssl.CERT_REQUIRED)

HTTPConnection request socket.gaierror in python

I encountered an error today while trying to retrieve an XML by sending a 'GET' HTTP request.
from httplib import HTTPConnection
import urllib
params = urllib.urlencode({'sK': 'test', 'sXML': 1})
httpCon = HTTPConnection("http://www.podnapisi.net",80)
httpCon.request('GET', '/en/ppodnapisi/search',params)
r1 = httpCon.getresponse()
and here is the error i got:
.....
File "C:\Python27\lib\socket.py", line 553, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
socket.gaierror: [Errno 11004] getaddrinfo failed
The XML that I am trying to retrieve HERE
How can I fix this error ?
Thanks in Advance ...
No scheme (http://) in the HTTPConnection constructor:
httpCon = HTTPConnection("www.podnapisi.net",80)
It already knows it's HTTP, it's an HTTPConnection object :)
You accidentally included the protocol prefix in the domain argument to HTTPConnection. You want:
httpCon = HTTPConnection("www.podnapisi.net", 80)
Generally, This error indicates there was a problem resolving the domain name to an IP address. In It might be just intermittent. If the problem persists, check the DNS configuration on your system.
For example, you can set it to use Google's public DNS server. For more information about how to configure your DNS server on Microsoft Windows, refer to Microsoft's knowledge database.

Error using httlib's HTTPSConnection with PKCS#12 certificate

I'm trying to use httplib's HTTPSConnection for client validation, using a PKCS #12 certificate. I know the certificate is good, as I can connect to the server using it in MSIE and Firefox.
Here's my connect function (the certificate includes the private key). I've pared it down to just the basics:
def connect(self, cert_file, host, usrname, passwd):
self.cert_file = cert_file
self.host = host
self.conn = httplib.HTTPSConnection(host=self.host, port=self.port, key_file=cert_file, cert_file=cert_file)
self.conn.putrequest('GET', 'pathnet/,DanaInfo=200.222.1.1+')
self.conn.endheaders()
retCreateCon = self.conn.getresponse()
if is_verbose:
print "Create HTTPS connection, " + retCreateCon.read()
(Note: No comments on the hard-coded path, please - I'm trying to get this to work first; I'll make it pretty afterwards. The hard-coded path is correct, as I connect to it in MSIE and Firefox. I changed the IP address for the post.)
When I try to run this using a PKCS#12 certificate (a .pfx file), I get back what appears to be an openSSL error. Here is the entire error traceback:
File "Usinghttplib_Test.py", line 175, in
t.connect(cert_file=opts["-keys"], host=host_name, usrname=opts["-username"], passwd=opts["-password"])
File "Usinghttplib_Test.py", line 40, in connect
self.conn.endheaders()
File "c:\python26\lib\httplib.py", line 904, in endheaders
self._send_output()
File "c:\python26\lib\httplib.py", line 776, in _send_output
self.send(msg)
File "c:\python26\lib\httplib.py", line 735, in send
self.connect()
File "c:\python26\lib\httplib.py", line 1112, in connect
self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file)
File "c:\python26\lib\ssl.py", line 350, in wrap_socket
suppress_ragged_eofs=suppress_ragged_eofs)
File "c:\python26\lib\ssl.py", line 113, in __init__
cert_reqs, ssl_version, ca_certs) ssl.SSLError: [Errno 336265225] _ssl.c:337: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib
Notice, the openSSL error (the last entry in the list) notes "PEM lib", which I found odd, since I'm not trying to use a PEM certificate.
For kicks, I converted the PKCS#12 cert to a PEM cert, and ran the same code using that. In that case, I received no error, I was prompted to enter the PEM pass phrase, and the code did attempt to reach the server. (I received the response "The service is not
available. Please try again later.", but I believe that would be because the server does not accept the PEM cert. I can't connect in Firefox to the server using the PEM cert either.)
Is httplib's HTTPSConnection supposed to support PCKS#12 certificates? (That is, pfx files.) If so, why does it look like openSSL is trying to load it inside the PEM lib? Am I doing this all wrong?
Any advice is welcome.
EDIT: The certificate file contains both the certificate and the private key, which is why I'm providing the same file name for both the HTTPSConnection's key_file and cert_file parameters.
This is no surprise. The Python library reference docs are pretty clear about this. From http://docs.python.org/library/httplib.html:
class httplib.HTTPSConnection(host[, port[, key_file[, cert_file[, strict[, timeout[, source_address]]]]]])
A subclass of HTTPConnection that uses SSL for communication with secure servers. Default port is 443. key_file is the name of a PEM formatted file that contains your private key. cert_file is a PEM formatted certificate chain file.
On the openSSL mailing list, I chatted with Mounir Idrassi. He noted that openSSL does support PKCS#12 files, and - based on the error message I'm receiving - it appears that httplib is calling the wrong function to load the key.
In his words:
Concerning the error you are getting, it appears that the phython module you are using is calling SSL_CTX_use_PrivateKey_file by giving it the PKCS#12 file name. This is does not because SSL_CTX_use_PrivateKey_file only accepts two formats : SSL_FILETYPE_PEM and SSL_FILETYPE_ASN1.
(I'm giving httplib the PKCS#12 file name as key file, because this file format includes both the cert and the private key in the same file.)
In order to correct this, you have two solutions :
- Either feed the python module with the private key in a PEM file.
- Or modify the source code of this python module in order to use the PKCS#12 functions I mentioned above to extract the private key as an EVP_PKEY and then call SSL_use_PrivateKey instead of SSL_CTX_use_PrivateKey_file, along with SSL_use_certificate for setting the associated certificate.
(I tried the former and wasn't able to get it to work. Doesn't necessarily mean it won't work; only that I wasn't able to.)

Categories

Resources