rackspace/php-opencloud — pull request #463 by ycombinator (2014-11-20 01:30:23+00:00)
Title: Adding capability for version negotiation in service endpoint URIs.

Certain services (e.g. OpenStack Neutron) do not publish a version in their endpoint URIs in the service catalog. Here is an example of the Neutron section of a OpenStack service catalog:

```json
{
"endpoints": [
{
"adminURL": "http://23.253.159.142:9696/",
"region": "RegionOne",
"internalURL": "http://23.253.159.142:9696/",
"id": "195e82869d6248cdaff43ea2b1e4e777",
"publicURL": "http://23.253.159.142:9696/"
}
],
"endpoints_links": [],
"type": "network",
"name": "neutron"
}
```

Notice how the `adminURL`, `internalURL`, and `publicURL` do not contain a version at the end of their respective URLs. The expectation here is that the consumer of this response will issue a `GET` request to the specified URL for version negotiation. Here is an example response from making a `GET` request to `http://23.253.159.142:9696/`:

```json
{
"versions": [
{
"status": "CURRENT",
"id": "v2.0",
"links": [
{
"href": "http://23.253.159.142:9696/v2.0",
"rel": "self"
}
]
}
]
}
```

This PR implements version negotiation. A couple of points to note:

1. Since there is no indication in the service catalog as to which services require version negotiation vs. which ones do not, the SDK must speculatively make the additional `GET` request to the requested endpoint URL in case it demands version negotiation.
2. As suggested in the sample version negotiation response JSON above, there might be multiple versions of the same service. This implementation chooses the first version that has `"status": "CURRENT"`.