Class: ZeroCaptcha::HTTP

Inherits:
Object
  • Object
show all
Defined in:
lib/zero_captcha/http.rb

Overview

ZeroCaptcha::HTTP exposes common HTTP routines that can be used by the ZeroCaptcha API client.

Class Method Summary collapse

Class Method Details

.open_url(url) ⇒ String

Retrieve the contents of a captcha URL supporting HTTPS and redirects.

Parameters:

  • url (String)

    The captcha URL.

Returns:

  • (String)

    The contents of the captcha URL.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/zero_captcha/http.rb', line 12

def self.open_url(url)
  uri = URI(url)

  http = Net::HTTP.new(uri.host, uri.port)

  if uri.scheme == 'https'
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  end

  res = http.get(uri.request_uri)

  if (redirect = res.header['location'])
    open_url(redirect)
  else
    res.body
  end
end

.prepare_multipart_data(payload) ⇒ String

Prepare the multipart data to be sent via a :multipart request.

Parameters:

  • payload (Hash)

    Data to be prepared via a multipart post.

Returns:

  • (String, String)

    Boundary and body for the multipart post.



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/zero_captcha/http.rb', line 103

def self.prepare_multipart_data(payload)
  boundary = 'infosimples' + rand(1_000_000).to_s # a random unique string

  content = []
  payload.each do |param, value|
    content << '--' + boundary
    content << "Content-Disposition: form-data; name=\"#{param}\""
    content << ''
    content << value
  end
  content << '--' + boundary + '--'
  content << ''

  [boundary, content.join("\r\n")]
end

.request(options = {}) ⇒ String

Perform an HTTP request with support to multipart requests.

Parameters:

  • options (Hash) (defaults to: {})

    Options hash.

  • options (String) (defaults to: {})

    url URL to be requested.

  • options (Symbol) (defaults to: {})

    method HTTP method (:get, :post, :multipart).

  • options (Hash) (defaults to: {})

    payload Data to be sent through the HTTP request.

  • options (Integer) (defaults to: {})

    timeout HTTP open/read timeout in seconds.

Returns:

  • (String)

    Response body of the HTTP request.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/zero_captcha/http.rb', line 41

def self.request(options = {})
  uri     = URI(options[:url])
  method  = options[:method] || :get
  payload = options[:payload] || {}
  timeout = options[:timeout] || 60
  headers = { 'User-Agent' => ZeroCaptcha::USER_AGENT }

  case method
  when :get
    uri.query = URI.encode_www_form(payload)
    req = Net::HTTP::Get.new(uri.request_uri, headers)

  when :post
    req = Net::HTTP::Post.new(uri.request_uri, headers)
    req.set_form_data(payload)

  when :multipart
    req = Net::HTTP::Post.new(uri.request_uri, headers)
    boundary, body = prepare_multipart_data(payload)
    req.content_type = "multipart/form-data; boundary=#{boundary}"
    req.body = body

  else
    fail ZeroCaptcha::ArgumentError, "Illegal HTTP method (#{method})"
  end

  http = Net::HTTP.new(uri.hostname, uri.port)
  http.use_ssl = true if (uri.scheme == 'https')
  http.open_timeout = timeout
  http.read_timeout = timeout
  res = http.request(req)

  case res
  when Net::HTTPSuccess
    res.body

  when Net::HTTPBadRequest
    fail ZeroCaptcha::APIBadRequest

  when Net::HTTPUnauthorized, Net::HTTPForbidden
    fail ZeroCaptcha::APIForbidden

  when Net::HTTPNotFound
    fail ZeroCaptcha::InvalidCaptchaType

  when Net::HTTPGatewayTimeOut
    fail ZeroCaptcha::Timeout

  else
    fail ZeroCaptcha::APIResponseError, res.body
  end

rescue Net::OpenTimeout, Net::ReadTimeout
  raise ZeroCaptcha::Timeout
end