Implement V2 API base endpoint

This implements a base endpoint that will respond with a 200 OK and an empty
json response. Such an endpoint can be used as to ping the v2 service or as an
endpoint to check authorization status.
master
Stephen J Day 2014-12-10 22:33:36 -08:00
parent 2a16a2ff6a
commit 76929fb63f
5 changed files with 85 additions and 0 deletions

View File

@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/http/httputil"
@ -22,6 +23,50 @@ import (
"github.com/gorilla/handlers"
)
// TestCheckAPI hits the base endpoint (/v2/) ensures we return the specified
// 200 OK response.
func TestCheckAPI(t *testing.T) {
config := configuration.Configuration{
Storage: configuration.Storage{
"inmemory": configuration.Parameters{},
},
}
app := NewApp(config)
server := httptest.NewServer(handlers.CombinedLoggingHandler(os.Stderr, app))
builder, err := newURLBuilderFromString(server.URL)
if err != nil {
t.Fatalf("error creating url builder: %v", err)
}
baseURL, err := builder.buildBaseURL()
if err != nil {
t.Fatalf("unexpected error building base url: %v", err)
}
resp, err := http.Get(baseURL)
if err != nil {
t.Fatalf("unexpected error issuing request: %v", err)
}
defer resp.Body.Close()
checkResponse(t, "issuing api base check", resp, http.StatusOK)
checkHeaders(t, resp, http.Header{
"Content-Type": []string{"application/json"},
"Content-Length": []string{"2"},
})
p, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatalf("unexpected error reading response body: %v", err)
}
if string(p) != "{}" {
t.Fatalf("unexpected response body: %v", string(p))
}
}
// TestLayerAPI conducts a full of the of the layer api.
func TestLayerAPI(t *testing.T) {
// TODO(stevvooe): This test code is complete junk but it should cover the

15
app.go
View File

@ -1,6 +1,7 @@
package registry
import (
"fmt"
"net/http"
"github.com/docker/docker-registry/storagedriver"
@ -38,6 +39,9 @@ func NewApp(configuration configuration.Configuration) *App {
}
// Register the handler dispatchers.
app.register(routeNameBase, func(ctx *Context, r *http.Request) http.Handler {
return http.HandlerFunc(apiBase)
})
app.register(routeNameImageManifest, imageManifestDispatcher)
app.register(routeNameTags, tagsDispatcher)
app.register(routeNameBlob, layerDispatcher)
@ -134,3 +138,14 @@ func (app *App) dispatcher(dispatch dispatchFunc) http.Handler {
}
})
}
// apiBase implements a simple yes-man for doing overall checks against the
// api. This can support auth roundtrips to support docker login.
func apiBase(w http.ResponseWriter, r *http.Request) {
const emptyJSON = "{}"
// Provide a simple /v2/ 200 OK response with empty json response.
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Content-Length", fmt.Sprint(len(emptyJSON)))
fmt.Fprint(w, emptyJSON)
}

View File

@ -6,6 +6,7 @@ import (
)
const (
routeNameBase = "base"
routeNameImageManifest = "image-manifest"
routeNameTags = "tags"
routeNameBlob = "blob"
@ -27,6 +28,11 @@ func v2APIRouter() *mux.Router {
router := mux.NewRouter().
StrictSlash(true)
// GET /v2/ Check Check that the registry implements API version 2(.1)
router.
Path("/v2/").
Name(routeNameBase)
// GET /v2/<name>/manifest/<tag> Image Manifest Fetch the image manifest identified by name and tag.
// PUT /v2/<name>/manifest/<tag> Image Manifest Upload the image manifest identified by name and tag.
// DELETE /v2/<name>/manifest/<tag> Image Manifest Delete the image identified by name and tag.

View File

@ -46,6 +46,11 @@ func TestRouter(t *testing.T) {
server := httptest.NewServer(router)
for _, testcase := range []routeTestCase{
{
RouteName: routeNameBase,
RequestURI: "/v2/",
Vars: map[string]string{},
},
{
RouteName: routeNameImageManifest,
RequestURI: "/v2/foo/bar/manifests/tag",

14
urls.go
View File

@ -39,6 +39,20 @@ func newURLBuilderFromString(root string) (*urlBuilder, error) {
return newURLBuilder(u), nil
}
func (ub *urlBuilder) buildBaseURL() (string, error) {
route := clonedRoute(ub.router, routeNameBase)
baseURL, err := route.
Schemes(ub.url.Scheme).
Host(ub.url.Host).
URL()
if err != nil {
return "", err
}
return baseURL.String(), nil
}
func (ub *urlBuilder) buildTagsURL(name string) (string, error) {
route := clonedRoute(ub.router, routeNameTags)