Class: Patron::Session

Inherits:
Object
  • Object
show all
Defined in:
lib/patron/session.rb,
ext/patron/session_ext.c

Overview

This class represents multiple request/response transactions with an HTTP server. This is the primary API for Patron.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = {}, &block) ⇒ Session

Create a new Session object.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/patron/session.rb', line 93

def initialize(args = {}, &block)

  # Allows accessors to be set via constructor hash. Ex:  {:base_url => 'www.home.com'}
  args.each do |attribute, value|
    send("#{attribute}=", value)
  end

  # Allows accessors to be set via block.
  if block_given?
    yield self
  end

  @headers ||= {}
  @timeout ||= 5
  @connect_timeout ||= 1
  @max_redirects ||= 5
  @auth_type ||= :basic
  @force_ipv4 ||= false
end

Instance Attribute Details

#auth_typeObject

Set the authentication type for the request.

See Also:

  • Request#auth_type


66
67
68
# File 'lib/patron/session.rb', line 66

def auth_type
  @auth_type
end

#base_urlObject

Prepended to the URL in all requests.



50
51
52
# File 'lib/patron/session.rb', line 50

def base_url
  @base_url
end

#buffer_sizeObject

Set the buffer size for this request. This option will only be set if buffer_size is non-nil



82
83
84
# File 'lib/patron/session.rb', line 82

def buffer_size
  @buffer_size
end

#cacertObject

What cacert file should this session use to verify SSL certificates?



75
76
77
# File 'lib/patron/session.rb', line 75

def cacert
  @cacert
end

#connect_timeoutObject

HTTP connection timeout in seconds. Defaults to 1 second.



40
41
42
# File 'lib/patron/session.rb', line 40

def connect_timeout
  @connect_timeout
end

#default_response_charsetObject

Default encoding of responses. Used if no charset is provided by the host.



85
86
87
# File 'lib/patron/session.rb', line 85

def default_response_charset
  @default_response_charset
end

#force_ipv4Object

Force curl to use IPv4



88
89
90
# File 'lib/patron/session.rb', line 88

def force_ipv4
  @force_ipv4
end

#headersObject

Standard set of headers that are used in all requests.



62
63
64
# File 'lib/patron/session.rb', line 62

def headers
  @headers
end

#ignore_content_lengthObject

Does this session ignore Content-Size headers?



78
79
80
# File 'lib/patron/session.rb', line 78

def ignore_content_length
  @ignore_content_length
end

#insecureObject

Does this session stricly verify SSL certificates?



69
70
71
# File 'lib/patron/session.rb', line 69

def insecure
  @insecure
end

#max_redirectsObject

Maximum number of times to follow redirects. Set to 0 to disable and -1 to follow all redirects. Defaults to 5.



47
48
49
# File 'lib/patron/session.rb', line 47

def max_redirects
  @max_redirects
end

#passwordObject

Username and password for http authentication



53
54
55
# File 'lib/patron/session.rb', line 53

def password
  @password
end

#proxyObject

Proxy URL in cURL format (‘hostname:8080’)



56
57
58
# File 'lib/patron/session.rb', line 56

def proxy
  @proxy
end

#proxy_typeObject

Proxy type (default is HTTP), see constants under ProxyType for supported types.



59
60
61
# File 'lib/patron/session.rb', line 59

def proxy_type
  @proxy_type
end

#ssl_versionObject

Specifies the ssl version



72
73
74
# File 'lib/patron/session.rb', line 72

def ssl_version
  @ssl_version
end

#timeoutObject

HTTP transaction timeout in seconds. Defaults to 5 seconds.



43
44
45
# File 'lib/patron/session.rb', line 43

def timeout
  @timeout
end

#usernameObject

Username and password for http authentication



53
54
55
# File 'lib/patron/session.rb', line 53

def username
  @username
end

Instance Method Details

#build_request(action, url, headers, options = {}) ⇒ Object

Build a request object that can be used in handle_request



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/patron/session.rb', line 220

def build_request(action, url, headers, options = {})
  # If the Expect header isn't set uploads are really slow
  headers['Expect'] ||= ''

  Request.new.tap do |req|
    req.action                 = action
    req.headers                = self.headers.merge headers
    req.timeout                = options.fetch :timeout,               self.timeout
    req.connect_timeout        = options.fetch :connect_timeout,       self.connect_timeout
    req.force_ipv4             = options.fetch :force_ipv4,            self.force_ipv4
    req.max_redirects          = options.fetch :max_redirects,         self.max_redirects
    req.username               = options.fetch :username,              self.username
    req.password               = options.fetch :password,              self.password
    req.proxy                  = options.fetch :proxy,                 self.proxy
    req.proxy_type             = options.fetch :proxy_type,            self.proxy_type
    req.auth_type              = options.fetch :auth_type,             self.auth_type
    req.insecure               = options.fetch :insecure,              self.insecure
    req.ssl_version            = options.fetch :ssl_version,           self.ssl_version
    req.cacert                 = options.fetch :cacert,                self.cacert
    req.ignore_content_length  = options.fetch :ignore_content_length, self.ignore_content_length
    req.buffer_size            = options.fetch :buffer_size,           self.buffer_size
    req.multipart              = options[:multipart]
    req.upload_data            = options[:data]
    req.file_name              = options[:file]

    base_url = self.base_url.to_s
    url = url.to_s
    raise ArgumentError, "Empty URL" if base_url.empty? && url.empty?
    uri = URI.parse(base_url.empty? ? url : File.join(base_url, url))
    query = uri.query.to_s.split('&')
    query += options[:query].is_a?(Hash) ? Util.build_query_pairs_from_hash(options[:query]) : options[:query].to_s.split('&')
    uri.query = query.join('&')
    uri.query = nil if uri.query.empty?
    url = uri.to_s
    req.url = url
  end
end

#copy(url, dest, headers = {}) ⇒ Object

Sends a WebDAV COPY request to the specified url.



204
205
206
207
# File 'lib/patron/session.rb', line 204

def copy(url, dest, headers = {})
  headers['Destination'] = dest
  request(:copy, url, headers)
end

#delete(url, headers = {}) ⇒ Object

As #get but sends an HTTP DELETE request. Notice: this method doesn’t accept any data argument: if you need to send data with a delete request, please, use the #request method.



164
165
166
# File 'lib/patron/session.rb', line 164

def delete(url, headers = {})
  request(:delete, url, headers)
end

Turn on cookie handling for this session, storing them in memory by default or in file if specified. The file must be readable and writable. Calling multiple times will add more files.



711
712
713
714
715
716
717
718
719
720
721
722
723
# File 'ext/patron/session_ext.c', line 711

static VALUE enable_cookie_session(VALUE self, VALUE file) {
  struct curl_state *state = get_curl_state(self);
  CURL* curl = state->handle;
  char* file_path = NULL;

  file_path = RSTRING_PTR(file);
  if (file_path != NULL && strlen(file_path) != 0) {
    curl_easy_setopt(curl, CURLOPT_COOKIEJAR, file_path);
  }
  curl_easy_setopt(curl, CURLOPT_COOKIEFILE, file_path);

  return self;
}

#enable_debug(file = nil) ⇒ Object

Enable debug output to stderr or to specified file.



131
132
133
# File 'lib/patron/session.rb', line 131

def enable_debug(file = nil)
  set_debug_file(file.to_s)
end

#escape(string) ⇒ Object Also known as: urlencode

URL escapes the provided string.



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'ext/patron/session_ext.c', line 225

static VALUE session_escape(VALUE self, VALUE value) {
  struct curl_state *state = get_curl_state(self);
  VALUE string = StringValue(value);
  char* escaped = NULL;
  VALUE retval = Qnil;

  escaped = curl_easy_escape(state->handle,
                             RSTRING_PTR(string),
                             (int) RSTRING_LEN(string));

  retval = rb_str_new2(escaped);
  curl_free(escaped);

  return retval;
}

#get(url, headers = {}) ⇒ Object

Retrieve the contents of the specified url optionally sending the specified headers. If the base_url varaible is set then it is prepended to the url parameter. Any custom headers are merged with the contents of the headers instance variable. The results are returned in a Response object. Notice: this method doesn’t accept any data argument: if you need to send data with a get request, please, use the #request method.



146
147
148
# File 'lib/patron/session.rb', line 146

def get(url, headers = {})
  request(:get, url, headers)
end

#get_file(url, filename, headers = {}) ⇒ Object

Retrieve the contents of the specified url as with #get, but the content at the URL is downloaded directly into the specified file.



152
153
154
# File 'lib/patron/session.rb', line 152

def get_file(url, filename, headers = {})
  request(:get, url, headers, :file => filename)
end

#handle_cookies(file = nil) ⇒ Object

Turn on cookie handling for this session, storing them in memory by default or in file if specified. The file must be readable and writable. Calling multiple times will add more files.



116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/patron/session.rb', line 116

def handle_cookies(file = nil)
  if file
    path = Pathname(file).expand_path
    unless File.exists?(file) and File.writable?(path.dirname)
      raise ArgumentError, "Can't create file #{path} (permission error)"
    end
    unless File.readable?(file) or File.writable?(path)
      raise ArgumentError, "Can't read or write file #{path} (permission error)"
    end
  end
  enable_cookie_session(path.to_s)
  self
end

#handle_request(request) ⇒ Object

Peform the actual HTTP request by calling libcurl. Each filed in the request object will be used to set the appropriate option on the libcurl library. After the request completes, a Response object will be created and returned.

In the event of an error in the libcurl library, a Ruby exception will be created and raised. The exception will return the libcurl error code and error message.



667
668
669
670
# File 'ext/patron/session_ext.c', line 667

static VALUE session_handle_request(VALUE self, VALUE request) {
  set_options_from_request(self, request);
  return rb_ensure(&perform_request, self, &cleanup, self);
}

#head(url, headers = {}) ⇒ Object

As #get but sends an HTTP HEAD request.



157
158
159
# File 'lib/patron/session.rb', line 157

def head(url, headers = {})
  request(:head, url, headers)
end

#interruptObject

Interrupt any currently executing request. This will cause the current request to error and raise an exception.



698
699
700
701
702
# File 'ext/patron/session_ext.c', line 698

static VALUE session_interrupt(VALUE self) {
  struct curl_state *state = get_curl_state(self);
  state->interrupt = 1;
  return self;
}

#post(url, data, headers = {}) ⇒ Object

Uploads the passed data to the specified url using HTTP POST. data can be a string or a hash.



181
182
183
184
185
186
187
# File 'lib/patron/session.rb', line 181

def post(url, data, headers = {})
  if data.is_a?(Hash)
    data = data.map {|k,v| urlencode(k.to_s) + '=' + urlencode(v.to_s) }.join('&')
    headers['Content-Type'] = 'application/x-www-form-urlencoded'
  end
  request(:post, url, headers, :data => data)
end

#post_file(url, filename, headers = {}) ⇒ Object

Uploads the contents of a file to the specified url using HTTP POST.



190
191
192
# File 'lib/patron/session.rb', line 190

def post_file(url, filename, headers = {})
  request(:post, url, headers, :file => filename)
end

#post_multipart(url, data, filename, headers = {}) ⇒ Object

Uploads the contents of a file and data to the specified url using HTTP POST.



195
196
197
# File 'lib/patron/session.rb', line 195

def post_multipart(url, data, filename, headers = {})
  request(:post, url, headers, {:data => data, :file => filename, :multipart => true})
end

#put(url, data, headers = {}) ⇒ Object

Uploads the passed data to the specified url using HTTP PUT. data must be a string.



170
171
172
# File 'lib/patron/session.rb', line 170

def put(url, data, headers = {})
  request(:put, url, headers, :data => data)
end

#put_file(url, filename, headers = {}) ⇒ Object

Uploads the contents of a file to the specified url using HTTP PUT.



175
176
177
# File 'lib/patron/session.rb', line 175

def put_file(url, filename, headers = {})
  request(:put, url, headers, :file => filename)
end

#request(action, url, headers, options = {}) ⇒ Object

Send an HTTP request to the specified url.



214
215
216
217
# File 'lib/patron/session.rb', line 214

def request(action, url, headers, options = {})
  req = build_request(action, url, headers, options)
  handle_request(req)
end

#resetObject

Reset the underlying cURL session. This effectively closes all open connections and disables debug output.



678
679
680
681
682
683
684
685
686
687
688
689
690
# File 'ext/patron/session_ext.c', line 678

static VALUE session_reset(VALUE self) {
  struct curl_state *state;
  Data_Get_Struct(self, struct curl_state, state);

  if (NULL != state->handle) {
    cleanup(self);
    curl_easy_cleanup(state->handle);
    state->handle = NULL;
    session_close_debug_file(state);
  }

  return self;
}

#set_debug_file(file) ⇒ Object

Enable debug output to stderr or to specified file.



730
731
732
733
734
735
736
737
738
739
740
741
742
743
# File 'ext/patron/session_ext.c', line 730

static VALUE set_debug_file(VALUE self, VALUE file) {
  struct curl_state *state = get_curl_state(self);
  char* file_path = RSTRING_PTR(file);

  session_close_debug_file(state);

  if(file_path != NULL && strlen(file_path) != 0) {
    state->debug_file = open_file(file, "wb");
  } else {
    state->debug_file = stderr;
  }

  return self;
}

#unescape(string) ⇒ Object Also known as: urldecode

Unescapes the provided string.



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'ext/patron/session_ext.c', line 246

static VALUE session_unescape(VALUE self, VALUE value) {
  struct curl_state *state = get_curl_state(self);
  VALUE string = StringValue(value);
  char* unescaped = NULL;
  VALUE retval = Qnil;

  unescaped = curl_easy_unescape(state->handle,
                                 RSTRING_PTR(string),
                                 (int) RSTRING_LEN(string),
                                 NULL);

  retval = rb_str_new2(unescaped);
  curl_free(unescaped);

  return retval;
}