104 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Ruby
		
	
	
	
		
		
			
		
	
	
			104 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Ruby
		
	
	
	
|  | # | ||
|  | # Copyright (c) 2015 Rick Olson | ||
|  | # | ||
|  | # Permission is hereby granted, free of charge, to any person obtaining a copy | ||
|  | # of this software and associated documentation files (the "Software"), to deal | ||
|  | # in the Software without restriction, including without limitation the rights | ||
|  | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
|  | # copies of the Software, and to permit persons to whom the Software is | ||
|  | # furnished to do so, subject to the following conditions: | ||
|  | # | ||
|  | # The above copyright notice and this permission notice shall be included in all | ||
|  | # copies or substantial portions of the Software. | ||
|  | # | ||
|  | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
|  | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
|  | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
|  | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
|  | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
|  | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
|  | # SOFTWARE. | ||
|  | # | ||
|  | require 'hurley' | ||
|  | require 'hurley/client' | ||
|  | require 'hurley/connection' | ||
|  | require 'net/https' | ||
|  | 
 | ||
|  | # Temporary monkey patch for streaming downloads. These are fixed in HEAD, | ||
|  | # but pending a 0.3 release. | ||
|  | if Hurley::VERSION == '0.2' | ||
|  |   module Hurley | ||
|  |     class Response | ||
|  |       def location | ||
|  |         @location ||= begin | ||
|  |           return unless loc = @header[:location] | ||
|  |           verb = STATUS_FORCE_GET.include?(status_code) ? :get : request.verb | ||
|  |           statuses, receiver = request.send(:body_receiver) | ||
|  |           new_request = Request.new(verb, request.url.join(Url.parse(loc)), request.header, request.body, request.options, request.ssl_options) | ||
|  |           new_request.on_body(*statuses, &receiver) unless receiver.is_a?(Hurley::BodyReceiver) | ||
|  |           new_request | ||
|  |         end | ||
|  |       end | ||
|  |     end | ||
|  | 
 | ||
|  |     class Connection | ||
|  |       def call(request) | ||
|  |         net_http_connection(request) do |http| | ||
|  |           begin | ||
|  |             Response.new(request) do |res| | ||
|  |               perform_request(http, request, res) | ||
|  | 
 | ||
|  |               # net/http only raises exception on 407 with ssl...? | ||
|  |               if res.status_code == 407
 | ||
|  |                 raise ConnectionFailed, %(407 "Proxy Authentication Required") | ||
|  |               end | ||
|  |             end | ||
|  |           rescue *NET_HTTP_EXCEPTIONS => err | ||
|  |             if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err | ||
|  |               raise SSLError, err | ||
|  |             else | ||
|  |               raise ConnectionFailed, err | ||
|  |             end | ||
|  |           end | ||
|  |         end | ||
|  | 
 | ||
|  |       rescue ::Timeout::Error => err | ||
|  |         raise Timeout, err | ||
|  |       end | ||
|  | 
 | ||
|  |       private | ||
|  | 
 | ||
|  |       def net_http_request(request) | ||
|  |         http_req = Net::HTTPGenericRequest.new( | ||
|  |           request.verb.to_s.upcase, # request method | ||
|  |           !!request.body,           # is there a request body | ||
|  |           :head != request.verb,    # is there a response body | ||
|  |           request.url.request_uri,  # request uri path | ||
|  |           request.header,           # request headers | ||
|  |         ) | ||
|  | 
 | ||
|  |         if body = request.body_io | ||
|  |           http_req.body_stream = body | ||
|  |         end | ||
|  | 
 | ||
|  |         http_req | ||
|  |       end | ||
|  | 
 | ||
|  |       def perform_request(http, request, res) | ||
|  |         http.request(net_http_request(request)) do |http_res| | ||
|  |           res.status_code = http_res.code.to_i | ||
|  |           http_res.each_header do |key, value| | ||
|  |             res.header[key] = value | ||
|  |           end | ||
|  | 
 | ||
|  |           if :get == request.verb | ||
|  |             http_res.read_body { |chunk| res.receive_body(chunk) } | ||
|  |           else | ||
|  |             res.receive_body(http_res.body) | ||
|  |           end | ||
|  |         end | ||
|  |       end | ||
|  |     end | ||
|  |   end | ||
|  | end |