Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
File Transfer Service
fts-rest
Commits
dd418e8c
Commit
dd418e8c
authored
Mar 24, 2014
by
Alejandro Alvarez Ayllon
Browse files
Switched to pycurl. Caching password so it is asked only once.
parent
bc2f7ef1
Changes
4
Hide whitespace changes
Inline
Side-by-side
dist/fts-rest.spec
View file @
dd418e8c
...
...
@@ -56,6 +56,7 @@ Summary: FTS3 Rest Interface CLI
Group: Applications/Internet
Requires: python-fts
Requires: python-pycurl
%description cli
Command line utilities for the FTS3 REST interface
...
...
src/fts3/rest/client/context.py
View file @
dd418e8c
from
datetime
import
datetime
from
M2Crypto
import
X509
,
RSA
,
EVP
,
BIO
import
getpass
import
json
import
logging
import
os
...
...
@@ -37,6 +38,11 @@ class Context(object):
else
:
self
.
logger
=
logging
.
getLogger
()
def
_read_passwd_from_stdin
(
self
,
*
args
,
**
kwargs
):
if
not
self
.
passwd
:
self
.
passwd
=
getpass
.
getpass
(
'Private key password: '
)
return
self
.
passwd
def
_set_x509
(
self
,
ucert
,
ukey
):
if
not
ucert
:
if
'X509_USER_PROXY'
in
os
.
environ
:
...
...
@@ -57,7 +63,7 @@ class Context(object):
if
not_after
.
get_datetime
()
<
datetime
.
now
(
pytz
.
UTC
):
raise
Exception
(
"Proxy expired!"
)
self
.
rsa_key
=
RSA
.
load_key
(
ukey
)
self
.
rsa_key
=
RSA
.
load_key
(
ukey
,
self
.
_read_passwd_from_stdin
)
self
.
evp_key
=
EVP
.
PKey
()
self
.
evp_key
.
assign_rsa
(
self
.
rsa_key
)
...
...
@@ -82,10 +88,12 @@ class Context(object):
return
endpoint_info
def
__init__
(
self
,
endpoint
,
ucert
=
None
,
ukey
=
None
,
logger
=
None
):
self
.
passwd
=
None
self
.
_set_logger
(
logger
)
self
.
_set_endpoint
(
endpoint
)
self
.
_set_x509
(
ucert
,
ukey
)
self
.
_requester
=
RequestFactory
(
self
.
ucert
,
self
.
ukey
)
self
.
_requester
=
RequestFactory
(
self
.
ucert
,
self
.
ukey
,
passwd
=
self
.
passwd
)
self
.
endpoint_info
=
self
.
_validate_endpoint
()
# Log obtained information
self
.
logger
.
debug
(
"Using endpoint: %s"
%
self
.
endpoint_info
[
'url'
])
...
...
src/fts3/rest/client/delegator.py
View file @
dd418e8c
...
...
@@ -46,7 +46,6 @@ class Delegator(object):
proxy_subject
.
add_entry_by_txt
(
'commonName'
,
0x1000
,
'proxy'
,
-
1
,
-
1
,
0
)
proxy
=
X509
.
X509
()
proxy
.
set_version
(
2
)
proxy
.
set_subject
(
proxy_subject
)
proxy
.
set_serial_number
(
int
(
time
.
time
()))
proxy
.
set_version
(
x509_request
.
get_version
())
...
...
@@ -75,6 +74,7 @@ class Delegator(object):
if
any_rfc_proxies
:
raise
NotImplementedError
(
'RFC proxies not supported yet'
)
proxy
.
set_version
(
2
)
proxy
.
sign
(
self
.
context
.
evp_key
,
'sha1'
)
return
proxy
...
...
src/fts3/rest/client/request.py
View file @
dd418e8c
import
httplib
import
sys
import
urllib2
import
pycurl
from
exceptions
import
*
class
HTTPSWithCertHandler
(
urllib2
.
HTTPSHandler
):
def
__init__
(
self
,
cert
,
key
):
urllib2
.
HTTPSHandler
.
__init__
(
self
)
self
.
cert
=
cert
self
.
key
=
key
def
https_open
(
self
,
req
):
return
self
.
do_open
(
self
.
getConnection
,
req
)
def
getConnection
(
self
,
host
,
timeout
=
1000
):
return
httplib
.
HTTPSConnection
(
host
,
cert_file
=
self
.
cert
,
key_file
=
self
.
key
)
from
StringIO
import
StringIO
class
RequestFactory
(
object
):
def
__init__
(
self
,
ucert
,
ukey
,
cafile
=
None
,
capath
=
None
,
verify
=
False
):
def
__init__
(
self
,
ucert
,
ukey
,
cafile
=
None
,
capath
=
None
,
passwd
=
None
,
verify
=
False
):
self
.
ucert
=
ucert
self
.
ukey
=
ukey
self
.
passwd
=
passwd
self
.
verify
=
verify
...
...
@@ -36,28 +22,67 @@ class RequestFactory(object):
else
:
self
.
capath
=
'/etc/grid-security/certificates'
def
_handleException
(
self
,
url
,
e
):
f
=
open
(
'/tmp/request-error.html'
,
'w'
)
print
>>
f
,
e
.
read
()
del
f
if
e
.
code
==
400
:
raise
ClientError
(
str
(
e
))
elif
e
.
code
>=
401
and
e
.
code
<=
403
:
def
_handle_error
(
self
,
url
,
code
):
if
code
==
400
:
raise
ClientError
(
'Bad request'
)
elif
code
>=
401
and
code
<=
403
:
raise
Unauthorized
()
elif
e
.
code
==
404
:
elif
code
==
404
:
raise
NotFound
(
url
)
elif
e
.
code
>
404
and
e
.
code
<
500
:
raise
ClientError
(
str
(
e
))
elif
e
.
code
>=
500
:
raise
ServerError
(
str
(
e
))
def
method
(
self
,
method
,
url
,
body
=
None
,
headers
=
{}):
opener
=
urllib2
.
build_opener
(
HTTPSWithCertHandler
(
self
.
ucert
,
self
.
ukey
))
try
:
request
=
urllib2
.
Request
(
url
,
headers
=
headers
,
data
=
body
)
request
.
get_method
=
lambda
:
method
response
=
opener
.
open
(
request
)
return
response
.
read
()
except
urllib2
.
HTTPError
,
e
:
self
.
_handleException
(
url
,
e
)
elif
code
>
404
and
code
<
500
:
raise
ClientError
(
str
(
code
))
elif
code
>=
500
:
raise
ServerError
(
str
(
code
))
def
_receive
(
self
,
data
):
self
.
_response
+=
data
return
len
(
data
)
def
_send
(
self
,
len
):
return
self
.
_input
.
read
(
len
)
def
_ioctl
(
self
,
cmd
):
if
cmd
==
pycurl
.
IOCMD_RESTARTREAD
:
self
.
_input
.
seek
(
0
)
def
method
(
self
,
method
,
url
,
body
=
None
,
headers
=
None
):
handle
=
pycurl
.
Curl
()
handle
.
setopt
(
pycurl
.
SSL_VERIFYPEER
,
self
.
verify
)
handle
.
setopt
(
pycurl
.
SSL_VERIFYHOST
,
self
.
verify
)
handle
.
setopt
(
pycurl
.
CAPATH
,
self
.
capath
)
handle
.
setopt
(
pycurl
.
CAINFO
,
self
.
cafile
)
handle
.
setopt
(
pycurl
.
SSLCERT
,
self
.
ucert
)
handle
.
setopt
(
pycurl
.
SSLKEY
,
self
.
ukey
)
if
self
.
passwd
:
handle
.
setopt
(
pycurl
.
SSLKEYPASSWD
,
self
.
passwd
)
if
method
==
'GET'
:
handle
.
setopt
(
pycurl
.
HTTPGET
,
True
)
elif
method
==
'HEAD'
:
handle
.
setopt
(
pycurl
.
NOBODY
,
True
)
elif
method
==
'POST'
:
handle
.
setopt
(
pycurl
.
POST
,
True
)
elif
method
==
'PUT'
:
handle
.
setopt
(
pycurl
.
UPLOAD
,
True
)
else
:
handle
.
setopt
(
pycurl
.
CUSTOMREQUEST
,
method
)
if
headers
:
handle
.
setopt
(
pycurl
.
HTTPHEADER
,
map
(
lambda
(
k
,
v
):
"%s: %s"
%
(
k
,
v
),
headers
.
iteritems
()))
handle
.
setopt
(
pycurl
.
URL
,
str
(
url
))
self
.
_response
=
''
handle
.
setopt
(
pycurl
.
WRITEFUNCTION
,
self
.
_receive
)
if
body
is
not
None
:
self
.
_input
=
StringIO
(
body
)
handle
.
setopt
(
pycurl
.
INFILESIZE
,
len
(
body
))
handle
.
setopt
(
pycurl
.
POSTFIELDSIZE
,
len
(
body
))
handle
.
setopt
(
pycurl
.
READFUNCTION
,
self
.
_send
)
handle
.
setopt
(
pycurl
.
IOCTLFUNCTION
,
self
.
_ioctl
)
handle
.
perform
()
self
.
_handle_error
(
url
,
handle
.
getinfo
(
pycurl
.
HTTP_CODE
))
return
self
.
_response
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment