5

I'm using Erlang's httpc to make a get request with parameters and with a basic auth header. When used without the header in httpc/1, like this:

 url = String.to_char_list("https://endpoint.com/endpoint?param=foo")
 :httpc.request(url)

I get the expected 403 unauthorized. However, when I use the httpc/4 like this:

 url = String.to_char_list("https://endpoint.com/endpoint?param=foo")
 headers = headers ++ [authheader]
 httpc.request(:get, {url, headers}, [], [])

I get a 404 not found error. I can IO.puts the url and directly access the resource successfully when adding the auth header manually from the browser. My post routes all work just fine with httpc/4. What's happening here?

Dania_es
  • 1,026
  • 1
  • 10
  • 20

1 Answers1

0

This is most likely spelling mistake in the URL. This is, how using basic auth in httpc looks like for me.

:httpc.request(:get, {'http://localhost:8080/', [{'Authorization', 'Basic ' ++ :base64.encode_to_string('test:test')}]}, [], [])
{:ok, {{'HTTP/1.0', 200, 'OK'}, ...}

Authenticating is perfomed before checking url, so you can try to connect to non existing url and receive 401:

:httpc.request(:get, {'http://localhost:8080/asdf', []}, [], [])
{:ok, {{'HTTP/1.0', 401, 'Unauthorized'}, ...}

If you add proper headers:

:httpc.request(:get, {'http://localhost:8080/asdf', [{'Authorization', 'Basic ' ++ :base64.encode_to_string('test:test')}]}, [], [])
{:ok, {{'HTTP/1.0', 404, 'File not found'}, ...}

Also, this can't be problem with ssl, because it gives completely different error.

There is also small chance, that the server has different routes for http and https. This way pasting the url to the browser without the https:// could work.

In your question, you said "403 unauthorized", while unauthorized is 401. 403 is forbidden, but forbidden doesn't make much sense in this context, so I assumed, you meant 401.

There is no colon before httpc.request(...) in your question, which makes simple spelling mistake even more likely.

Aside tip: you can use 'text' (in single quotes) instead of String.to_character_list("text").

tkowal
  • 9,129
  • 1
  • 27
  • 51
  • I have the colon in the code, and httpc/1 works as expected as long as no authorization is needed. I'm getting the URL as a binary so that's why the String.to_char_list. Here's the full code: https://github.com/Dania02525/cowboycors/blob/master/lib/handler.ex – Dania_es Jul 25 '15 at 12:46
  • I've created gist with python https server with basic auth and tested your code against it: https://gist.github.com/tomekowal/1577f9cef7326a38b285 Download files, run `python SimpleAuthServer.py login:pass`, run your program and type `http://localhost:8000/https%3A%2F%2Flocalhost%3A4443` in your browser. Everything works correctly. I am asked for auth. I type `login` and `pass` and I get the directory listing. I only needed to uncomment this line in your file: https://github.com/Dania02525/cowboycors/blob/master/lib/handler.ex#L34 It must be server issue or typo somewhere. – tkowal Jul 25 '15 at 23:03
  • In this line https://github.com/Dania02525/cowboycors/blob/master/lib/handler.ex#L58 you don't have to concatenate lists, you can simply return the other one. In this line https://github.com/Dania02525/cowboycors/blob/master/lib/handler.ex#L58 you are trying to concatenate binary with term, which fails. You can do it this way: `An Error Occured" <> inspect reason`. – tkowal Jul 25 '15 at 23:11