class Tina4::API
def add_headers(headers)
def add_headers(headers) @headers.merge!(headers) self end
def apply_headers(request, extra_headers)
def apply_headers(request, extra_headers) @headers.merge(extra_headers).each do |key, value| request[key] = value end end
def build_multipart_body(boundary, file_path, field_name, extra_fields)
def build_multipart_body(boundary, file_path, field_name, extra_fields) body = "" extra_fields.each do |key, value| body += "--#{boundary}\r\n" body += "Content-Disposition: form-data; name=\"#{key}\"\r\n\r\n" body += "#{value}\r\n" end filename = File.basename(file_path) body += "--#{boundary}\r\n" body += "Content-Disposition: form-data; name=\"#{field_name}\"; filename=\"#{filename}\"\r\n" body += "Content-Type: application/octet-stream\r\n\r\n" body += File.binread(file_path) body += "\r\n--#{boundary}--\r\n" body end
def build_uri(path, params = {})
def build_uri(path, params = {}) url = "#{@base_url}#{path}" uri = URI.parse(url) unless params.empty? query = URI.encode_www_form(params) uri.query = uri.query ? "#{uri.query}&#{query}" : query end uri end
def delete(path, body: nil)
def delete(path, body: nil) uri = build_uri(path) request = Net::HTTP::Delete.new(uri) request.body = body.is_a?(String) ? body : JSON.generate(body) if body apply_headers(request, {}) execute(uri, request) end
def execute(uri, request)
def execute(uri, request) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = uri.scheme == "https" http.open_timeout = @timeout http.read_timeout = @timeout response = http.request(request) APIResponse.new( status: response.code.to_i, body: response.body, headers: response.to_hash ) rescue StandardError => e APIResponse.new( status: 0, body: "", headers: {}, error: e.message ) end
def get(path, params: {})
def get(path, params: {}) uri = build_uri(path, params) request = Net::HTTP::Get.new(uri) apply_headers(request, {}) execute(uri, request) end
def initialize(base_url, headers: {}, timeout: 30)
def initialize(base_url, headers: {}, timeout: 30) @base_url = base_url.chomp("/") @headers = { "Content-Type" => "application/json", "Accept" => "application/json" }.merge(headers) @timeout = timeout end
def patch(path, body: nil, content_type: "application/json")
def patch(path, body: nil, content_type: "application/json") uri = build_uri(path) request = Net::HTTP::Patch.new(uri) if body request.body = body.is_a?(String) ? body : JSON.generate(body) request["Content-Type"] = content_type end apply_headers(request, {}) execute(uri, request) end
def post(path, body: nil, content_type: "application/json")
def post(path, body: nil, content_type: "application/json") uri = build_uri(path) request = Net::HTTP::Post.new(uri) if body request.body = body.is_a?(String) ? body : JSON.generate(body) request["Content-Type"] = content_type end apply_headers(request, {}) execute(uri, request) end
def put(path, body: nil, content_type: "application/json")
def put(path, body: nil, content_type: "application/json") uri = build_uri(path) request = Net::HTTP::Put.new(uri) if body request.body = body.is_a?(String) ? body : JSON.generate(body) request["Content-Type"] = content_type end apply_headers(request, {}) execute(uri, request) end
def send_request(method = "GET", path = "", body: nil, content_type: "application/json")
def send_request(method = "GET", path = "", body: nil, content_type: "application/json") case method.upcase when "GET" then get(path) when "POST" then post(path, body: body, content_type: content_type) when "PUT" then put(path, body: body, content_type: content_type) when "PATCH" then patch(path, body: body, content_type: content_type) when "DELETE" then delete(path, body: body) else get(path) end end
def set_basic_auth(username, password)
def set_basic_auth(username, password) @headers["Authorization"] = "Basic #{Base64.strict_encode64("#{username}:#{password}")}" self end
def set_bearer_token(token)
def set_bearer_token(token) @headers["Authorization"] = "Bearer #{token}" self end
def upload(path, file_path, field_name: "file", extra_fields: {}, headers: {})
def upload(path, file_path, field_name: "file", extra_fields: {}, headers: {}) uri = build_uri(path) boundary = "----Tina4Boundary#{SecureRandom.hex(16)}" body = build_multipart_body(boundary, file_path, field_name, extra_fields) request = Net::HTTP::Post.new(uri) request.body = body request["Content-Type"] = "multipart/form-data; boundary=#{boundary}" headers.each { |k, v| request[k] = v } execute(uri, request) end