-
Notifications
You must be signed in to change notification settings - Fork 35
/
S3_s3sync_mod.rb
143 lines (125 loc) · 5.4 KB
/
S3_s3sync_mod.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# This software code is made available "AS IS" without warranties of any
# kind. You may copy, display, modify and redistribute the software
# code either by itself or as incorporated into your code; provided that
# you do not remove any proprietary notices. Your use of this software
# code is at your own risk and you waive any claim against Amazon
# Digital Services, Inc. or its affiliates with respect to your use of
# this software code. (c) 2006 Amazon Digital Services, Inc. or its
# affiliates.
#
# This software code is made available "AS IS" without warranties of any
# kind. You may copy, display, modify and redistribute the software
# code either by itself or as incorporated into your code; provided that
# you do not remove any proprietary notices. Your use of this software
# code is at your own risk and you waive any claim against the author
# with respect to your use of this software code.
# (c) 2007 s3sync.net
#
require 'S3'
require 'HTTPStreaming'
# The purpose of this file is to overlay the S3 library from AWS
# to add some functionality
# (without changing the file itself or requiring a specific version)
# It still isn't perfectly robust, i.e. if radical changes are made
# to the underlying lib this stuff will need updating.
module S3
class AWSAuthConnection
def make_http(bucket='', host='', proxy_host=nil, proxy_port=nil, proxy_user=nil, proxy_pass=nil)
# build the domain based on the calling format
server = ''
if host != ''
server = host
elsif bucket.empty?
# for a bucketless request (i.e. list all buckets)
# revert to regular domain case since this operation
# does not make sense for vanity domains
server = @server
elsif @calling_format == CallingFormat::SUBDOMAIN
server = "#{bucket}.#{@server}"
elsif @calling_format == CallingFormat::VANITY
server = bucket
else
server = @server
end
# automatically does the right thing when no proxy
http = Net::HTTP::Proxy(proxy_host, proxy_port, proxy_user, proxy_pass).new(server, @port)
#http = Net::HTTP.new(server, @port)
http.use_ssl = @is_secure
http.verify_mode=@verify_mode
http.ca_file=@ca_file
http.ca_path=@ca_path
http.start
return http
end
# add support for streaming the response body to an IO stream
alias __make_request__ make_request
def make_request(method, bucket='', key='', path_args={}, headers={}, data='', metadata={}, streamOut=nil)
# build the path based on the calling format
path = ''
if (not bucket.empty?) and (@calling_format == CallingFormat::REGULAR)
path << "/#{bucket}"
end
# add the slash after the bucket regardless
# the key will be appended if it is non-empty
path << "/#{key}"
# build the path_argument string
# add the ? in all cases since
# signature and credentials follow path args
path << '?'
path << S3.path_args_hash_to_string(path_args)
req = method_to_request_class(method).new("#{path}")
set_headers(req, headers)
set_headers(req, metadata, METADATA_PREFIX)
set_headers(req, {'Connection' => 'keep-alive', 'Keep-Alive' => '300'})
set_aws_auth_header(req, @aws_access_key_id, @aws_secret_access_key, bucket, key, path_args)
http = $S3syncHttp
if req.request_body_permitted?
return http.request(req, data, streamOut)
else
return http.request(req, nil, streamOut)
end
end
# a "get" operation that sends the body to an IO stream
def get_stream(bucket, key, headers={}, streamOut=nil)
return GetResponse.new(make_request('GET', bucket, CGI::escape(key), {}, headers, '', {}, streamOut))
end
# a "get" operation that sends the body to an IO stream
def get_query_stream(bucket, key, path_args={}, headers={}, streamOut=nil)
return GetResponse.new(make_request('GET', bucket, CGI::escape(key), path_args, headers, '', {}, streamOut))
end
def head(bucket, key=nil, headers={})
return GetResponse.new(make_request('HEAD', bucket, CGI::escape(key), {}, headers, '', {}))
end
undef create_bucket
def create_bucket(bucket, object)
object = S3Object.new(object) if not object.instance_of? S3Object
return Response.new(
make_request('PUT', bucket, '', {}, {}, object.data, object.metadata)
)
end
# no, because internally the library does not support the header,wait,body paradigm, so this is useless
#alias __put__ put
#def put(bucket, key, object, headers={})
# headers['Expect'] = "100-continue"
# __put__(bucket, key, object, headers)
#end
# allow ssl validation
attr_accessor :verify_mode
attr_accessor :ca_path
attr_accessor :ca_file
end
module CallingFormat
def CallingFormat.string_to_format(s)
case s
when 'REGULAR'
return CallingFormat::REGULAR
when 'SUBDOMAIN'
return CallingFormat::SUBDOMAIN
when 'VANITY'
return CallingFormat::VANITY
else
raise "Unsupported calling format #{s}"
end
end
end
end