CMS 3D CMS Logo

visDQMUpload.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 import sys
4 import os
5 import re
6 import string
7 import httplib
8 import mimetypes
9 import urllib
10 import urllib2
11 import httplib
12 import gzip
13 import hashlib
14 from commands import getstatusoutput
15 from cStringIO import StringIO
16 from stat import *
17 try:
18  from Monitoring.DQM import visDQMUtils
19 except:
20  import visDQMUtils
21 
22 HTTPS = httplib.HTTPS
23 if sys.version_info[:3] >= (2, 4, 0):
24  HTTPS = httplib.HTTPSConnection
25 
26 ssl_key_file = None
27 ssl_cert_file = None
28 
29 class HTTPSCertAuth(HTTPS):
30  def __init__(self, host, *args, **kwargs):
31  HTTPS.__init__(self, host, key_file = ssl_key_file, cert_file = ssl_cert_file, **kwargs)
32 
33 class HTTPSCertAuthenticate(urllib2.AbstractHTTPHandler):
34  def default_open(self, req):
35  return self.do_open(HTTPSCertAuth, req)
36 
37 def filetype(filename):
38  return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
39 
40 def encode(args, files):
41  """
42  Encode form (name, value) and (name, filename, type) elements into
43  multi-part/form-data. We don't actually need to know what we are
44  uploading here, so just claim it's all text/plain.
45  """
46  boundary = '----------=_DQM_FILE_BOUNDARY_=-----------'
47  (body, crlf) = ('', '\r\n')
48  for (key, value) in args.items():
49  payload = str(value)
50  body += '--' + boundary + crlf
51  body += ('Content-Disposition: form-data; name="%s"' % key) + crlf
52  body += crlf + payload + crlf
53  for (key, filename) in files.items():
54  body += '--' + boundary + crlf
55  body += ('Content-Disposition: form-data; name="%s"; filename="%s"'
56  % (key, os.path.basename(filename))) + crlf
57  body += ('Content-Type: %s' % filetype(filename)) + crlf
58  body += ('Content-Length: %d' % os.stat(filename)[ST_SIZE]) + crlf
59  body += crlf + open(filename, "r").read() + crlf
60  body += '--' + boundary + '--' + crlf + crlf
61  return ('multipart/form-data; boundary=' + boundary, body)
62 
63 def marshall(args, files, request):
64  """
65  Marshalls the arguments to the CGI script as multi-part/form-data,
66  not the default application/x-www-form-url-encoded. This improves
67  the transfer of the large inputs and eases command line invocation
68  of the CGI script.
69  """
70  (type, body) = encode(args, files)
71  request.add_header('Content-Type', type)
72  request.add_header('Content-Length', str(len(body)))
73  request.add_data(body)
74 
75 def upload(url, args, files):
76  ident = "visDQMUpload DQMGUI/%s python/%s" % \
77  (os.getenv('DQMGUI_VERSION', '?'), "%d.%d.%d" % sys.version_info[:3])
78  datareq = urllib2.Request(url + '/data/put')
79  datareq.add_header('Accept-encoding', 'gzip')
80  datareq.add_header('User-agent', ident)
81  marshall(args, files, datareq)
82  if 'https://' in url:
83  result = urllib2.build_opener(HTTPSCertAuthenticate()).open(datareq)
84  else:
85  result = urllib2.build_opener(urllib2.ProxyHandler({})).open(datareq)
86 
87  data = result.read()
88  if result.headers.get ('Content-encoding', '') == 'gzip':
89  data = gzip.GzipFile (fileobj=StringIO(data)).read ()
90  return (result.headers, data)
91 
92 x509_path = os.getenv("X509_USER_PROXY", None)
93 if x509_path and os.path.exists(x509_path):
94  ssl_key_file = ssl_cert_file = x509_path
95 
96 if not ssl_key_file:
97  x509_path = os.getenv("X509_USER_KEY", None)
98  if x509_path and os.path.exists(x509_path):
99  ssl_key_file = x509_path
100 
101 if not ssl_cert_file:
102  x509_path = os.getenv("X509_USER_CERT", None)
103  if x509_path and os.path.exists(x509_path):
104  ssl_cert_file = x509_path
105 
106 if not ssl_key_file and not ssl_cert_file:
107  (status, uid) = getstatusoutput("id -u")
108  if os.path.exists("/tmp/x509up_u%s" % uid):
109  ssl_key_file = ssl_cert_file = "/tmp/x509up_u%s" % uid
110 
111 if not ssl_key_file:
112  x509_path = os.getenv("HOME") + "/.globus/userkey.pem"
113  if os.path.exists(x509_path):
114  ssl_key_file = x509_path
115 
116 if not ssl_cert_file:
117  x509_path = os.getenv("HOME") + "/.globus/usercert.pem"
118  if os.path.exists(x509_path):
119  ssl_cert_file = x509_path
120 
121 if 'https://' in sys.argv[1] and (not ssl_key_file or not os.path.exists(ssl_key_file)):
122  print >>sys.stderr, "no certificate private key file found"
123  sys.exit(1)
124 
125 if 'https://' in sys.argv[1] and (not ssl_cert_file or not os.path.exists(ssl_cert_file)):
126  print >>sys.stderr, "no certificate public key file found"
127  sys.exit(1)
128 
129 try:
130  for file_path in sys.argv[2:]:
131  # Before even trying to make a call to the other side, we first do a check on
132  # the filename:
133  classification_ok, classification_result = visDQMUtils.classifyDQMFile(file_path)
134  if not classification_ok:
135  print "Check of filename before upload failed with following message:"
136  print classification_result
137  sys.exit(1)
138  # If file check was fine, we continue with the upload method:
139  else:
140  print "Using SSL private key", ssl_key_file
141  print "Using SSL public key", ssl_cert_file
142  (headers, data) = \
143  upload(sys.argv[1],
144  { 'size': os.stat(sys.argv[2])[ST_SIZE],
145  'checksum': "md5:%s" % hashlib.md5(file(sys.argv[2]).read()).hexdigest() },
146  { 'file': file_path })
147  print 'Status code: ', headers.get("Dqm-Status-Code", "None")
148  print 'Message: ', headers.get("Dqm-Status-Message", "None")
149  print 'Detail: ', headers.get("Dqm-Status-Detail", "None")
150  print data
151  sys.exit(0)
152 except urllib2.HTTPError, e:
153  print "ERROR", e
154  print 'Status code: ', e.hdrs.get("Dqm-Status-Code", "None")
155  print 'Message: ', e.hdrs.get("Dqm-Status-Message", "None")
156  print 'Detail: ', e.hdrs.get("Dqm-Status-Detail", "None")
157  sys.exit(1)
158 
def filetype(filename)
Definition: visDQMUpload.py:37
def upload(url, args, files)
Definition: visDQMUpload.py:75
def __init__(self, host, args, kwargs)
Definition: visDQMUpload.py:30
def encode(args, files)
Definition: visDQMUpload.py:40
def marshall(args, files, request)
Definition: visDQMUpload.py:63
#define str(s)
def classifyDQMFile(path)
Definition: visDQMUtils.py:29