lib/bubble-wrap/http.rb in bubble-wrap-0.3.1 vs lib/bubble-wrap/http.rb in bubble-wrap-0.4.0
- old
+ new
@@ -1,249 +1,2 @@
-module BubbleWrap
-
- SETTINGS = {}
-
- # The HTTP module provides a simple interface to make HTTP requests.
- #
- # TODO: preflight support, easier/better cookie support, better error handling
- module HTTP
-
- # Make a GET request and process the response asynchronously via a block.
- #
- # @examples
- # # Simple GET request printing the body
- # BubbleWrap::HTTP.get("https://api.github.com/users/mattetti") do |response|
- # p response.body.to_str
- # end
- #
- # # GET request with basic auth credentials
- # BubbleWrap::HTTP.get("https://api.github.com/users/mattetti", {credentials: {username: 'matt', password: 'aimonetti'}}) do |response|
- # p response.body.to_str # prints the response's body
- # end
- #
- def self.get(url, options={}, &block)
- delegator = block_given? ? block : options.delete(:action)
- HTTP::Query.new( url, :get, options.merge({:action => delegator}) )
- end
-
- # Make a POST request
- def self.post(url, options={}, &block)
- delegator = block_given? ? block : options.delete(:action)
- HTTP::Query.new( url, :post, options.merge({:action => delegator}) )
- end
-
- # Make a PUT request
- def self.put(url, options={}, &block)
- delegator = block_given? ? block : options.delete(:action)
- HTTP::Query.new( url, :put, options.merge({:action => delegator}) )
- end
-
- # Make a DELETE request
- def self.delete(url, options={}, &block)
- delegator = block_given? ? block : options.delete(:action)
- HTTP::Query.new( url, :delete, options.merge({:action => delegator}) )
- end
-
- # Make a HEAD request
- def self.head(url, options={}, &block)
- delegator = block_given? ? block : options.delete(:action)
- HTTP::Query.new( url, :head, options.merge({:action => delegator}) )
- end
-
- # Make a PATCH request
- def self.patch(url, options={}, &block)
- delegator = block_given? ? block : options.delete(:action)
- HTTP::Query.new( url, :patch, options.merge({:action => delegator}) )
- end
-
- # Response class wrapping the results of a Query's response
- class Response
- attr_reader :body
- attr_reader :headers
- attr_accessor :status_code, :error_message
- attr_reader :url
-
- def initialize(values={})
- self.update(values)
- end
-
- def update(values)
- values.each do |k,v|
- self.instance_variable_set("@#{k}", v)
- end
- end
-
- def ok?
- status_code.to_s =~ /20\d/ ? true : false
- end
-
- end
-
- # Class wrapping NSConnection and often used indirectly by the BubbleWrap::HTTP module methods.
- class Query
- attr_accessor :request
- attr_accessor :connection
- attr_accessor :credentials # username & password has a hash
- attr_accessor :proxy_credential # credential supplied to proxy servers
- attr_accessor :post_data
- attr_reader :method
-
- attr_reader :response
- attr_reader :status_code
- attr_reader :response_headers
- attr_reader :response_size
- attr_reader :options
-
- # ==== Parameters
- # url<String>:: url of the resource to download
- # http_method<Symbol>:: Value representing the HTTP method to use
- # options<Hash>:: optional options used for the query
- #
- # ==== Options
- # :payload<String> - data to pass to a POST, PUT, DELETE query.
- # :delegator - Proc, class or object to call when the file is downloaded.
- # a proc will receive a Response object while the passed object
- # will receive the handle_query_response method
- # :headers<Hash> - headers send with the request
- # Anything else will be available via the options attribute reader.
- #
- def initialize(url, http_method = :get, options={})
- @method = http_method.upcase.to_s
- @delegator = options.delete(:action) || self
- @payload = options.delete(:payload)
- @credentials = options.delete(:credentials) || {}
- @credentials = {:username => '', :password => ''}.merge(@credentials)
- @timeout = options.delete(:timeout) || 30.0
- headers = options.delete(:headers)
- if headers
- @headers = {}
- headers.each{|k,v| @headers[k] = v.gsub("\n", '\\n') } # escaping LFs
- end
- @cachePolicy = options.delete(:cache_policy) || NSURLRequestUseProtocolCachePolicy
- @options = options
- @response = HTTP::Response.new
- initiate_request(url)
- connection.start
- UIApplication.sharedApplication.networkActivityIndicatorVisible = true
- connection
- end
-
- def generate_get_params(payload, prefix=nil)
- list = []
- payload.each do |k,v|
- if v.is_a?(Hash)
- new_prefix = prefix ? "#{prefix}[#{k.to_s}]" : k.to_s
- param = generate_get_params(v, new_prefix)
- else
- param = prefix ? "#{prefix}[#{k}]=#{v}" : "#{k}=#{v}"
- end
- list << param
- end
- return list.flatten
- end
-
- def initiate_request(url_string)
- # http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/nsrunloop_Class/Reference/Reference.html#//apple_ref/doc/constant_group/Run_Loop_Modes
- # NSConnectionReplyMode
-
- unless @payload.nil?
- if @payload.is_a?(Hash)
- params = generate_get_params(@payload)
- @payload = params.join("&")
- end
- url_string = "#{url_string}?#{@payload}" if @method == "GET"
- end
-
- p "BubbleWrap::HTTP building a NSRequest for #{url_string}" if SETTINGS[:debug]
- @url = NSURL.URLWithString(url_string.stringByAddingPercentEscapesUsingEncoding NSUTF8StringEncoding)
- @request = NSMutableURLRequest.requestWithURL(@url,
- cachePolicy:@cachePolicy,
- timeoutInterval:@timeout)
- @request.setHTTPMethod @method
- @request.setAllHTTPHeaderFields(@headers) if @headers
-
- # @payload needs to be converted to data
- unless @method == "GET" || @payload.nil?
- @payload = @payload.to_s.dataUsingEncoding(NSUTF8StringEncoding)
- @request.setHTTPBody @payload
- end
-
- # NSHTTPCookieStorage.sharedHTTPCookieStorage
-
- @connection = create_connection(request, self)
- @request.instance_variable_set("@done_loading", false)
- def @request.done_loading; @done_loading; end
- def @request.done_loading!; @done_loading = true; end
- end
-
- def connection(connection, didReceiveResponse:response)
- @status_code = response.statusCode
- @response_headers = response.allHeaderFields
- @response_size = response.expectedContentLength.to_f
- end
-
- # This delegate method get called every time a chunk of data is being received
- def connection(connection, didReceiveData:received_data)
- @received_data ||= NSMutableData.new
- @received_data.appendData(received_data)
- end
-
- def connection(connection, willSendRequest:request, redirectResponse:redirect_response)
- p "HTTP redirected #{request.description}" if SETTINGS[:debug]
- new_request = request.mutableCopy
- # new_request.setValue(@credentials.inspect, forHTTPHeaderField:'Authorization') # disabled while we figure this one out
- new_request.setAllHTTPHeaderFields(@headers) if @headers
- @connection.cancel
- @connection = create_connection(new_request, self)
- new_request
- end
-
- def connection(connection, didFailWithError: error)
- UIApplication.sharedApplication.networkActivityIndicatorVisible = false
- @request.done_loading!
- NSLog"HTTP Connection failed #{error.localizedDescription}" if SETTINGS[:debug]
- @response.error_message = error.localizedDescription
- call_delegator_with_response
- end
-
-
- # The transfer is done and everything went well
- def connectionDidFinishLoading(connection)
- UIApplication.sharedApplication.networkActivityIndicatorVisible = false
- @request.done_loading!
- # copy the data in a local var that we will attach to the response object
- response_body = NSData.dataWithData(@received_data) if @received_data
- @response.update(status_code: status_code, body: response_body, headers: response_headers, url: @url)
-
- call_delegator_with_response
- end
-
- def connection(connection, didReceiveAuthenticationChallenge:challenge)
-
- if (challenge.previousFailureCount == 0)
- # by default we are keeping the credential for the entire session
- # Eventually, it would be good to let the user pick one of the 3 possible credential persistence options:
- # NSURLCredentialPersistenceNone,
- # NSURLCredentialPersistenceForSession,
- # NSURLCredentialPersistencePermanent
- p "auth challenged, answered with credentials: #{credentials.inspect}" if SETTINGS[:debug]
- new_credential = NSURLCredential.credentialWithUser(credentials[:username], password:credentials[:password], persistence:NSURLCredentialPersistenceForSession)
- challenge.sender.useCredential(new_credential, forAuthenticationChallenge:challenge)
- else
- challenge.sender.cancelAuthenticationChallenge(challenge)
- p 'Auth Failed :('
- end
- end
-
- def call_delegator_with_response
- if @delegator.respond_to?(:call)
- @delegator.call( @response, self )
- end
- end
-
- # This is a temporary method used for mocking.
- def create_connection(request, delegate)
- NSURLConnection.connectionWithRequest(request, delegate:delegate)
- end
- end
- end
-end
+require File.expand_path('../loader.rb', __FILE__)
+BubbleWrap.require('motion/http.rb')