lib/streamly_ffi/request.rb in streamly_ffi-0.1.6 vs lib/streamly_ffi/request.rb in streamly_ffi-0.2.0
- old
+ new
@@ -5,159 +5,16 @@
require "singleton"
module StreamlyFFI
class Request
include Singleton
+ include StreamlyFFI::Base
- alias __method__ method
-
- attr_reader :url, :method
-
- # @TODO: Argumenting Checking + Error Handling
def initialize(options={})
- url = options[:url]
- method = options[:method]
-
- @response_body = nil
- @response_header = nil
- @custom_header_handler = nil
- @custom_write_handler = nil
-
- # url should be a string that doesn't suck
- # method should be :post, :get, :put, :delete, :head
- # options should contain any of the following keys:
- # :headers, :response_header_handler, :response_body_handler, :payload (required if method = :post / :put)
-
- case method
- when :get then connection.setopt :HTTPGET, 1
- when :head then connection.setopt :NOBODY, 1
- when :post then connection.setopt :POST, 1
- connection.setopt :POSTFIELDS, options[:payload]
- connection.setopt :POSTFIELDSIZE, options[:payload].size
- when :put then connection.setopt :CUSTOMREQUEST, "PUT"
- connection.setopt :POSTFIELDS, options[:payload]
- connection.setopt :POSTFIELDSIZE, options[:payload].size
- when :delete then connection.setopt :CUSTOMREQUEST, "DELETE"
- # else I WILL CUT YOU
- end
-
- if options[:headers].is_a? Hash and options[:headers].size > 0
- options[:headers].each_pair do |key_and_value|
- request_headers = CurlFFI.slist_append(request_headers, key_and_value.join(": "))
- end
- connection.setopt :HTTPHEADER, request_headers
- end
-
- @custom_header_handler = options[:response_header_handler] if options.has_key?(:response_header_handler)
- @custom_write_handler = options[:response_body_handler] if options.has_key?(:response_body_handler)
-
- default_header_handler
- default_write_handler
-
-
- connection.setopt :ENCODING, "identity, deflate, gzip" unless method == :head
- connection.setopt :URL, url
-
- # Other common options (blame streamly guy)
- connection.setopt :FOLLOWLOCATION, 1
- connection.setopt :MAXREDIRS, 3
- # @TODO: This should be an option
- connection.setopt :SSL_VERIFYPEER, 0
- connection.setopt :SSL_VERIFYHOST, 0
-
- connection.setopt :ERRORBUFFER, error_buffer
-
- return self # I am a terrible hack. I should abandon the singleton
+ self.set_options(options)
end
- def connection
- @connection ||= CurlFFI::Easy.new
- end
-
- def error_buffer
- @error_buffer ||= FFI::MemoryPointer.new(:char, CurlFFI::ERROR_SIZE, :clear)
- end
-
- def request_headers
- @request_headers ||= FFI::MemoryPointer.from_string("")
- end
-
- def response_body
- @response_body ||= ""
- end
-
- def response_header
- @response_header ||= ""
- end
-
- def execute
- status = connection.perform
-
- # @TODO: Intelligent error stuff
-# raise Streamly::Error if status
-
- CurlFFI.slist_free_all(@request_headers) if @request_headers
-
- @connection.reset
- end
-
def self.execute(options={})
- request = new(options)
-
- request.execute
-
- return nil if(options.has_key?(:response_header_handler) or options.has_key?(:response_body_handler))
-
- resp = if(options[:method] == :head && request.response_header.respond_to?(:to_str))
- request.response_header
- elsif(request.response_body.is_a?(String))
- request.response_body
- else
- nil
- end
-
- return resp
+ new(options).execute
end
-
- def default_write_handler
- connection.setopt(:WRITEFUNCTION, FFI::Function.new(:size_t, [:pointer, :size_t, :size_t,], &self.__method__(:write_callback)))
- end
-
- def default_header_handler
- connection.setopt(:HEADERFUNCTION, FFI::Function.new(:size_t, [:pointer, :size_t, :size_t], &self.__method__(:header_callback)))
- end
-
- def write_callback(string_ptr, size, nmemb)
- length = size * nmemb
-
- if(@custom_write_handler)
- @custom_write_handler.call(string_ptr.read_string(length))
- else
- response_body << string_ptr.read_string(length)
- end
-
- return length
- end
-
- def header_callback(string_ptr, size, nmemb)
- length = size * nmemb
-
- if(@custom_header_handler)
- @custom_header_handler.call(string_ptr.read_string(length))
- else
- response_header << string_ptr.read_string(length)
- end
-
- return length
- end
-
- # streamly's .c internal methods:
- # @TODO: header_handler
- # @TODO: data_handler
- # @TODO: each_http_header
- # @TODO: select_error
- # @TODO: rb_streamly_new
- # @TODO: rb_streamly_init
- # @TODO: nogvl_perform
- # @TODO: rb_streamly_execute
end
end
\ No newline at end of file