2015-11-26 5 views
1

Пожалуйста, помогите мне понять, что я делаю неправильно? Мне нужно сделать POST-запрос api из моего приложения rails, я попытался сделать это сначала с помощью gem «faraday», а затем с «net/http». Ответ от сервера тот же. Счет создает, но дает ошибку:Net :: HTTPBadResponse (неправильный формат строки заголовка)

Net::HTTPBadResponse (wrong header line format)

class Connect 
require 'uri' 
require 'net/http' 
require 'net/https' 
require 'faraday' 

def initialize(email, password, account) 
    @base_url = "https://example.com" 
    @client_id = ENV["client_id"] 
    @client_secret = ENV["client_secret"] 
    @email = email 
    @password = password 
    @account = account 
end 

# method with net/http 
def create_account 

    @toSend = { 
    first_name: @account[:first_name], 
    last_name: @account[:last_name], 
    client_id: @client_id, 
    client_secret: @client_secret, 
    email: @email, 
    password: @password 
    }.to_json 

    uri = URI.parse("#{@base_url}/endclient/api/account") 
    https = Net::HTTP.new(uri.host,uri.port) 
    https.use_ssl = true 
    req = Net::HTTP::Post.new(
    uri.path, 
    initheader = { 
        'Content-Type' =>'application/json', 
        'Accept' =>'application/json' 
    } 
) 
    req.body = "#{@toSend}" 
    res = https.request(req) 
end 

# faraday method 
def make_account 

    conn = Faraday.new(:url => "#{@base_url}") do |faraday| 
    faraday.response :logger     
    faraday.adapter Faraday.default_adapter 
    end 

    params = { first_name: @account[:first_name], 
    last_name: @account[:last_name], 
    client_id: @client_id, 
    client_secret: @client_secret, 
    email: @email, 
    password: @password 
    }.to_json 

    response = conn.post do |req| 
    req.url '/endclient/api/account' 
    req.headers['Content-Type'] = 'application/json' 
    req.headers['Accept'] = 'application/json' 
    req.body = params 
    end 
end 
end 

Done этот запрос с успехом через Postman, поэтому конечная точка апи работает.

Пожалуйста, помогите мне понять, что случилось с заголовками? Спасибо заранее!

UPDATE:

Может быть проблема в этом?

Cannot render console with content type application/jsonAllowed content types: [#<Mime::Type:0x00000003661658 @synonyms=["application/xhtml+xml"], @symbol=:html, @string="text/html">, #<Mime::Type:0x00000003660fc8 @synonyms=[], @symbol=:text, @string="text/plain">, #<Mime::Type:0x0000000365ca68 @synonyms=[], @symbol=:url_encoded_form, @string="application/x-www-form-urlencoded">] 
+0

Для вашего метода net/http попробуйте этот 'req.body = @ toSend.to_query' вместо' req.body = "# {@ toSend}" '. сообщите мне, если это сработает. –

+0

@HarryBomrah, спасибо за ваш ответ, я попробовал это, он дает мне ошибку 'ArgumentError (неправильное количество аргументов (0 для 1)' –

+0

Какая строка? У меня что-то изменилось? –

ответ

0

Если вы хотите HTTP LIB, который легко смешивается в классе/модуль, чем я бы рекомендовал httparty над Faraday или просто старым Net::HTTP.

require 'httparty' # Requires go at the top of the file. Not in class body. 

class MyApiClient 
    include HTTParty 
    base_uri 'test.example.com' 
    # Tells Httparty to send JSON for all requests. 
    format :json 

    # @see https://robots.thoughtbot.com/ruby-2-keyword-arguments 
    def initialize(client_id: ENV["client_id"], client_secret: ENV["client_secret"]) 
    @options = { 
     body: { 
     client_id: client_id, 
     client_secret: client_secret 
     } 
    } 
    end 

    # @return [HTTParty::Response] 
    def create_account(first_name:, last_name:, email:, password:) 
    # ActiveSupport method that creates a copy so that we don't 
    # alter the instance options as a side effect. 
    opts = @options.deep_dup 
    opts[:body].merge!(
     email: email, 
     password: password, 
     first_name: first_name, 
     last_name: last_name 
    ) 
    self.class.post('/endclient/api/account', opts) 
    end 
end 

Хорошая вещь, что httparty будет делать всю работу с разбором параметров и из JSON и отправки правильных заголовков. Он также заботится о скучной работе по созданию URI.

Обратите внимание, что метод подпись немного отличается:

client = MyApiClient.new 
response = client.create_account(
    first_name: 'John', 
    last_name: 'Doe', 
    email: '[email protected]', 
    password: 'abcd1234' 
) 
+0

С другой стороны, ваш API, вероятно, не должен принимать идентификатор клиента и секрет по каждому запросу. Клиенты должны сначала аутентифицироваться и торговать за токен, который затем отправляется с каждым запросом. Но как создать аутентификацию на основе токенов, здесь вид из объема. – max

+0

Благодарим вас за ответ. HTTParty - это хорошо. Мы обнаружили ошибку, это были неправильные заголовки от стороннего API nginx. –

0

Существовал проблема на стороне API, неправильные символы в заголовке.

 Смежные вопросы

  • Нет связанных вопросов^_^