1313from distutils .errors import DistutilsError
1414from distutils .version import StrictVersion as Version
1515from pathlib import Path
16- from urllib .request import urlcleanup , urljoin , urlopen , urlretrieve
16+ from urllib .parse import urljoin
17+ from urllib .request import Request , urlcleanup , urlopen , urlretrieve
1718
1819from setuptools import Extension , setup
1920from setuptools .command .build_ext import build_ext as build_ext_orig
@@ -31,31 +32,60 @@ def handle_starttag(self, tag, attrs):
3132 self .hrefs .append (value )
3233
3334
35+ def make_request (url , github_token = None , json_response = False ):
36+ headers = {'User-Agent' : 'https://github.com/xmlsec/python-xmlsec' }
37+ if github_token :
38+ headers ['authorization' ] = "Bearer " + github_token
39+ request = Request (url , headers = headers )
40+ with contextlib .closing (urlopen (request )) as r :
41+ if json_response :
42+ return json .load (r )
43+ else :
44+ charset = r .headers .get_content_charset () or 'utf-8'
45+ content = r .read ().decode (charset )
46+ return content
47+
48+
3449def latest_release_from_html (url , matcher ):
35- with contextlib .closing (urlopen (url )) as r :
36- charset = r .headers .get_content_charset () or 'utf-8'
37- content = r .read ().decode (charset )
38- collector = HrefCollector ()
39- collector .feed (content )
40- hrefs = collector .hrefs
41-
42- def comp (text ):
43- try :
44- return Version (matcher .match (text ).groupdict ()['version' ])
45- except (AttributeError , ValueError ):
46- return Version ('0.0' )
50+ content = make_request (url )
51+ collector = HrefCollector ()
52+ collector .feed (content )
53+ hrefs = collector .hrefs
54+
55+ def comp (text ):
56+ try :
57+ return Version (matcher .match (text ).groupdict ()['version' ])
58+ except (AttributeError , ValueError ):
59+ return Version ('0.0' )
4760
48- latest = max (hrefs , key = comp )
49- return '{}/{}' .format (url , latest )
61+ latest = max (hrefs , key = comp )
62+ return '{}/{}' .format (url , latest )
5063
5164
5265def latest_release_from_gnome_org_cache (url , lib_name ):
5366 cache_url = '{}/cache.json' .format (url )
54- with contextlib .closing (urlopen (cache_url )) as r :
55- cache = json .load (r )
56- latest_version = cache [2 ][lib_name ][- 1 ]
57- latest_source = cache [1 ][lib_name ][latest_version ]['tar.xz' ]
58- return '{}/{}' .format (url , latest_source )
67+ cache = make_request (cache_url , json_response = True )
68+ latest_version = cache [2 ][lib_name ][- 1 ]
69+ latest_source = cache [1 ][lib_name ][latest_version ]['tar.xz' ]
70+ return '{}/{}' .format (url , latest_source )
71+
72+
73+ def latest_release_from_github_api (repo ):
74+ api_url = 'https://api.github.com/repos/{}/releases' .format (repo )
75+
76+ # if we are running in CI, pass along the GH_TOKEN, so we don't get rate limited
77+ token = os .environ .get ("GH_TOKEN" )
78+ if token :
79+ log .info ("Using GitHub token to avoid rate limiting" )
80+ api_releases = make_request (api_url , token , json_response = True )
81+ releases = [r ['tarball_url' ] for r in api_releases if r ['prerelease' ] is False and r ['draft' ] is False ]
82+ if not releases :
83+ raise DistutilsError ('No release found for {}' .format (repo ))
84+ return releases [0 ]
85+
86+
87+ def latest_openssl_release ():
88+ return latest_release_from_github_api ('openssl/openssl' )
5989
6090
6191def latest_zlib_release ():
@@ -238,7 +268,7 @@ def prepare_static_build_win(self):
238268 ext .include_dirs = [str (p .absolute ()) for p in includes ]
239269
240270 def prepare_static_build_linux (self ):
241- self .openssl_version = os .environ .get ('PYXMLSEC_OPENSSL_VERSION' , '1.1.1t' )
271+ self .openssl_version = os .environ .get ('PYXMLSEC_OPENSSL_VERSION' )
242272 self .libiconv_version = os .environ .get ('PYXMLSEC_LIBICONV_VERSION' )
243273 self .libxml2_version = os .environ .get ('PYXMLSEC_LIBXML2_VERSION' )
244274 self .libxslt_version = os .environ .get ('PYXMLSEC_LIBXSLT_VERSION' )
@@ -250,8 +280,13 @@ def prepare_static_build_linux(self):
250280 if openssl_tar is None :
251281 self .info ('{:10}: {}' .format ('OpenSSL' , 'source tar not found, downloading ...' ))
252282 openssl_tar = self .libs_dir / 'openssl.tar.gz'
253- self .info ('{:10}: {} {}' .format ('OpenSSL' , 'version' , self .openssl_version ))
254- urlretrieve ('https://www.openssl.org/source/openssl-{}.tar.gz' .format (self .openssl_version ), str (openssl_tar ))
283+ if self .openssl_version is None :
284+ url = latest_openssl_release ()
285+ self .info ('{:10}: {}' .format ('OpenSSL' , 'PYXMLSEC_OPENSSL_VERSION unset, downloading latest from {}' .format (url )))
286+ else :
287+ url = 'https://api.github.com/repos/openssl/openssl/tarball/openssl-{}' .format (self .openssl_version )
288+ self .info ('{:10}: {} {}' .format ('OpenSSL' , 'version' , self .openssl_version ))
289+ urlretrieve (url , str (openssl_tar ))
255290
256291 # fetch zlib
257292 zlib_tar = next (self .libs_dir .glob ('zlib*.tar.gz' ), None )
@@ -361,7 +396,7 @@ def prepare_static_build_linux(self):
361396
362397 self .info ('Building OpenSSL' )
363398 openssl_dir = next (self .build_libs_dir .glob ('openssl-*' ))
364- subprocess .check_output (['./config' , prefix_arg , 'no-shared' , '-fPIC' ], cwd = str (openssl_dir ), env = env )
399+ subprocess .check_output (['./config' , prefix_arg , 'no-shared' , '-fPIC' , '--libdir=lib' ], cwd = str (openssl_dir ), env = env )
365400 subprocess .check_output (['make' , '-j{}' .format (multiprocessing .cpu_count () + 1 )], cwd = str (openssl_dir ), env = env )
366401 subprocess .check_output (
367402 ['make' , '-j{}' .format (multiprocessing .cpu_count () + 1 ), 'install_sw' ], cwd = str (openssl_dir ), env = env
0 commit comments