func onHttpRequestBody()

in plugins/wasm-go/extensions/transformer/main.go [396:515]


func onHttpRequestBody(ctx wrapper.HttpContext, config TransformerConfig, body []byte, log wrapper.Log) types.Action {
	if config.reqTrans == nil {
		return types.ActionContinue
	}

	log.Debug("on http request body ...")

	host, path, err := getHostAndPathFromHttpCtx(ctx)
	if err != nil {
		log.Warn(err.Error())
		return types.ActionContinue
	}
	contentType, ok := ctx.GetContext("content-type").(string)
	if !ok {
		log.Warn(errGetContentType.Error())
		return types.ActionContinue
	}
	structuredBody, err := parseBody(contentType, body)
	if err != nil {
		if !errors.Is(err, errEmptyBody) {
			log.Warnf("failed to parse request body: %v", err)
		}
		log.Debug("request body is empty")
		return types.ActionContinue
	}

	mapSourceData := make(map[string]MapSourceData)
	var hs map[string][]string
	var qs map[string][]string

	hs = ctx.GetContext("headers").(map[string][]string)
	if hs == nil {
		log.Warn("failed to get request headers")
		return types.ActionContinue
	}
	if hs[":authority"] == nil {
		log.Warn(errGetRequestHost.Error())
		return types.ActionContinue
	}
	if hs[":path"] == nil {
		log.Warn(errGetRequestPath.Error())
		return types.ActionContinue
	}
	mapSourceData["headers"] = MapSourceData{
		mapSourceType: "headers",
		kvs:           hs,
	}

	qs = ctx.GetContext("querys").(map[string][]string)
	if qs == nil {
		log.Warn("failed to get request querys")
		return types.ActionContinue
	}
	mapSourceData["querys"] = MapSourceData{
		mapSourceType: "querys",
		kvs:           qs,
	}

	switch structuredBody.(type) {
	case map[string]interface{}:
		mapSourceData["body"] = MapSourceData{
			mapSourceType: "bodyJson",
			json:          structuredBody.(map[string]interface{})["body"].([]byte),
		}
	case map[string][]string:
		mapSourceData["body"] = MapSourceData{
			mapSourceType: "bodyKv",
			kvs:           structuredBody.(map[string][]string),
		}
	}

	if ctx.GetContext("need_head_trans") != nil {
		if config.reqTrans.IsHeaderChange() {
			if err = config.reqTrans.TransformHeaders(host, path, hs, mapSourceData); err != nil {
				log.Warnf("failed to transform request headers: %v", err)
				return types.ActionContinue
			}
		}

		if config.reqTrans.IsQueryChange() {
			if err = config.reqTrans.TransformQuerys(host, path, qs, mapSourceData); err != nil {
				log.Warnf("failed to transform request query params: %v", err)
				return types.ActionContinue
			}
			path, err = constructPath(path, qs)
			if err != nil {
				log.Warnf("failed to construct path: %v", err)
				return types.ActionContinue
			}
			hs[":path"] = []string{path}
		}

		headers := reconvertHeaders(hs)
		if err = proxywasm.ReplaceHttpRequestHeaders(headers); err != nil {
			log.Warnf("failed to replace request headers: %v", err)
			return types.ActionContinue
		}
	}

	if !config.reqTrans.IsBodyChange() {
		return types.ActionContinue
	}

	if err = config.reqTrans.TransformBody(host, path, structuredBody, mapSourceData); err != nil {
		log.Warnf("failed to transform request body: %v", err)
		return types.ActionContinue
	}

	body, err = constructBody(contentType, structuredBody)
	if err != nil {
		log.Warnf("failed to construct request body: %v", err)
		return types.ActionContinue
	}
	if err = proxywasm.ReplaceHttpRequestBody(body); err != nil {
		log.Warnf("failed to replace request body: %v", err)
		return types.ActionContinue
	}

	return types.ActionContinue
}