Example #1
0
func GetImageJSONV1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	var jsonInfo string
	var payload string
	var err error

	imageId := ctx.Params(":imageId")

	i := new(models.Image)
	if jsonInfo, err = i.GetJSON(imageId); err != nil {
		log.Error("[REGISTRY API V1] Search Image JSON Error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Search Image JSON Error"})
		return http.StatusNotFound, result
	}

	if payload, err = i.GetChecksumPayload(imageId); err != nil {
		log.Error("[REGISTRY API V1] Search Image Checksum Error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Search Image Checksum Error"})
		return http.StatusNotFound, result
	}

	ctx.Resp.Header().Set("X-Docker-Checksum-Payload", fmt.Sprintf("sha256:%v", payload))
	ctx.Resp.Header().Set("X-Docker-Size", fmt.Sprint(i.Size))
	ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(jsonInfo)))

	return http.StatusOK, []byte(jsonInfo)
}
Example #2
0
func PutImageChecksumV1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	imageId := ctx.Params(":imageId")

	checksum := strings.Split(ctx.Req.Header.Get("X-Docker-Checksum"), ":")[1]
	payload := strings.Split(ctx.Req.Header.Get("X-Docker-Checksum-Payload"), ":")[1]

	log.Debug("[REGISTRY API V1] Image Checksum : %v", checksum)
	log.Debug("[REGISTRY API V1] Image Payload: %v", payload)

	i := new(models.Image)
	if err := i.PutChecksum(imageId, checksum, true, payload); err != nil {
		log.Error("[REGISTRY API V1] Put Image Checksum & Payload Error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Put Image Checksum & Payload Error"})
		return http.StatusBadRequest, result
	}

	if err := i.PutAncestry(imageId); err != nil {
		log.Error("[REGISTRY API V1] Put Image Ancestry Error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Put Image Ancestry Error"})
		return http.StatusBadRequest, result
	}

	result, _ := json.Marshal(map[string]string{})
	return http.StatusOK, result
}
Example #3
0
func GetBlobsV2Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	digest := ctx.Params(":digest")

	tarsum := strings.Split(digest, ":")[1]

	i := new(models.Image)
	if exists, err := i.Get(tarsum); err != nil {
		log.Error("[REGISTRY API V2] Failed to get tarsum %v: %v", tarsum, err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to get tarsum"})
		return http.StatusBadRequest, result
	} else if !exists {
		log.Error("[REGISTRY API V2] Not found tarsum: %v: %v", tarsum, err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Not found tarsum"})
		return http.StatusNotFound, result
	}

	layer, err := module.DownloadLayer(i.Path)
	if err != nil {
		log.Error("[REGISTRY API V2] Failed to get layer: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to read layer file"})
		return http.StatusInternalServerError, result
	}

	ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
	ctx.Resp.Header().Set("Docker-Content-Digest", digest)
	ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(layer)))

	return http.StatusOK, layer
}
Example #4
0
func GetImageLayerV1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	imageId := ctx.Params(":imageId")

	i := new(models.Image)
	if _, err := i.Get(imageId); err != nil {
		log.Error("[REGISTRY API V1] Failed to get image %v layer: %v", imageId, err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to get image layer"})
		return http.StatusNotFound, result
	}

	layerfile := i.Path
	if _, err := os.Stat(layerfile); err != nil {
		log.Error("[REGISTRY API V1] Image layer file state error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Image layer file state error"})
		return http.StatusInternalServerError, result
	}

	file, err := ioutil.ReadFile(layerfile)
	if err != nil {
		log.Error("[REGISTRY API V1] Failed to read image layer: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to read image layer"})
		return http.StatusInternalServerError, result
	}

	ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
	ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(file)))

	return http.StatusOK, file
}
Example #5
0
func PutImageLayerv1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	imageId := ctx.Params(":imageId")

	basePath := setting.ImagePath
	imagePath := fmt.Sprintf("%v/images/%v", basePath, imageId)
	layerfile := fmt.Sprintf("%v/images/%v/layer", basePath, imageId)

	if !utils.IsDirExist(imagePath) {
		os.MkdirAll(imagePath, os.ModePerm)
	}

	if _, err := os.Stat(layerfile); err == nil {
		os.Remove(layerfile)
	}

	data, _ := ioutil.ReadAll(ctx.Req.Request.Body)
	if err := ioutil.WriteFile(layerfile, data, 0777); err != nil {
		log.Error("[REGISTRY API V1] Put Image Layer File Error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Put Image Layer File Error"})
		return http.StatusBadRequest, result
	}

	i := new(models.Image)
	if err := i.PutLayer(imageId, layerfile, true, int64(len(data))); err != nil {
		log.Error("[REGISTRY API V1] Put Image Layer File Data Error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Put Image Layer File Data Error"})
		return http.StatusBadRequest, result
	}

	result, _ := json.Marshal(map[string]string{})
	return http.StatusOK, result
}
Example #6
0
func HeadBlobsV2Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	digest := ctx.Params(":digest")
	tarsum := strings.Split(digest, ":")[1]

	ctx.Resp.Header().Set("Content-Type", "application/json; charset=utf-8")
	i := new(models.Image)
	if exists, err := i.Get(tarsum); err != nil {
		log.Info("[REGISTRY API V2] Failed to get tarsum %v: %v", tarsum, err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to get tarsum"})
		return http.StatusBadRequest, result
	} else if !exists {
		log.Info("[REGISTRY API V2] Not found tarsum: %v", tarsum)

		result, _ := json.Marshal(map[string]string{"message": "Not found tarsum"})
		return http.StatusNotFound, result
	}

	ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
	ctx.Resp.Header().Set("Docker-Content-Digest", digest)
	ctx.Resp.Header().Set("Content-Length", fmt.Sprint(i.Size))

	result, _ := json.Marshal(map[string]string{})
	return http.StatusOK, result
}
Example #7
0
func GetImageAncestryV1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	imageId := ctx.Params(":imageId")

	i := new(models.Image)
	if _, err := i.Get(imageId); err != nil {
		log.Error("[REGISTRY API V1] Failed to get image %v ancestry: %v", imageId, err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to get image ancestry"})
		return http.StatusBadRequest, result
	}

	ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(i.Ancestry)))

	return http.StatusOK, []byte(i.Ancestry)
}
Example #8
0
func PutBlobsV2Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	desc := ctx.Params(":uuid")
	uuid := strings.Split(desc, "?")[0]

	digest := ctx.Query("digest")
	tarsum := strings.Split(digest, ":")[1]

	imagePathTmp := module.GetImagePath(uuid, setting.APIVERSION_V2)
	layerPathTmp := module.GetLayerPath(uuid, "layer", setting.APIVERSION_V2)
	imagePath := module.GetImagePath(tarsum, setting.APIVERSION_V2)
	layerPath := module.GetLayerPath(tarsum, "layer", setting.APIVERSION_V2)

	reqbody, _ := ctx.Req.Body().Bytes()
	layerlen, err := module.SaveLayerLocal(imagePathTmp, layerPathTmp, imagePath, layerPath, reqbody)
	if err != nil {
		log.Error("[REGISTRY API V2] Failed to save layer %v: %v", layerPath, err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to save layer file"})
		return http.StatusInternalServerError, result
	}

	//saving specific tarsum every times is in order to split the same tarsum in HEAD handler
	i := new(models.Image)
	i.Path, i.Size = layerPath, int64(layerlen)
	if err := i.Save(tarsum); err != nil {
		log.Error("[REGISTRY API V2] Failed to save tarsum %v: %v", tarsum, err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to save tarsum"})
		return http.StatusBadRequest, result
	}

	random := fmt.Sprintf("%s://%s/v2/%s/%s/blobs/%s",
		setting.ListenMode,
		setting.Domains,
		ctx.Params(":namespace"),
		ctx.Params(":repository"),
		digest)

	ctx.Resp.Header().Set("Content-Type", "text/plain; charset=utf-8")
	ctx.Resp.Header().Set("Docker-Content-Digest", digest)
	ctx.Resp.Header().Set("Location", random)

	result, _ := json.Marshal(map[string]string{})
	return http.StatusCreated, result
}
Example #9
0
func PutBlobsV2Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	desc := ctx.Params(":uuid")
	uuid := strings.Split(desc, "?")[0]

	digest := ctx.Query("digest")
	tarsum := strings.Split(digest, ":")[1]

	imagePathTmp := fmt.Sprintf("%v/%v", setting.ImagePath, uuid)
	layerfileTmp := fmt.Sprintf("%v/%v/layer", setting.ImagePath, uuid)
	imagePath := fmt.Sprintf("%v/tarsum/%v", setting.ImagePath, tarsum)
	layerfile := fmt.Sprintf("%v/tarsum/%v/layer", setting.ImagePath, tarsum)

	reqbody, _ := ctx.Req.Body().Bytes()
	layerlen, err := module.CopyImgLayer(imagePathTmp, layerfileTmp, imagePath, layerfile, reqbody)
	if err != nil {
		log.Error("[REGISTRY API V2] Save layerfile failed: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Save layerfile failed"})
		return http.StatusBadRequest, result
	}

	//saving specific tarsum every times is in order to split the same tarsum in HEAD handler
	i := new(models.Image)
	i.Path, i.Size = layerfile, int64(layerlen)
	if err := i.PutTarsum(tarsum); err != nil {
		log.Error("[REGISTRY API V2] Save tarsum failed: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Save tarsum failed"})
		return http.StatusBadRequest, result
	}

	random := fmt.Sprintf("%s://%s/v2/%s/%s/blobs/%s",
		setting.ListenMode,
		setting.Domains,
		ctx.Params(":namespace"),
		ctx.Params(":repository"),
		digest)

	ctx.Resp.Header().Set("Docker-Content-Digest", digest)
	ctx.Resp.Header().Set("Location", random)

	result, _ := json.Marshal(map[string]string{})
	return http.StatusCreated, result
}
Example #10
0
func HeadBlobsV2Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	digest := ctx.Params(":digest")
	tarsum := strings.Split(digest, ":")[1]

	i := new(models.Image)
	if has, _ := i.HasTarsum(tarsum); has == false {
		log.Info("[REGISTRY API V2] Tarsum not found: %v", tarsum)

		result, _ := json.Marshal(map[string]string{"message": "Tarsum not found"})
		return http.StatusNotFound, result
	}

	ctx.Resp.Header().Set("Content-Type", "application/x-gzip")
	ctx.Resp.Header().Set("Docker-Content-Digest", digest)
	ctx.Resp.Header().Set("Content-Length", fmt.Sprint(i.Size))

	result, _ := json.Marshal(map[string]string{})
	return http.StatusOK, result
}
Example #11
0
func GetImageAncestryV1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	imageId := ctx.Params(":imageId")

	i := new(models.Image)
	if has, _, err := i.Has(imageId); err != nil {
		log.Error("[REGISTRY API V1] Read Image Ancestry Error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Read Image Ancestry Error"})
		return http.StatusBadRequest, result
	} else if has == false {
		log.Error("[REGISTRY API V1] Read Image None: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Read Image None"})
		return http.StatusNotFound, result
	}

	ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(i.Ancestry)))

	return http.StatusOK, []byte(i.Ancestry)
}
Example #12
0
func GetACIHandler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	namespace := ctx.Params(":namespace")
	repository := ctx.Params(":repository")
	acifilename := ctx.Params(":acifilename")

	acifile := strings.Trim(acifilename, ".asc")
	tag := strings.Trim(acifile, ".aci")

	t := new(models.Tag)
	if exists, err := t.Get(namespace, repository, tag); err != nil || !exists {
		log.Error("[ACI API] Not found ACI %v/%v/%v", namespace, repository, acifilename)
		result, _ := json.Marshal(map[string]string{"message": "Not found ACI"})
		return http.StatusNotFound, result
	}

	i := new(models.Image)
	if exists, err := i.Get(t.ImageId); err != nil || !exists {
		log.Error("[ACI API] Not found ACI %v/%v/%v", namespace, repository, acifilename)
		result, _ := json.Marshal(map[string]string{"message": "Not found ACI"})
		return http.StatusNotFound, result
	}

	var filepath string
	if b := strings.Contains(acifilename, ".asc"); b == true {
		filepath = i.SignPath
	} else {
		filepath = i.AciPath
	}

	content, err := ioutil.ReadFile(filepath)
	if err != nil {
		log.Error("[ACI API] Failed to get ACI file %v: %v", filepath, err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to get ACI file"})
		return http.StatusInternalServerError, result
	}

	return http.StatusOK, content
}
Example #13
0
func PutImageJSONV1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	imageId := ctx.Params(":imageId")

	info, err := ctx.Req.Body().String()
	if err != nil {
		log.Error("[REGISTRY API V1] Get request body error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Put V1 image JSON failed,request body is empty"})
		return http.StatusBadRequest, result
	}

	i := new(models.Image)
	if err := i.PutJSON(imageId, info, setting.APIVERSION_V1); err != nil {
		log.Error("[REGISTRY API V1] Put Image JSON Error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Put Image JSON Error"})
		return http.StatusBadRequest, result
	}

	result, _ := json.Marshal(map[string]string{})
	return http.StatusOK, result
}
Example #14
0
func GetImageLayerV1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	imageId := ctx.Params(":imageId")

	i := new(models.Image)
	if has, _, err := i.Has(imageId); err != nil {
		log.Error("[REGISTRY API V1] Read Image Layer File Status Error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Read Image Layer file Error"})
		return http.StatusBadRequest, result
	} else if has == false {
		log.Error("[REGISTRY API V1] Read Image None Error")

		result, _ := json.Marshal(map[string]string{"message": "Read Image None"})
		return http.StatusNotFound, result
	}

	layerfile := i.Path
	if _, err := os.Stat(layerfile); err != nil {
		log.Error("[REGISTRY API V1] Read Image file state error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Read Image file state error"})
		return http.StatusBadRequest, result
	}

	file, err := ioutil.ReadFile(layerfile)
	if err != nil {
		log.Error("[REGISTRY API V1] Read Image file error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Read Image file error"})
		return http.StatusBadRequest, result
	}

	ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
	ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(file)))

	return http.StatusOK, file
}
Example #15
0
func GetBlobsV2Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	digest := ctx.Params(":digest")

	tarsum := strings.Split(digest, ":")[1]

	i := new(models.Image)
	has, _ := i.HasTarsum(tarsum)
	if has == false {
		log.Error("[REGISTRY API V2] Digest not found: %v", tarsum)

		result, _ := json.Marshal(map[string]string{"message": "Digest not found"})
		return http.StatusNotFound, result
	}

	layerfile := i.Path
	if _, err := os.Stat(layerfile); err != nil {
		log.Error("[REGISTRY API V2] File path is invalid: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "File path is invalid"})
		return http.StatusBadRequest, result
	}

	file, err := ioutil.ReadFile(layerfile)
	if err != nil {
		log.Error("[REGISTRY API V2] Read file failed: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Read file failed"})
		return http.StatusBadRequest, result
	}

	ctx.Resp.Header().Set("Content-Type", "application/x-gzip")
	ctx.Resp.Header().Set("Docker-Content-Digest", digest)
	ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(file)))

	return http.StatusOK, file
}
Example #16
0
//Upload the layer of image to object storage service,support to analyzed docker V1/V2 manifest now
//consider recycling resources while save to oss failure,get and delete should be support soon
func UploadLayer(tarsumlist []string) error {
	if backend.Drv == nil {
		return nil
	}

	if len(tarsumlist) <= 0 {
		return fmt.Errorf("no blobs")
	}

	for _, tarsum := range tarsumlist {
		i := new(models.Image)
		if exists, err := i.Get(tarsum); err != nil {
			return err
		} else if !exists {
			return fmt.Errorf("not found tarsum")
		}

		if _, err := backend.Drv.Save(i.Path); err != nil {
			return err
		}
	}

	return nil
}
Example #17
0
func (n *notification) Handler(ctx *macaron.Context) {
	namespace := ctx.Params(":namespace")
	repository := ctx.Params(":repository")

	//Notification function just supports DockerV2 now
	r := new(models.Repository)
	if exists, err := r.Get(namespace, repository); err != nil || exists == false {
		return
	}
	if r.Version != setting.APIVERSION_V2 {
		return
	}

	actor := ActorRecord{Name: namespace}
	repo := fmt.Sprintf("%v/%v", namespace, repository)

	switch ctx.Req.Method {
	case "HEAD":
		digest := ctx.Params(":digest")
		tarsum := strings.Split(digest, ":")[1]

		i := new(models.Image)
		if exists, _ := i.Get(tarsum); exists == false {
			return
		}

		desc := Descriptor{
			MediaType: DefaultMedisType,
			Size:      i.Size,
			Digest:    digest,
		}

		req := newReqRecord(utils.EncodeBasicAuth(namespace, "headblobsv2"), ctx.Req.Request)
		requrl, err := module.NewURLBuilderFromRequest(ctx.Req.Request).BuildBlobURL(repo, desc.Digest)
		if err != nil {
			fmt.Errorf("[REGISTRY API V2] Head blobs and get request URL failed, error:: %v", err.Error())
		}

		b := newBridge(requrl, actor, req, notice)
		Err := b.createBlobEventAndWrite(EventActionPull, repo, desc)
		if Err.Err != nil {
			ctx.Resp.WriteHeader(http.StatusForbidden)
			return
		} else if Err.StatusCode >= 300 {
			ctx.Resp.WriteHeader(Err.StatusCode)
			return
		}

	case "GET":
		if flag := utils.Compare(ctx.Req.RequestURI, "/v2/"); flag == 0 {
			return
		}

		if flag := strings.Contains(ctx.Req.RequestURI, "/blobs/"); flag == true {
			digest := ctx.Params(":digest")
			tarsum := strings.Split(digest, ":")[1]

			i := new(models.Image)
			if exists, _ := i.Get(tarsum); exists == false {
				return
			}

			desc := Descriptor{
				MediaType: BlobMediaType,
				Size:      i.Size,
				Digest:    digest,
			}

			req := newReqRecord(utils.EncodeBasicAuth(namespace, "getblobsv2"), ctx.Req.Request)
			requrl, err := module.NewURLBuilderFromRequest(ctx.Req.Request).BuildBlobURL(repo, desc.Digest)
			if err != nil {
				fmt.Errorf("[REGISTRY API V2] Get blobs and get request URL failed, error:: %v", err.Error())
			}

			b := newBridge(requrl, actor, req, notice)
			Err := b.createBlobEventAndWrite(EventActionPull, repo, desc)
			if Err.Err != nil {
				ctx.Resp.WriteHeader(http.StatusForbidden)
				return
			} else if Err.StatusCode >= 300 {
				ctx.Resp.WriteHeader(Err.StatusCode)
				return
			}
			return
		}

		if flag := strings.Contains(ctx.Req.RequestURI, "/manifests/"); flag == true {
			t := new(models.Tag)
			if exists, err := t.Get(namespace, repository, ctx.Params(":tag")); err != nil || !exists {
				return
			}

			digest, err := utils.DigestManifest([]byte(t.Manifest))
			if err != nil {
				fmt.Errorf("[REGISTRY API V2] Get manifest digest failed: %v", err.Error())
				return
			}

			var sm SignedManifest
			if err := json.Unmarshal([]byte(t.Manifest), &sm); err != nil {
				fmt.Errorf("Unmarshal manifest error")
			}

			sm.Raw = make([]byte, len(t.Manifest), len(t.Manifest))
			copy(sm.Raw, []byte(t.Manifest))

			req := newReqRecord(utils.EncodeBasicAuth(namespace, "getmanifestv2"), ctx.Req.Request)
			requrl, err := module.NewURLBuilderFromRequest(ctx.Req.Request).BuildManifestURL(sm.Name, digest)
			if err != nil {
				fmt.Errorf("[REGISTRY API V2] Get manifest and get request URL failed, error:: %v", err.Error())
			}

			b := newBridge(requrl, actor, req, notice)
			Err := b.createManifestEventAndWrite(EventActionPull, repo, &sm)

			if Err.Err != nil {
				ctx.Resp.WriteHeader(http.StatusForbidden)
				return
			} else if Err.StatusCode >= 300 {
				ctx.Resp.WriteHeader(Err.StatusCode)
				return
			}

			return
		}

	case "PUT":
		if flag := strings.Contains(ctx.Req.RequestURI, "/blobs/uploads/"); flag == true {
			param := ctx.Params(":uuid")
			uuid := strings.Split(param, "?")[0]
			layer, _ := ioutil.ReadFile(fmt.Sprintf("%v/%v/layer", setting.ImagePath, uuid))
			digest := ctx.Query("digest")

			desc := Descriptor{
				MediaType: DefaultMedisType,
				Size:      int64(len(layer)),
				Digest:    digest,
			}

			req := newReqRecord(utils.EncodeBasicAuth(namespace, "putblobsv2"), ctx.Req.Request)
			requrl, err := module.NewURLBuilderFromRequest(ctx.Req.Request).BuildBlobURL(repo, desc.Digest)
			if err != nil {
				fmt.Errorf("[REGISTRY API V2] Get blobs and get request URL failed, error:: %v", err.Error())
			}

			b := newBridge(requrl, actor, req, notice)
			Err := b.createBlobEventAndWrite(EventActionPush, repo, desc)
			if Err.Err != nil {
				ctx.Resp.WriteHeader(http.StatusForbidden)
				return
			} else if Err.StatusCode >= 300 {
				ctx.Resp.WriteHeader(Err.StatusCode)
				return
			}
			return
		}

		if flag := strings.Contains(ctx.Req.RequestURI, "/manifests/"); flag == true {
			buf, _ := ctx.Req.Body().Bytes()

			handler.ManifestCtx = buf

			var sm SignedManifest
			if err := json.Unmarshal(buf, &sm); err != nil {
				fmt.Errorf("Unmarshal manifest error")
			}

			sm.Raw = make([]byte, len(buf), len(buf))
			copy(sm.Raw, buf)

			digest, err := utils.DigestManifest(buf)
			if err != nil {
				fmt.Errorf("[REGISTRY API V2] Get manifest digest failed: %v", err.Error())
				//return http.StatusBadRequest, result
			}
			req := newReqRecord(utils.EncodeBasicAuth(namespace, "putmanifestv2"), ctx.Req.Request)
			requrl, err := module.NewURLBuilderFromRequest(ctx.Req.Request).BuildManifestURL(sm.Name, digest)
			if err != nil {
				fmt.Errorf("[REGISTRY API V2] Put manifest and get request URL failed, error:: %v", err.Error())
			}

			b := newBridge(requrl, actor, req, notice)
			Err := b.createManifestEventAndWrite(EventActionPush, repo, &sm)
			if Err.Err != nil {
				ctx.Resp.WriteHeader(http.StatusForbidden)
				return
			} else if Err.StatusCode >= 300 {
				ctx.Resp.WriteHeader(Err.StatusCode)
				return
			}
			return
		}

	default:
		return
	}
}