git-svn-id: https://s3tools.svn.sourceforge.net/svnroot/s3tools/s3cmd/trunk@374 830e0280-6d2a-0410-9c65-932aecc39d9d
Michal Ludvig authored on 2009/02/14 16:01:41... | ... |
@@ -7,6 +7,7 @@ import logging |
7 | 7 |
from logging import debug, info, warning, error |
8 | 8 |
import re |
9 | 9 |
import Progress |
10 |
+from SortedDict import SortedDict |
|
10 | 11 |
|
11 | 12 |
class Config(object): |
12 | 13 |
_instance = None |
... | ... |
@@ -26,6 +27,7 @@ class Config(object): |
26 | 26 |
recv_chunk = 4096 |
27 | 27 |
list_md5 = False |
28 | 28 |
human_readable_sizes = False |
29 |
+ extra_headers = SortedDict() |
|
29 | 30 |
force = False |
30 | 31 |
get_continue = False |
31 | 32 |
skip_existing = False |
... | ... |
@@ -320,7 +320,7 @@ def cmd_object_put(args): |
320 | 320 |
|
321 | 321 |
uri_final = S3Uri(local_list[key]['remote_uri']) |
322 | 322 |
|
323 |
- extra_headers = {} |
|
323 |
+ extra_headers = copy(cfg.extra_headers) |
|
324 | 324 |
full_name_orig = local_list[key]['full_name'] |
325 | 325 |
full_name = full_name_orig |
326 | 326 |
seq_label = "[%d of %d]" % (seq, local_count) |
... | ... |
@@ -518,8 +518,9 @@ def subcmd_cp_mv(args, process_fce, message): |
518 | 518 |
|
519 | 519 |
if dst_uri.object() == "": |
520 | 520 |
dst_uri = S3Uri(dst_uri.uri() + src_uri.object()) |
521 |
- |
|
522 |
- response = process_fce(src_uri, dst_uri) |
|
521 |
+ |
|
522 |
+ extra_headers = copy(cfg.extra_headers) |
|
523 |
+ response = process_fce(src_uri, dst_uri, extra_headers) |
|
523 | 524 |
output(message % { "src" : src_uri, "dst" : dst_uri}) |
524 | 525 |
if Config().acl_public: |
525 | 526 |
output(u"Public URL is: %s" % dst_uri.public_url()) |
... | ... |
@@ -979,12 +980,13 @@ def cmd_sync_local2remote(args): |
979 | 979 |
src = item['full_name'] |
980 | 980 |
uri = S3Uri(item['remote_uri']) |
981 | 981 |
seq_label = "[%d of %d]" % (seq, local_count) |
982 |
- attr_header = None |
|
982 |
+ extra_headers = copy(cfg.extra_headers) |
|
983 | 983 |
if cfg.preserve_attrs: |
984 | 984 |
attr_header = _build_attr_header(src) |
985 |
- debug(attr_header) |
|
985 |
+ debug(u"attr_header: %s" % attr_header) |
|
986 |
+ extra_headers.update(attr_header) |
|
986 | 987 |
try: |
987 |
- response = s3.object_put(src, uri, attr_header, extra_label = seq_label) |
|
988 |
+ response = s3.object_put(src, uri, extra_headers, extra_label = seq_label) |
|
988 | 989 |
except S3UploadError, e: |
989 | 990 |
error(u"%s: upload failed too many times. Skipping that file." % item['full_name_unicode']) |
990 | 991 |
continue |
... | ... |
@@ -1375,6 +1377,8 @@ def main(): |
1375 | 1375 |
optparser.add_option("-m", "--mime-type", dest="default_mime_type", type="mimetype", metavar="MIME/TYPE", help="Default MIME-type to be set for objects stored.") |
1376 | 1376 |
optparser.add_option("-M", "--guess-mime-type", dest="guess_mime_type", action="store_true", help="Guess MIME-type of files by their extension. Falls back to default MIME-Type as specified by --mime-type option") |
1377 | 1377 |
|
1378 |
+ optparser.add_option( "--add-header", dest="add_header", action="append", metavar="NAME:VALUE", help="Add a given HTTP header to the upload request. Can be used multiple times. (only for [put] and [sync] commands).") |
|
1379 |
+ |
|
1378 | 1380 |
optparser.add_option( "--encoding", dest="encoding", metavar="ENCODING", help="Override autodetected terminal and filesystem encoding (character set). Autodetected: %s" % preferred_encoding) |
1379 | 1381 |
|
1380 | 1382 |
optparser.add_option( "--list-md5", dest="list_md5", action="store_true", help="Include MD5 sums in bucket listings (only for 'ls' command).") |
... | ... |
@@ -1446,6 +1450,21 @@ def main(): |
1446 | 1446 |
error(u"Option --progress is not yet supported on MS Windows platform. Assuming --no-progress.") |
1447 | 1447 |
cfg.progress_meter = False |
1448 | 1448 |
|
1449 |
+ ## Pre-process --add-header's and put them to Config.extra_headers SortedDict() |
|
1450 |
+ if options.add_header: |
|
1451 |
+ for hdr in options.add_header: |
|
1452 |
+ try: |
|
1453 |
+ key, val = hdr.split(":", 1) |
|
1454 |
+ except ValueError: |
|
1455 |
+ raise ParameterError("Invalid header format: %s" % hdr) |
|
1456 |
+ key_inval = re.sub("[a-zA-Z0-9-.]", "", key) |
|
1457 |
+ if key_inval: |
|
1458 |
+ key_inval = key_inval.replace(" ", "<space>") |
|
1459 |
+ key_inval = key_inval.replace("\t", "<tab>") |
|
1460 |
+ raise ParameterError("Invalid character(s) in header name '%s': \"%s\"" % (key, key_inval)) |
|
1461 |
+ debug(u"Updating Config.Config extra_headers[%s] -> %s" % (key.strip(), val.strip())) |
|
1462 |
+ cfg.extra_headers[key.strip()] = val.strip() |
|
1463 |
+ |
|
1449 | 1464 |
## Update Config with other parameters |
1450 | 1465 |
for option in cfg.option_list(): |
1451 | 1466 |
try: |
... | ... |
@@ -1530,9 +1549,6 @@ def main(): |
1530 | 1530 |
except S3Error, e: |
1531 | 1531 |
error(u"S3 error: %s" % e) |
1532 | 1532 |
sys.exit(1) |
1533 |
- except ParameterError, e: |
|
1534 |
- error(u"Parameter problem: %s" % e) |
|
1535 |
- sys.exit(1) |
|
1536 | 1533 |
|
1537 | 1534 |
if __name__ == '__main__': |
1538 | 1535 |
try: |
... | ... |
@@ -1552,6 +1568,10 @@ if __name__ == '__main__': |
1552 | 1552 |
main() |
1553 | 1553 |
sys.exit(0) |
1554 | 1554 |
|
1555 |
+ except ParameterError, e: |
|
1556 |
+ error(u"Parameter problem: %s" % e) |
|
1557 |
+ sys.exit(1) |
|
1558 |
+ |
|
1555 | 1559 |
except SystemExit, e: |
1556 | 1560 |
sys.exit(e.code) |
1557 | 1561 |
|