t2-server 0.6.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rvmrc +1 -0
- data/CHANGES.rdoc +48 -0
- data/LICENCE.rdoc +2 -2
- data/README.rdoc +245 -10
- data/Rakefile +108 -0
- data/bin/t2-delete-runs +21 -34
- data/bin/t2-get-output +134 -0
- data/bin/t2-run-workflow +121 -109
- data/bin/t2-server-admin +128 -0
- data/bin/t2-server-info +25 -38
- data/lib/t2-server-cli.rb +116 -0
- data/lib/t2-server.rb +16 -27
- data/lib/t2-server/admin.rb +147 -0
- data/lib/t2-server/connection-parameters.rb +144 -0
- data/lib/t2-server/connection.rb +352 -0
- data/lib/t2-server/credentials.rb +84 -0
- data/lib/t2-server/exceptions.rb +42 -21
- data/lib/t2-server/port.rb +472 -0
- data/lib/t2-server/run.rb +822 -227
- data/lib/t2-server/server.rb +313 -317
- data/lib/t2-server/util.rb +71 -0
- data/lib/t2-server/xml/libxml.rb +87 -0
- data/lib/t2-server/xml/nokogiri.rb +85 -0
- data/lib/t2-server/xml/rexml.rb +85 -0
- data/lib/t2-server/xml/xml.rb +111 -0
- data/lib/t2server.rb +4 -1
- data/t2-server.gemspec +112 -0
- data/test/tc_admin.rb +63 -0
- data/test/{tc_paths.rb → tc_params.rb} +11 -25
- data/test/tc_perms.rb +132 -0
- data/test/tc_run.rb +200 -67
- data/test/tc_secure.rb +191 -0
- data/test/tc_server.rb +25 -23
- data/test/tc_util.rb +74 -0
- data/test/ts_t2server.rb +57 -12
- data/test/workflows/always_fail.t2flow +69 -0
- data/test/workflows/list_and_value.t2flow +12 -0
- data/test/workflows/list_with_errors.t2flow +107 -0
- data/test/workflows/secure/basic-http.t2flow +74 -0
- data/test/workflows/secure/basic-https.t2flow +74 -0
- data/test/workflows/secure/client-https.t2flow +162 -0
- data/test/workflows/secure/digest-http.t2flow +129 -0
- data/test/workflows/secure/digest-https.t2flow +107 -0
- data/test/workflows/secure/heater-pk.pem +20 -0
- data/test/workflows/secure/user-cert.p12 +0 -0
- data/test/workflows/secure/ws-http.t2flow +180 -0
- data/test/workflows/secure/ws-https.t2flow +180 -0
- data/test/workflows/strings.txt +10 -0
- data/test/workflows/xml_xpath.t2flow +136 -136
- data/version.yml +4 -0
- metadata +132 -34
- data/lib/t2-server/xml.rb +0 -86
@@ -0,0 +1,144 @@
|
|
1
|
+
# Copyright (c) 2010-2012 The University of Manchester, UK.
|
2
|
+
#
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# * Neither the names of The University of Manchester nor the names of its
|
16
|
+
# contributors may be used to endorse or promote products derived from this
|
17
|
+
# software without specific prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
22
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
23
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
24
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
25
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
26
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
27
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
28
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
29
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
#
|
31
|
+
# Author: Robert Haines
|
32
|
+
|
33
|
+
require 'forwardable'
|
34
|
+
|
35
|
+
module T2Server
|
36
|
+
|
37
|
+
# This is the base class for holding parameters for network connections. It
|
38
|
+
# delegates most work to the underlying Hash in which options are actually
|
39
|
+
# stored.
|
40
|
+
#
|
41
|
+
# The parameters that can be set are:
|
42
|
+
# * :ca_file
|
43
|
+
# * :ca_path
|
44
|
+
# * :verify_peer
|
45
|
+
# * :client_certificate
|
46
|
+
# * :client_password
|
47
|
+
# All others will be ignored. Any parameters not set will return +nil+ when
|
48
|
+
# queried.
|
49
|
+
class ConnectionParameters
|
50
|
+
# :stopdoc:
|
51
|
+
ALLOWED_PARAMS = [
|
52
|
+
:ca_file,
|
53
|
+
:ca_path,
|
54
|
+
:verify_peer,
|
55
|
+
:client_certificate,
|
56
|
+
:client_password
|
57
|
+
]
|
58
|
+
# :startdoc:
|
59
|
+
|
60
|
+
extend Forwardable
|
61
|
+
def_delegators :@params, :[], :to_s, :inspect
|
62
|
+
|
63
|
+
# Create a new set of connection parameters with no defaults set.
|
64
|
+
def initialize
|
65
|
+
@params = {}
|
66
|
+
end
|
67
|
+
|
68
|
+
# :call-seq:
|
69
|
+
# [param] = value -> value
|
70
|
+
#
|
71
|
+
# Set a connection parameter. See the list of allowed parameters in the
|
72
|
+
# class description.
|
73
|
+
def []=(param, value)
|
74
|
+
@params[param] = value if ALLOWED_PARAMS.include?(param)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Connection parameters with sensible defaults set for standard connections.
|
79
|
+
# If the connection is over SSL then the peer will be verified using the
|
80
|
+
# underlying OS's certificate store.
|
81
|
+
class DefaultConnectionParameters < ConnectionParameters
|
82
|
+
def initialize
|
83
|
+
super
|
84
|
+
self[:verify_peer] = true
|
85
|
+
self[:ca_path] = "/etc/ssl/certs" # need to get good defaults for Win/OSX
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Connection parameters that specifically turn off peer verification when
|
90
|
+
# using SSL.
|
91
|
+
class InsecureSSLConnectionParameters < ConnectionParameters
|
92
|
+
def initialize
|
93
|
+
super
|
94
|
+
self[:verify_peer] = false
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Connection parameters that simplify setting up verification of servers with
|
99
|
+
# "self-signed" or non-standard certificates.
|
100
|
+
class CustomCASSLConnectionParameters < DefaultConnectionParameters
|
101
|
+
# :call-seq:
|
102
|
+
# new(path) -> CustomCASSLConnectionParameters
|
103
|
+
#
|
104
|
+
# _path_ can either be a directory where the required certificate is stored
|
105
|
+
# or the path to the certificate file itself.
|
106
|
+
def initialize(path)
|
107
|
+
super
|
108
|
+
|
109
|
+
case path
|
110
|
+
when String
|
111
|
+
self[:ca_path] = path if File.directory? path
|
112
|
+
self[:ca_file] = path if File.file? path
|
113
|
+
when File
|
114
|
+
self[:ca_file] = path.path
|
115
|
+
when Dir
|
116
|
+
self[:ca_path] = path.path
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Connection parameters that simplify setting up client authentication to a
|
122
|
+
# server over SSL.
|
123
|
+
class ClientAuthSSLConnectionParameters < DefaultConnectionParameters
|
124
|
+
# :call-seq:
|
125
|
+
# new(certificate, password = nil) -> ClientAuthSSLConnectionParameters
|
126
|
+
#
|
127
|
+
# _certificate_ should point to a file with the client user's certificate
|
128
|
+
# and private key. The key will be unlocked with _password_ if it is
|
129
|
+
# encrypted. If _password_ is not specified, but needed, then the
|
130
|
+
# underlying SSL implementation may ask for it if it can.
|
131
|
+
def initialize(cert, password = nil)
|
132
|
+
super
|
133
|
+
|
134
|
+
case cert
|
135
|
+
when String
|
136
|
+
self[:client_certificate] = cert
|
137
|
+
when File
|
138
|
+
self[:client_certificate] = cert.path
|
139
|
+
end
|
140
|
+
|
141
|
+
self[:client_password] = password
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,352 @@
|
|
1
|
+
# Copyright (c) 2010-2012 The University of Manchester, UK.
|
2
|
+
#
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# * Neither the names of The University of Manchester nor the names of its
|
16
|
+
# contributors may be used to endorse or promote products derived from this
|
17
|
+
# software without specific prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
22
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
23
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
24
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
25
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
26
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
27
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
28
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
29
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
#
|
31
|
+
# Author: Robert Haines
|
32
|
+
|
33
|
+
require 'uri'
|
34
|
+
require 'net/https'
|
35
|
+
|
36
|
+
module T2Server
|
37
|
+
|
38
|
+
# This is a factory for connections to a Taverna Server. It will return
|
39
|
+
# either a http or https connection depending on what sort of uri is passed
|
40
|
+
# into it. This class maintains a list of connections that it knows about
|
41
|
+
# and will return an already established connection if it can.
|
42
|
+
class ConnectionFactory
|
43
|
+
|
44
|
+
private_class_method :new
|
45
|
+
|
46
|
+
# list of connections we know about
|
47
|
+
@@connections = []
|
48
|
+
|
49
|
+
# :call-seq:
|
50
|
+
# ConnectionFactory.connect(uri) -> Connection
|
51
|
+
#
|
52
|
+
# Connect to a Taverna Server instance and return either a
|
53
|
+
# T2Server::HttpConnection or T2Server::HttpsConnection object to
|
54
|
+
# represent it.
|
55
|
+
def ConnectionFactory.connect(uri, params = nil)
|
56
|
+
# we want to use URIs here
|
57
|
+
if !uri.is_a? URI
|
58
|
+
raise URI::InvalidURIError.new
|
59
|
+
end
|
60
|
+
|
61
|
+
# if we're given params they must be of the right type
|
62
|
+
if !params.nil? and !params.is_a? ConnectionParameters
|
63
|
+
raise ArgumentError, "Parameters must be ConnectionParameters", caller
|
64
|
+
end
|
65
|
+
|
66
|
+
# see if we've already got this connection
|
67
|
+
conn = @@connections.find {|c| c.uri == uri}
|
68
|
+
|
69
|
+
if !conn
|
70
|
+
if uri.scheme == "http"
|
71
|
+
conn = HttpConnection.new(uri, params)
|
72
|
+
elsif uri.scheme == "https"
|
73
|
+
conn = HttpsConnection.new(uri, params)
|
74
|
+
else
|
75
|
+
raise URI::InvalidURIError.new
|
76
|
+
end
|
77
|
+
|
78
|
+
@@connections << conn
|
79
|
+
end
|
80
|
+
|
81
|
+
conn
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# A class representing a http connection to a Taverna Server. This class
|
86
|
+
# should only ever be created via the T2Server::Connection factory class.
|
87
|
+
class HttpConnection
|
88
|
+
# The URI of this connection instance.
|
89
|
+
attr_reader :uri
|
90
|
+
|
91
|
+
# Open a http connection to the Taverna Server at the uri supplied.
|
92
|
+
def initialize(uri, params = nil)
|
93
|
+
@uri = uri
|
94
|
+
@params = params || DefaultConnectionParameters.new
|
95
|
+
|
96
|
+
# set up http connection
|
97
|
+
@http = Net::HTTP.new(@uri.host, @uri.port)
|
98
|
+
end
|
99
|
+
|
100
|
+
# :call-seq:
|
101
|
+
# POST_run(path, value, credentials) -> String
|
102
|
+
#
|
103
|
+
# Initialize a T2Server::Run on a server by uploading its workflow.
|
104
|
+
# The new run's identifier (in String form) is returned.
|
105
|
+
def POST_run(path, value, credentials)
|
106
|
+
response = _POST(path, value, "application/xml", credentials)
|
107
|
+
|
108
|
+
case response
|
109
|
+
when Net::HTTPCreated
|
110
|
+
# return the identifier of the newly created run
|
111
|
+
path_leaf_from_uri(response['location'])
|
112
|
+
when Net::HTTPForbidden
|
113
|
+
raise ServerAtCapacityError.new
|
114
|
+
when Net::HTTPUnauthorized
|
115
|
+
raise AuthorizationError.new(credentials)
|
116
|
+
else
|
117
|
+
raise UnexpectedServerResponse.new(response)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# :call-seq:
|
122
|
+
# POST_file(path, value, run, credentials) -> bool
|
123
|
+
#
|
124
|
+
# Upload a file to a run. If successful, true is returned.
|
125
|
+
def POST_file(path, value, run, credentials)
|
126
|
+
response = _POST(path, value, "application/xml", credentials)
|
127
|
+
|
128
|
+
case response
|
129
|
+
when Net::HTTPCreated
|
130
|
+
# OK, carry on...
|
131
|
+
true
|
132
|
+
when Net::HTTPNotFound
|
133
|
+
raise RunNotFoundError.new(run)
|
134
|
+
when Net::HTTPForbidden
|
135
|
+
raise AccessForbiddenError.new("run #{run}")
|
136
|
+
when Net::HTTPUnauthorized
|
137
|
+
raise AuthorizationError.new(credentials)
|
138
|
+
else
|
139
|
+
raise UnexpectedServerResponse.new(response)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# :call-seq:
|
144
|
+
# POST_dir(path, value, run, dir, credentials) -> bool
|
145
|
+
#
|
146
|
+
# Create a directory in the scratch space of a run. If successful, true
|
147
|
+
# is returned.
|
148
|
+
def POST_dir(path, value, run, dir, credentials)
|
149
|
+
response = _POST(path, value, "application/xml", credentials)
|
150
|
+
|
151
|
+
case response
|
152
|
+
when Net::HTTPCreated
|
153
|
+
# OK, carry on...
|
154
|
+
true
|
155
|
+
when Net::HTTPNotFound
|
156
|
+
raise RunNotFoundError.new(run)
|
157
|
+
when Net::HTTPForbidden
|
158
|
+
raise AccessForbiddenError.new("#{dir} on run #{run}")
|
159
|
+
when Net::HTTPUnauthorized
|
160
|
+
raise AuthorizationError.new(credentials)
|
161
|
+
else
|
162
|
+
raise UnexpectedServerResponse.new(response)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# :call-seq:
|
167
|
+
# GET(path, type, range, credentials) -> String
|
168
|
+
#
|
169
|
+
# HTTP GET a resource at _path_ of _type_ from the server. If successful
|
170
|
+
# the body of the response is returned. A portion of the data can be
|
171
|
+
# retrieved by specifying a byte range, start..end, with the _range_
|
172
|
+
# parameter.
|
173
|
+
def GET(path, type, range, credentials)
|
174
|
+
get = Net::HTTP::Get.new(path)
|
175
|
+
get["Accept"] = type
|
176
|
+
get["Range"] = "bytes=#{range.min}-#{range.max}" unless range.nil?
|
177
|
+
response = submit(get, nil, credentials)
|
178
|
+
|
179
|
+
case response
|
180
|
+
when Net::HTTPOK, Net::HTTPPartialContent
|
181
|
+
return response.body
|
182
|
+
when Net::HTTPNoContent
|
183
|
+
return nil
|
184
|
+
when Net::HTTPMovedTemporarily
|
185
|
+
new_conn = redirect(response["location"])
|
186
|
+
raise ConnectionRedirectError.new(new_conn)
|
187
|
+
when Net::HTTPNotFound
|
188
|
+
raise AttributeNotFoundError.new(path)
|
189
|
+
when Net::HTTPForbidden
|
190
|
+
raise AccessForbiddenError.new("attribute #{path}")
|
191
|
+
when Net::HTTPUnauthorized
|
192
|
+
raise AuthorizationError.new(credentials)
|
193
|
+
else
|
194
|
+
raise UnexpectedServerResponse.new(response)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
# :call-seq:
|
199
|
+
# PUT(path, value, type, credentials) -> bool
|
200
|
+
#
|
201
|
+
# Perform a HTTP PUT of _value_ to a path on the server. If successful
|
202
|
+
# true is returned.
|
203
|
+
def PUT(path, value, type, credentials)
|
204
|
+
put = Net::HTTP::Put.new(path)
|
205
|
+
put.content_type = type
|
206
|
+
response = submit(put, value, credentials)
|
207
|
+
|
208
|
+
case response
|
209
|
+
when Net::HTTPOK
|
210
|
+
# OK, so carry on
|
211
|
+
true
|
212
|
+
when Net::HTTPNotFound
|
213
|
+
raise AttributeNotFoundError.new(path)
|
214
|
+
when Net::HTTPForbidden
|
215
|
+
raise AccessForbiddenError.new("attribute #{path}")
|
216
|
+
when Net::HTTPUnauthorized
|
217
|
+
raise AuthorizationError.new(credentials)
|
218
|
+
else
|
219
|
+
raise UnexpectedServerResponse.new(response)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
# :call-seq:
|
224
|
+
# POST(path, value, type, credentials)
|
225
|
+
#
|
226
|
+
# Perform an HTTP POST of _value_ to a path on the server and return the
|
227
|
+
# identifier of the created attribute as a string.
|
228
|
+
def POST(path, value, type, credentials)
|
229
|
+
response = _POST(path, value, type, credentials)
|
230
|
+
|
231
|
+
case response
|
232
|
+
when Net::HTTPCreated
|
233
|
+
# return the identifier of the newly created item
|
234
|
+
path_leaf_from_uri(response['location'])
|
235
|
+
when Net::HTTPNotFound
|
236
|
+
raise AttributeNotFoundError.new(path)
|
237
|
+
when Net::HTTPForbidden
|
238
|
+
raise AccessForbiddenError.new("attribute #{path}")
|
239
|
+
when Net::HTTPUnauthorized
|
240
|
+
raise AuthorizationError.new(credentials)
|
241
|
+
else
|
242
|
+
raise UnexpectedServerResponse.new(response)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
# :call-seq:
|
247
|
+
# DELETE(path, credentials) -> bool
|
248
|
+
#
|
249
|
+
# Perform an HTTP DELETE on a path on the server. If successful true
|
250
|
+
# is returned.
|
251
|
+
def DELETE(path, credentials)
|
252
|
+
run = path.split("/")[-1]
|
253
|
+
delete = Net::HTTP::Delete.new(path)
|
254
|
+
response = submit(delete, nil, credentials)
|
255
|
+
|
256
|
+
case response
|
257
|
+
when Net::HTTPNoContent
|
258
|
+
# Success, carry on...
|
259
|
+
true
|
260
|
+
when Net::HTTPNotFound
|
261
|
+
raise RunNotFoundError.new(run)
|
262
|
+
when Net::HTTPForbidden
|
263
|
+
raise AccessForbiddenError.new("run #{run}")
|
264
|
+
when Net::HTTPUnauthorized
|
265
|
+
raise AuthorizationError.new(credentials)
|
266
|
+
else
|
267
|
+
raise UnexpectedServerResponse.new(response)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
# :call-seq:
|
272
|
+
# OPTIONS(path, credentials) -> Hash
|
273
|
+
#
|
274
|
+
# Perform the HTTP OPTIONS command on the given _path_ and return a hash
|
275
|
+
# of the headers returned.
|
276
|
+
def OPTIONS(path, credentials)
|
277
|
+
options = Net::HTTP::Options.new(path)
|
278
|
+
response = submit(options, nil, credentials)
|
279
|
+
|
280
|
+
case response
|
281
|
+
when Net::HTTPOK
|
282
|
+
response.to_hash
|
283
|
+
when Net::HTTPForbidden
|
284
|
+
raise AccessForbiddenError.new("resource #{path}")
|
285
|
+
when Net::HTTPUnauthorized
|
286
|
+
raise AuthorizationError.new(credentials)
|
287
|
+
else
|
288
|
+
raise UnexpectedServerResponse.new(response)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
private
|
293
|
+
def _POST(path, value, type, credentials)
|
294
|
+
post = Net::HTTP::Post.new(path)
|
295
|
+
post.content_type = type
|
296
|
+
submit(post, value, credentials)
|
297
|
+
end
|
298
|
+
|
299
|
+
def path_leaf_from_uri(uri)
|
300
|
+
URI.parse(uri).path.split('/')[-1]
|
301
|
+
end
|
302
|
+
|
303
|
+
def submit(request, value, credentials)
|
304
|
+
credentials.authenticate(request) unless credentials.nil?
|
305
|
+
|
306
|
+
begin
|
307
|
+
@http.request(request, value)
|
308
|
+
rescue InternalHTTPError => e
|
309
|
+
raise ConnectionError.new(e)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
def redirect(location)
|
314
|
+
uri = URI.parse(location)
|
315
|
+
new_uri = URI::HTTP.new(uri.scheme, nil, uri.host, uri.port, nil,
|
316
|
+
@uri.path, nil, nil, nil);
|
317
|
+
ConnectionFactory.connect(new_uri, @params)
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
# A class representing a https connection to a Taverna Server. This class
|
322
|
+
# should only ever be created via the T2Server::Connection factory class.
|
323
|
+
class HttpsConnection < HttpConnection
|
324
|
+
|
325
|
+
# Open a https connection to the Taverna Server at the uri supplied.
|
326
|
+
def initialize(uri, params = nil)
|
327
|
+
super(uri, params)
|
328
|
+
|
329
|
+
# Configure connection options using params
|
330
|
+
@http.use_ssl = true
|
331
|
+
|
332
|
+
# Peer verification
|
333
|
+
if @params[:verify_peer]
|
334
|
+
if @params[:ca_file]
|
335
|
+
@http.ca_file = @params[:ca_file]
|
336
|
+
else
|
337
|
+
@http.ca_path = @params[:ca_path]
|
338
|
+
end
|
339
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
340
|
+
else
|
341
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
342
|
+
end
|
343
|
+
|
344
|
+
# Client authentication
|
345
|
+
if @params[:client_certificate]
|
346
|
+
pem = File.read(@params[:client_certificate])
|
347
|
+
@http.cert = OpenSSL::X509::Certificate.new(pem)
|
348
|
+
@http.key = OpenSSL::PKey::RSA.new(pem, @params[:client_password])
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|