class DeathByCaptcha::Client::HTTP

HTTP client for DeathByCaptcha API.

Public Instance Methods

captcha(captcha_id) click to toggle source

Retrieve information from an uploaded captcha.

@param [Integer] captcha_id Numeric ID of the captcha.

@return [DeathByCaptcha::Captcha] The captcha object.

# File lib/deathbycaptcha/client/http.rb, line 12
def captcha(captcha_id)
  response = perform("captcha/#{captcha_id}")
  DeathByCaptcha::Captcha.new(response)
end
report!(captcha_id) click to toggle source

Report incorrectly solved captcha for refund.

@param [Integer] captcha_id Numeric ID of the captcha.

@return [DeathByCaptcha::Captcha] The captcha object.

# File lib/deathbycaptcha/client/http.rb, line 23
def report!(captcha_id)
  response = perform("captcha/#{captcha_id}/report", :post)
  DeathByCaptcha::Captcha.new(response)
end
status() click to toggle source

Retrieve DeathByCaptcha server status.

@return [DeathByCaptcha::ServerStatus] The server status object.

# File lib/deathbycaptcha/client/http.rb, line 41
def status
  response = perform('status')
  DeathByCaptcha::ServerStatus.new(response)
end
upload(options = {}) click to toggle source

Upload a captcha to DeathByCaptcha.

This method will not return the solution. It's only useful if you want to implement your own “decode” function.

@return [DeathByCaptcha::Captcha] The captcha object (not solved yet).

# File lib/deathbycaptcha/client/http.rb, line 53
def upload(options = {})
  payload = {}
  payload[:captchafile] = "base64:#{options[:raw64]}"
  payload[:type] = options[:type] if options[:type].to_i > 0

  if options[:type].to_i == 3
    banner64 = load_captcha(options[:banner])
    raise DeathByCaptcha::InvalidCaptcha if banner64.to_s.empty?

    payload[:banner] = "base64:#{banner64}"
    payload[:banner_text] = options[:banner_text].to_s

  elsif [4, 5].include? options[:type].to_i
    payload = {
      type: options[:type].to_i,
      token_params: options[:token_params].to_json,
    }
  end

  response = perform('captcha', :post_multipart, payload)
  DeathByCaptcha::Captcha.new(response)
end
user() click to toggle source

Retrieve your user information (which has the current credit balance)

@return [DeathByCaptcha::User] The user object.

# File lib/deathbycaptcha/client/http.rb, line 32
def user
  response = perform('user')
  DeathByCaptcha::User.new(response)
end

Private Instance Methods

perform(action, method = :get, payload = {}) click to toggle source

Perform an HTTP request to the DeathByCaptcha API.

@param [String] action API method name. @param [Symbol] method HTTP method (:get, :post, :post_multipart). @param [Hash] payload Data to be sent through the HTTP request.

@return [Hash] Response from the DeathByCaptcha API.

# File lib/deathbycaptcha/client/http.rb, line 86
def perform(action, method = :get, payload = {})
  payload.merge!(username: self.username, password: self.password)

  headers = { 'User-Agent' => DeathByCaptcha::API_VERSION }

  if method == :post
    uri = URI("http://#{self.hostname}/api/#{action}")
    req = Net::HTTP::Post.new(uri.request_uri, headers)
    req.set_form_data(payload)

  elsif method == :post_multipart
    uri = URI("http://#{self.hostname}/api/#{action}")
    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
    uri = URI("http://#{self.hostname}/api/#{action}?#{URI.encode_www_form(payload)}")
    req = Net::HTTP::Get.new(uri.request_uri, headers)
  end

  res = Net::HTTP.start(uri.hostname, uri.port) do |http|
    http.request(req)
  end

  case res
  when Net::HTTPSuccess, Net::HTTPSeeOther
    Hash[URI.decode_www_form(res.body)]
  when Net::HTTPForbidden
    raise DeathByCaptcha::APIForbidden
  when Net::HTTPBadRequest
    raise DeathByCaptcha::APIBadRequest
  when Net::HTTPRequestEntityTooLarge
    raise DeathByCaptcha::APICaptchaTooLarge
  when Net::HTTPServiceUnavailable
    raise DeathByCaptcha::APIServiceUnavailable
  else
    raise DeathByCaptcha::APIResponseError.new(res.body)
  end
end
prepare_multipart_data(payload) click to toggle source

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

@param [Hash] payload Data to be prepared via a multipart post.

@return [String,String] Boundary and body for the multipart post.

# File lib/deathbycaptcha/client/http.rb, line 133
def 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