mirror of https://github.com/knative/func.git
				
				
				
			
		
			
				
	
	
		
			105 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
// Copyright 2018 Google LLC All Rights Reserved.
 | 
						|
//
 | 
						|
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
// you may not use this file except in compliance with the License.
 | 
						|
// You may obtain a copy of the License at
 | 
						|
//
 | 
						|
//    http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
//
 | 
						|
// Unless required by applicable law or agreed to in writing, software
 | 
						|
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
// See the License for the specific language governing permissions and
 | 
						|
// limitations under the License.
 | 
						|
 | 
						|
// Package registry implements a docker V2 registry and the OCI distribution specification.
 | 
						|
//
 | 
						|
// It is designed to be used anywhere a low dependency container registry is needed, with an
 | 
						|
// initial focus on tests.
 | 
						|
//
 | 
						|
// Its goal is to be standards compliant and its strictness will increase over time.
 | 
						|
//
 | 
						|
// This is currently a low flightmiles system. It's likely quite safe to use in tests; If you're using it
 | 
						|
// in production, please let us know how and send us CL's for integration tests.
 | 
						|
package registry
 | 
						|
 | 
						|
import (
 | 
						|
	"log"
 | 
						|
	"net/http"
 | 
						|
	"os"
 | 
						|
)
 | 
						|
 | 
						|
type registry struct {
 | 
						|
	log       *log.Logger
 | 
						|
	blobs     blobs
 | 
						|
	manifests manifests
 | 
						|
}
 | 
						|
 | 
						|
// https://docs.docker.com/registry/spec/api/#api-version-check
 | 
						|
// https://github.com/opencontainers/distribution-spec/blob/master/spec.md#api-version-check
 | 
						|
func (r *registry) v2(resp http.ResponseWriter, req *http.Request) *regError {
 | 
						|
	if isBlob(req) {
 | 
						|
		return r.blobs.handle(resp, req)
 | 
						|
	}
 | 
						|
	if isManifest(req) {
 | 
						|
		return r.manifests.handle(resp, req)
 | 
						|
	}
 | 
						|
	if isTags(req) {
 | 
						|
		return r.manifests.handleTags(resp, req)
 | 
						|
	}
 | 
						|
	if isCatalog(req) {
 | 
						|
		return r.manifests.handleCatalog(resp, req)
 | 
						|
	}
 | 
						|
	resp.Header().Set("Docker-Distribution-API-Version", "registry/2.0")
 | 
						|
	if req.URL.Path != "/v2/" && req.URL.Path != "/v2" {
 | 
						|
		return ®Error{
 | 
						|
			Status:  http.StatusNotFound,
 | 
						|
			Code:    "METHOD_UNKNOWN",
 | 
						|
			Message: "We don't understand your method + url",
 | 
						|
		}
 | 
						|
	}
 | 
						|
	resp.WriteHeader(200)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (r *registry) root(resp http.ResponseWriter, req *http.Request) {
 | 
						|
	if rerr := r.v2(resp, req); rerr != nil {
 | 
						|
		r.log.Printf("%s %s %d %s %s", req.Method, req.URL, rerr.Status, rerr.Code, rerr.Message)
 | 
						|
		rerr.Write(resp)
 | 
						|
		return
 | 
						|
	}
 | 
						|
	r.log.Printf("%s %s", req.Method, req.URL)
 | 
						|
}
 | 
						|
 | 
						|
// New returns a handler which implements the docker registry protocol.
 | 
						|
// It should be registered at the site root.
 | 
						|
func New(opts ...Option) http.Handler {
 | 
						|
	r := ®istry{
 | 
						|
		log: log.New(os.Stderr, "", log.LstdFlags),
 | 
						|
		blobs: blobs{
 | 
						|
			blobHandler: &memHandler{m: map[string][]byte{}},
 | 
						|
			uploads:     map[string][]byte{},
 | 
						|
		},
 | 
						|
		manifests: manifests{
 | 
						|
			manifests: map[string]map[string]manifest{},
 | 
						|
			log:       log.New(os.Stderr, "", log.LstdFlags),
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for _, o := range opts {
 | 
						|
		o(r)
 | 
						|
	}
 | 
						|
	return http.HandlerFunc(r.root)
 | 
						|
}
 | 
						|
 | 
						|
// Option describes the available options
 | 
						|
// for creating the registry.
 | 
						|
type Option func(r *registry)
 | 
						|
 | 
						|
// Logger overrides the logger used to record requests to the registry.
 | 
						|
func Logger(l *log.Logger) Option {
 | 
						|
	return func(r *registry) {
 | 
						|
		r.log = l
 | 
						|
		r.manifests.log = l
 | 
						|
	}
 | 
						|
}
 |