motion/http.rb in bubble-wrap-1.1.5 vs motion/http.rb in bubble-wrap-1.2.0.pre
- old
+ new
@@ -32,10 +32,11 @@
class Response
attr_reader :body
attr_reader :headers
attr_accessor :status_code, :status_description, :error_message
attr_reader :url
+ attr_reader :original_url
def initialize(values={})
self.update(values)
end
@@ -84,10 +85,11 @@
# :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
+ # :cookies<Boolean> - Set whether cookies should be sent with request or not (Default: true)
# Anything else will be available via the options attribute reader.
#
def initialize(url_string, http_method = :get, options={})
@method = http_method.upcase.to_s
@delegator = options.delete(:action) || self
@@ -99,21 +101,24 @@
@timeout = options.delete(:timeout) || 30.0
@headers = escape_line_feeds(options.delete :headers)
@format = options.delete(:format)
@cache_policy = options.delete(:cache_policy) || NSURLRequestUseProtocolCachePolicy
@credential_persistence = options.delete(:credential_persistence) || NSURLCredentialPersistenceForSession
+ @cookies = options.key?(:cookies) ? options.delete(:cookies) : true
@options = options
@response = HTTP::Response.new
+ @follow_urls = options[:follow_urls] || true
@url = create_url(url_string)
@body = create_request_body
@request = create_request
+ @original_url = @url.copy
@connection = create_connection(request, self)
@connection.start
- UIApplication.sharedApplication.networkActivityIndicatorVisible = true
+ UIApplication.sharedApplication.networkActivityIndicatorVisible = true if defined?(UIApplication)
end
def to_s
"#<#{self.class}:#{self.object_id} - Method: #{@method}, url: #{@url.description}, body: #{@body.description}, Payload: #{@payload}, Headers: #{@headers} Credentials: #{@credentials}, Timeout: #{@timeout}, \
Cache policy: #{@cache_policy}, response: #{@response.inspect} >"
@@ -135,27 +140,32 @@
download_progress.call(@received_data.length.to_f, response_size)
end
end
def connection(connection, willSendRequest:request, redirectResponse:redirect_response)
+ # abort early if the user has explicitly disabled redirects
+ if @options[:no_redirect] and redirect_response then
+ return nil
+ end
@redirect_count ||= 0
@redirect_count += 1
log "##{@redirect_count} HTTP redirect_count: #{request.inspect} - #{self.description}"
if @redirect_count >= 30
@response.error_message = "Too many redirections"
@request.done_loading!
call_delegator_with_response
nil
else
+ @url = request.URL if @follow_urls
request
end
end
def connection(connection, didFailWithError: error)
- log "HTTP Connection failed #{error.localizedDescription}"
- UIApplication.sharedApplication.networkActivityIndicatorVisible = false
+ log "HTTP Connection to #{@url.absoluteString} failed #{error.localizedDescription}"
+ UIApplication.sharedApplication.networkActivityIndicatorVisible = false if defined?(UIApplication)
@request.done_loading!
@response.error_message = error.localizedDescription
call_delegator_with_response
end
@@ -164,14 +174,14 @@
upload_progress.call(sending, written, expected)
end
end
def connectionDidFinishLoading(connection)
- UIApplication.sharedApplication.networkActivityIndicatorVisible = false
+ UIApplication.sharedApplication.networkActivityIndicatorVisible = false if defined?(UIApplication)
@request.done_loading!
response_body = NSData.dataWithData(@received_data) if @received_data
- @response.update(status_code: status_code, body: response_body, headers: response_headers, url: @url)
+ @response.update(status_code: status_code, body: response_body, headers: response_headers, url: @url, original_url: @original_url)
call_delegator_with_response
end
def connection(connection, didReceiveAuthenticationChallenge:challenge)
@@ -201,10 +211,11 @@
timeoutInterval:@timeout)
request.setHTTPMethod(@method)
set_content_type
request.setAllHTTPHeaderFields(@headers)
request.setHTTPBody(@body)
+ request.setHTTPShouldHandleCookies(@cookies)
patch_nsurl_request(request)
request
end
@@ -258,30 +269,38 @@
end
def append_form_params(body)
list = process_payload_hash(@payload)
list.each do |key, value|
- form_data = NSMutableData.new
s = "--#{@boundary}\r\n"
s += "Content-Disposition: form-data; name=\"#{key}\"\r\n\r\n"
s += value.to_s
s += "\r\n"
- form_data.appendData(s.dataUsingEncoding NSUTF8StringEncoding)
- body.appendData(form_data)
+ body.appendData(s.dataUsingEncoding NSUTF8StringEncoding)
end
@payload_or_files_were_appended = true
body
end
+ def parse_file(key, value)
+ if value.is_a?(Hash)
+ raise InvalidFileError if value[:data].nil?
+ {data: value[:data], filename: value[:filename] || key}
+ else
+ {data: value, filename: key}
+ end
+ end
+
def append_files(body)
@files.each do |key, value|
- file_data = NSMutableData.new
+ file = parse_file(key, value)
s = "--#{@boundary}\r\n"
- s += "Content-Disposition: form-data; name=\"#{key}\"; filename=\"#{key}\"\r\n"
+ s += "Content-Disposition: form-data; name=\"#{key}\"; filename=\"#{file[:filename]}\"\r\n"
s += "Content-Type: application/octet-stream\r\n\r\n"
+ file_data = NSMutableData.new
file_data.appendData(s.dataUsingEncoding NSUTF8StringEncoding)
- file_data.appendData(value)
+ file_data.appendData(file[:data])
file_data.appendData("\r\n".dataUsingEncoding NSUTF8StringEncoding)
body.appendData(file_data)
end
@payload_or_files_were_appended = true
body
@@ -309,11 +328,11 @@
end
end
def escape(string)
if string
- CFURLCreateStringByAddingPercentEscapes nil, string.to_s, "[]", ";=&,", KCFStringEncodingUTF8
+ CFURLCreateStringByAddingPercentEscapes nil, string.to_s, nil, "!*'();:@&=+$,/?%#[]", KCFStringEncodingUTF8
end
end
def convert_payload_to_url
params_array = process_payload_hash(@payload)
@@ -374,5 +393,6 @@
end
end
end
class InvalidURLError < StandardError; end
+class InvalidFileError < StandardError; end