class T2Server::HttpConnection

A class representing a http connection to a Taverna Server. This class should only ever be created via the T2Server::Connection factory class.

Attributes

uri[R]

The URI of this connection instance.

Public Class Methods

new(uri, params = nil) click to toggle source

Open a http connection to the Taverna Server at the uri supplied.

    # File lib/t2-server/net/connection.rb
 92 def initialize(uri, params = nil)
 93   @uri = uri
 94   @params = params || DefaultConnectionParameters.new
 95 
 96   # Open a persistent HTTP connection.
 97   @http = Net::HTTP::Persistent.new("Taverna_Server_Ruby_Client")
 98 
 99   # Set timeouts if specified.
100   @http.open_timeout = @params[:open_timeout] if @params[:open_timeout]
101   @http.read_timeout = @params[:read_timeout] if @params[:read_timeout]
102 end

Public Instance Methods

DELETE(uri, credentials) → true or false click to toggle source

Perform an HTTP DELETE on a uri on the server. If successful true is returned.

    # File lib/t2-server/net/connection.rb
204 def DELETE(uri, credentials)
205   delete = Net::HTTP::Delete.new(uri.path)
206 
207   response = submit(delete, uri, credentials)
208 
209   case response
210   when Net::HTTPNoContent
211     # Success, carry on...
212     true
213   else
214     report_error("DELETE", uri.path, response, credentials)
215   end
216 end
GET(uri, type, range, credentials) → string click to toggle source

HTTP GET a resource at uri of type from the server. If successful the body of the response is returned. A portion of the data can be retrieved by specifying a byte range, start..end, with the range parameter.

    # File lib/t2-server/net/connection.rb
111 def GET(uri, type, range, credentials, &block)
112   get = Net::HTTP::Get.new(uri.path)
113   get["Accept"] = type
114   get["Range"] = "bytes=#{range.min}-#{range.max}" unless range.nil?
115 
116   response = submit(get, uri, credentials, &block)
117 
118   case response
119   when Net::HTTPOK, Net::HTTPPartialContent
120     return response.body
121   when Net::HTTPNoContent
122     return nil
123   when Net::HTTPMovedTemporarily
124     new_conn = redirect(response["location"])
125     raise ConnectionRedirectError.new(new_conn)
126   else
127     report_error("GET", uri.path, response, credentials)
128   end
129 end
OPTIONS(uri, credentials) → hash click to toggle source

Perform the HTTP OPTIONS command on the given uri and return a hash of the headers returned.

    # File lib/t2-server/net/connection.rb
223 def OPTIONS(uri, credentials)
224   options = Net::HTTP::Options.new(uri.path)
225 
226   response = submit(options, uri, credentials)
227 
228   case response
229   when Net::HTTPOK
230     response.to_hash
231   else
232     report_error("OPTIONS", uri.path, response, credentials)
233   end
234 end
POST(uri, value, type, credentials) → URI click to toggle source
POST(uri, stream, type, credentials) → URI

Upload data via HTTP POST. Data may be specified as a value or as a stream. The stream can be any object that has a read(length) method; instances of File or IO, for example.

If successful the URI of the uploaded resource is returned.

    # File lib/t2-server/net/connection.rb
180 def POST(uri, data, type, credentials)
181   post = Net::HTTP::Post.new(uri.path)
182   post.content_type = type
183 
184   set_upload_body(post, data)
185 
186   response = submit(post, uri, credentials)
187 
188   case response
189   when Net::HTTPCreated
190     # return the URI of the newly created item
191     URI.parse(response['location'])
192   when Net::HTTPServiceUnavailable
193     raise ServerAtCapacityError.new
194   else
195     report_error("POST", uri.path, response, credentials)
196   end
197 end
PUT(uri, value, type, credentials) → true or false click to toggle source
PUT(uri, value, type, credentials) → URI
PUT(uri, stream, type, credentials) → URI

Upload data via HTTP PUT. Data may be specified as a value or as a stream. The stream can be any object that has a read(length) method; instances of File or IO, for example.

If successful true or a URI to the uploaded resource is returned depending on whether the operation has altered a parameter (true) or uploaded new data (URI).

    # File lib/t2-server/net/connection.rb
143 def PUT(uri, data, type, credentials)
144   put = Net::HTTP::Put.new(uri.path)
145   put.content_type = type
146 
147   set_upload_body(put, data)
148 
149   response = submit(put, uri, credentials)
150 
151   case response
152   when Net::HTTPOK, Net::HTTPAccepted
153     # We've either set a parameter or started a run so we get 200 or 202
154     # back from the server, respectively. Return true to indicate success.
155     true
156   when Net::HTTPCreated
157     # We've uploaded data so we get 201 back from the server. Return the
158     # uri of the created resource.
159     URI.parse(response['location'])
160   when Net::HTTPNoContent
161     # We've modified data so we get 204 back from the server. Return the
162     # uri of the modified resource.
163     uri
164   when Net::HTTPServiceUnavailable
165     raise ServerAtCapacityError.new
166   else
167     report_error("PUT", uri.path, response, credentials)
168   end
169 end

Private Instance Methods

redirect(location) click to toggle source
    # File lib/t2-server/net/connection.rb
289 def redirect(location)
290   uri = URI.parse(location)
291   new_uri = URI::HTTP.new(uri.scheme, nil, uri.host, uri.port, nil,
292     @uri.path, nil, nil, nil);
293   ConnectionFactory.connect(new_uri, @params)
294 end
report_error(method, path, response, credentials) click to toggle source

If one of the expected responses for a HTTP method is not received then handle the error condition here.

    # File lib/t2-server/net/connection.rb
240 def report_error(method, path, response, credentials)
241   case response
242   when Net::HTTPNotFound
243     raise AttributeNotFoundError.new(path)
244   when Net::HTTPForbidden
245     raise AccessForbiddenError.new("resource #{path}")
246   when Net::HTTPUnauthorized
247     raise AuthorizationError.new(credentials)
248   else
249     raise UnexpectedServerResponse.new(method, path, response)
250   end
251 end
set_upload_body(request, data) click to toggle source

If we have a stream then we need to set body_stream and then either supply a content length or set the transfer encoding to “chunked”. A file object can supply its size, a bare IO object cannot. If we have a simple value we can set body directly.

    # File lib/t2-server/net/connection.rb
257 def set_upload_body(request, data)
258   if data.respond_to? :read
259     request.body_stream = data
260     if data.respond_to? :size
261       request.content_length = data.size
262     else
263       request["Transfer-encoding"] = "chunked"
264     end
265   else
266     request.body = data
267   end
268 end
submit(request, uri, credentials, &block) click to toggle source

If a block is passed in here then the response is returned in chunks (streamed). If no block is passed in the whole response is read into memory and returned.

    # File lib/t2-server/net/connection.rb
273 def submit(request, uri, credentials, &block)
274 
275   credentials.authenticate(request) unless credentials.nil?
276 
277   response = nil
278   begin
279     @http.request(uri, request) do |r|
280       r.read_body(&block)
281       response = r
282     end
283     response
284   rescue InternalHTTPError => e
285     raise ConnectionError.new(e)
286   end
287 end