swipely/docker-api — pull request #148 by ahazem (2014-06-07 23:16:47+00:00)
Title: Send appropriate headers for authentication

Hey,

So, after fixing #129 in #134, I tried using docker-api to build an image from a Dockerfile as I originally intended to do, but I wasn’t aware of the fact that the `X-Registry-Auth` header is quite different in structure from `X-Registry-Config`.

Apparently, `X-Registry-Auth` was used in docker remote API prior to version 1.9 which replaced the base64-encoded AuthConfig object (previously sent as `X-Registry-Auth`) with a base64-encoded ConfigFile object (sent as `X-Registry-Config`).

An AuthConfig object (as mentioned in the docs) should be be structured as:

```
{
'username': string,
'password': string,
'email': string,
'serveraddress' : string
}
```

But the problem is, docker's documentation does not have any mention of how ConfigFile objects are to be structured, and I had to dive deep into docker’s api package, only to discover that `X-Registry-Config` should be sent using the following format:

```
{
"configs":
{
"serveraddress":
{
"username": "",
"password": "",
"email": ""
}
}
}
```

I’m writing these details because I have lost a day or two trying to figure out what's wrong, so I hope it will save someone's time. Anyway, without further ado, what I propose here is the following:

1. `Docker::Image.build_from_dir` uses the `Docker::Util.build_auth_header` to encode the passed credentials and sends back the two headers (`X-Registry-Auth` and `X-Registry-Config`, which as I previously mentioned are different in structure). To solve this, I've created another method called `build_config_header` which takes the passed credentials, and send back the `X-Registry-Config` header after being encoded (using appropriate format).

2. Since `POST /build` is the only endpoint (as of api version 1.12) that uses `X-Registry-Config` and all other endpoints where authentication might be needed use the `X-Registry-Auth`, we will leave the `Docker::Util.build_auth_header` as is, and just make it return the `X-Registry-Auth` header only.

3. I think you should probably add a version check to use `Docker::Util.build_auth_header` instead of the proposed `Docker::Util.build_config_header` in `Docker::Image.build_from_dir` just to make sure that `X-Registry-Auth` header is sent if the api version used is less than 1.9. I thought of doing so myself, but I wasn't really sure what would be the best way to tackle this.