Jim

Jim

Help with HTTPoison POST

As a follow up to my earlier question:

I have the code compiling and running but not getting a successful login from the rest server. If I use cURL all is good, but my code reports a success code of 200, so the call executed correctly, but a failed login.

It seems to me that the parameters are the same, so I can’t figure out what is wrong. A successful login returns:

{
“return_code”: 1,
“session”: “nlvpneu7jgk2t4nvrus9hi4bp6”,
“uid”: “804276”,
“username”: “me@example.com
}

But I get the return for a failed login:

{“return_code”:0}

I’ll paste the cURL and my code, if someone sees the issue and can help me I would greatly appreciate the help.

Here is the cURL:

curl -X POST
SimpliSafe Control Panel
-H ‘Cache-Control: no-cache’
-H ‘Content-Type: application/x-www-form-urlencoded’
-d ‘name=user%example.com&pass=mypass&device_name=my_iphone&device_uuid=51644e80-1b62-11e3-b773-0800200c9a66&version=1200&no_persist=1&XDEBUG_SESSION_START=session_name’

Here is my code:

defmodule Simplisafe.SsFreeze do
@user_agent [ { “User-agent”, “Elixir” } ]

def fetch(user, password) do
ss_url()
|> ss_login(user, password)
|> handle_response
end

defp ss_url do
SimpliSafe Control Panel
end

defp handle_response({ :ok, %{status_code: 200, body: body}}) do
{ :ok, body }
end

defp handle_response({ :error, %{status_code: sc, body: body}}) do
{ :error, sc, body }
end

defp handle_response({ ec, %{status_code: sc, body: body}}) do
{ ec, sc, body }
end

def post_body(user, password) do
%{“name” => user,
“pass” => password,
“device_name” => “my_iphone”,
“device_uuid” => “51644e80-1b62-11e3-b773-0800200c9a66”,
“version” => “1200”,
“no_persist” => “1”,
“XDEBUG_SESSION_START” => “session_name”,
} |> Poison.encode!
end

def ss_login(user, password) do
HTTPoison.post(ss_url(), post_body(user, password),
%{“Content-Type” => “application/x-www-form-urlencoded”, “Cache-Control” => “no-cache”})
end

def ss_login(url, user, password) do
HTTPoison.post(url, post_body(user, password), %{“Content-Type” => “application/x-www-form-urlencoded”, “Cache-Control” => “no-cache”})
end
end

Most Liked

Aetherus

Aetherus

According to your curl example, the request should be sent with “application/x-www-form-urlencoded” format. You can try URI.encode_query/1 to encode a map or a keyword list to that format, for example,

req_body = URI.encode_query(%{"name" => "who am i", "pass" => "$3cret"})
HTTPoison.post(
  "http://www.example.com/login",
  req_body,
  %{"Content-Type" => "application/x-www-form-urlencoded"}
)
10
Post #4
Aetherus

Aetherus

No, it doesn’t. Here is the HTTP client module I wrote for a scraper, with HTTPoison for sending requests, and Floki for HTML parsing:

defmodule EkangScraper.HttpClient do
  alias EkangScraper.CookieStore

  def request_raw(method, url, params) do
    payload = URI.encode_query(params)
    cookies = Agent.get(CookieStore, &(&1)) || []
    try do
      response = case method do
        method when method in [:get, :delete] -> 
          real_url = url <> "?" <> payload
          apply(HTTPoison, :"#{method}!", [
            real_url, 
            %{},
            [hackney: [cookie: cookies]]])
        _ ->
          apply(HTTPoison, :"#{method}!", [
            url, 
            payload, 
            %{"Content-Type" => "application/x-www-form-urlencoded; charset=utf-8"},
            [hackney: [cookie: cookies]]])
      end

      case response.status_code do
        code when code >= 200 and code < 400 ->
          Agent.update(CookieStore, &(cookies(response) || &1))
          response.body
        code -> raise """
          Oops! #{code}
            URL: #{url}
            Method: #{method}
            Params: #{inspect params}
            Cookies: #{inspect cookies}
        """
      end
    rescue
      e in HTTPoison.Error ->
        raise """
          Oops! #{e.reason}!
            URL: #{url}
            Method: #{method}
            Params: #{inspect params}
            Cookies: #{inspect cookies}
        """
    end
  end

  def request(method, url, params) do
    request_raw(method, url, params)
    |> Floki.parse()
  end

  for method <- [:get, :post, :patch, :put, :delete] do
    def unquote(:"#{method}_raw")(url, params \\ %{}) do
      request_raw(unquote(method), url, params)
    end

    def unquote(method)(url, params \\ %{}) do
      request(unquote(method), url, params)
    end
  end

  defp cookies(%HTTPoison.Response{} = resp) do
    resp.headers
    |> Enum.filter(fn
      {"Set-Cookie", _} -> true
      _ -> false
    end)
    |> Enum.map(fn{_, cookie} -> cookie end)
  end
end 

The CookieStore is just a name for an Agent process

# in application.ex
children = [
      worker(Agent, [fn -> nil end, [name: EkangScraper.CookieStore]])
]

How to use

# GET request. 
# Params are appended to URL as query string. 
# Cookies are automatically handled
doc = EkangScraper.HttpClient.get("http://www.example.com/path", %{foo: "bar", baz: "qux"})

# POST request. 
# Params are encoded as application/x-www-form-urlencoded and put to request body.
# Cookies are automatically handled.
doc = EkangScraper.HttpClient.post("http://www.example.com/path", %{foo: "bar", baz: "qux"})

# If you just want a raw response body as a string
body_string = EkangScraper.HttpClient.get_raw("http://www.example.com/path", %{foo: "bar", baz: "qux"})

There are patch, put, delete and their _raw counterpart as well.

aseigo

aseigo

You are creating a json object but then saying that the Content-Type is "Content-Type" => "application/x-www-form-urlencoded" … that should be application/json or else you can pass a {:form, [{K, V}, ...]} tuple to HTTPoison.post as the body to send a urlencoded form. One or the other … hth :slight_smile:

Where Next?

Popular in Questions Top

shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
mathew4509
I have a list say x = ["23gh", "56kh", "97mh"] I would like to pass each element to Val in each iteration. Say, in iteration 1 -------...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New

We're in Beta

About us Mission Statement