File indexing completed on 2024-11-26 02:34:13
0001
0002
0003 import sys
0004 import os
0005 import re
0006 import string
0007 import mimetypes
0008 import http.client as httplib
0009 import ssl
0010 import gzip
0011 import hashlib
0012 from stat import *
0013
0014 import urllib.request as urllib2
0015 from subprocess import getstatusoutput
0016
0017 try:
0018 from Monitoring.DQM import visDQMUtils
0019 except:
0020 from DQMServices.FileIO import visDQMUtils
0021
0022 if sys.version_info[:3] >= (2, 4, 0):
0023 HTTPS = httplib.HTTPSConnection
0024 else:
0025 HTTPS = httplib.HTTPS
0026
0027 ssl_key_file = None
0028 ssl_cert_file = None
0029 context = None
0030
0031 class HTTPSCertAuth(HTTPS):
0032 def __init__(self, host, context = None, *args, **kwargs):
0033 if context is None:
0034 context = ssl._create_default_https_context()
0035 if ssl_key_file or ssl_cert_file:
0036 context.load_cert_chain(ssl_cert_file, ssl_key_file)
0037 HTTPS.__init__(self, host, context = context, **kwargs)
0038
0039 class HTTPSCertAuthenticate(urllib2.AbstractHTTPHandler):
0040 def default_open(self, req):
0041 return self.do_open(HTTPSCertAuth, req)
0042
0043 def filetype(filename):
0044 return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
0045
0046 def encode(args, files):
0047 """
0048 Encode form (name, value) and (name, filename, type) elements into
0049 multi-part/form-data. We don't actually need to know what we are
0050 uploading here, so just claim it's all text/plain.
0051 """
0052 boundary = b'----------=_DQM_FILE_BOUNDARY_=-----------'
0053 (body, crlf) = (b'', b'\r\n')
0054 for (key, value) in args.items():
0055 payload = str(value).encode('utf-8')
0056 body += b'--' + boundary + crlf
0057 body += (b'Content-Disposition: form-data; name="%s"' % key.encode('utf-8')) + crlf
0058 body += crlf + payload + crlf
0059 for (key, filename) in files.items():
0060 body += b'--' + boundary + crlf
0061 body += (b'Content-Disposition: form-data; name="%s"; filename="%s"'
0062 % (key.encode('utf-8'), os.path.basename(filename).encode('utf-8'))) + crlf
0063 body += (b'Content-Type: %s' % filetype(filename).encode('utf-8')) + crlf
0064 body += (b'Content-Length: %d' % os.stat(filename)[ST_SIZE]) + crlf
0065 with open(filename, 'rb') as file:
0066 body += crlf + file.read() + crlf
0067 body += b'--' + boundary + b'--' + crlf + crlf
0068 return (b'multipart/form-data; boundary=' + boundary, body)
0069
0070 def marshall(args, files, request):
0071 """
0072 Marshalls the arguments to the CGI script as multi-part/form-data,
0073 not the default application/x-www-form-url-encoded. This improves
0074 the transfer of the large inputs and eases command line invocation
0075 of the CGI script.
0076 """
0077 (type, body) = encode(args, files)
0078 request.add_header('Content-Type', type)
0079 request.add_header('Content-Length', str(len(body)))
0080 request.data = body
0081
0082 def upload(url, args, files):
0083 ident = "visDQMUpload DQMGUI/%s python/%s" % \
0084 (os.getenv('DQMGUI_VERSION', '?'), "%d.%d.%d" % sys.version_info[:3])
0085 datareq = urllib2.Request(url + '/data/put')
0086 datareq.add_header('Accept-encoding', 'gzip')
0087 datareq.add_header('User-agent', ident)
0088 marshall(args, files, datareq)
0089 if 'https://' in url:
0090 result = urllib2.build_opener(HTTPSCertAuthenticate()).open(datareq)
0091 else:
0092 result = urllib2.build_opener(urllib2.ProxyHandler({})).open(datareq)
0093
0094 data = result.read()
0095 if result.headers.get ('Content-encoding', '') == 'gzip':
0096 data = gzip.GzipFile (fileobj=StringIO(data)).read ()
0097 return (result.headers, data)
0098
0099 x509_path = os.getenv("X509_USER_PROXY", None)
0100 if x509_path and os.path.exists(x509_path):
0101 ssl_key_file = ssl_cert_file = x509_path
0102
0103 if not ssl_key_file:
0104 x509_path = os.getenv("X509_USER_KEY", None)
0105 if x509_path and os.path.exists(x509_path):
0106 ssl_key_file = x509_path
0107
0108 if not ssl_cert_file:
0109 x509_path = os.getenv("X509_USER_CERT", None)
0110 if x509_path and os.path.exists(x509_path):
0111 ssl_cert_file = x509_path
0112
0113 if not ssl_key_file and not ssl_cert_file:
0114 (status, uid) = getstatusoutput("id -u")
0115 if os.path.exists("/tmp/x509up_u%s" % uid):
0116 ssl_key_file = ssl_cert_file = "/tmp/x509up_u%s" % uid
0117
0118 if not ssl_key_file:
0119 x509_path = os.getenv("HOME") + "/.globus/userkey.pem"
0120 if os.path.exists(x509_path):
0121 ssl_key_file = x509_path
0122
0123 if not ssl_cert_file:
0124 x509_path = os.getenv("HOME") + "/.globus/usercert.pem"
0125 if os.path.exists(x509_path):
0126 ssl_cert_file = x509_path
0127
0128 if 'https://' in sys.argv[1] and (not ssl_key_file or not os.path.exists(ssl_key_file)):
0129 print("no certificate private key file found", file=sys.stderr)
0130 sys.exit(1)
0131
0132 if 'https://' in sys.argv[1] and (not ssl_cert_file or not os.path.exists(ssl_cert_file)):
0133 print("no certificate public key file found", file=sys.stderr)
0134 sys.exit(1)
0135
0136 try:
0137 for file_path in sys.argv[2:]:
0138
0139
0140 classification_ok, classification_result = visDQMUtils.classifyDQMFile(file_path)
0141 if not classification_ok:
0142 print("Check of filename before upload failed with following message:")
0143 print(classification_result)
0144 sys.exit(1)
0145
0146 else:
0147 print("Using SSL private key", ssl_key_file)
0148 print("Using SSL public key", ssl_cert_file)
0149
0150 hasher = hashlib.md5()
0151 with open(sys.argv[2], 'rb') as file:
0152 buf = file.read()
0153 hasher.update(buf)
0154
0155 (headers, data) = \
0156 upload(sys.argv[1],
0157 { 'size': os.stat(sys.argv[2])[ST_SIZE],
0158 'checksum': 'md5:%s' % hasher.hexdigest() },
0159 { 'file': file_path })
0160 print('Status code: ', headers.get("Dqm-Status-Code", "None"))
0161 print('Message: ', headers.get("Dqm-Status-Message", "None"))
0162 print('Detail: ', headers.get("Dqm-Status-Detail", "None"))
0163 print(data.decode('utf-8'))
0164 sys.exit(0)
0165 except urllib2.HTTPError as e:
0166 print('ERROR', e)
0167 print('Status code: ', e.hdrs.get("Dqm-Status-Code", "None"))
0168 print('Message: ', e.hdrs.get("Dqm-Status-Message", "None"))
0169 print('Detail: ', e.hdrs.get("Dqm-Status-Detail", "None"))
0170 sys.exit(1)