Exemplo n.º 1
0
func TestImportImportRequestResponsePairs_CanImportAMultiplePairs(t *testing.T) {
	RegisterTestingT(t)

	cache := cache.NewInMemoryCache()
	cfg := Configuration{Webserver: false}
	requestMatcher := matching.RequestMatcher{RequestCache: cache, Webserver: &cfg.Webserver}
	hv := Hoverfly{RequestCache: cache, Cfg: &cfg, RequestMatcher: requestMatcher}

	RegisterTestingT(t)

	originalPair1 := v1.RequestResponsePairView{
		Response: v1.ResponseDetailsView{
			Status:      200,
			Body:        "hello_world",
			EncodedBody: false,
			Headers:     map[string][]string{"Hoverfly": []string{"testing"}},
		},
		Request: v1.RequestDetailsView{
			Path:        StringToPointer("/"),
			Method:      StringToPointer("GET"),
			Destination: StringToPointer("/"),
			Scheme:      StringToPointer("scheme"),
			Query:       StringToPointer(""),
			Body:        StringToPointer(""),
			Headers:     map[string][]string{"Hoverfly": []string{"testing"}}}}

	originalPair2 := originalPair1
	originalPair2.Request.Path = StringToPointer("/new/path")

	originalPair3 := originalPair1
	originalPair3.Request.Path = StringToPointer("/newer/path")

	hv.ImportRequestResponsePairViews([]interfaces.RequestResponsePair{originalPair1, originalPair2, originalPair3})

	pairBytes, err := cache.Get([]byte("9b114df98da7f7e2afdc975883dab4f2"))
	Expect(err).To(BeNil())
	decodedPair1, err := models.NewRequestResponsePairFromBytes(pairBytes)
	Expect(err).To(BeNil())
	Expect(*decodedPair1).To(Equal(models.NewRequestResponsePairFromRequestResponsePairView(originalPair1)))

	pairBytes, err = cache.Get([]byte("9c03e4af1f30542ff079a712bddad602"))
	Expect(err).To(BeNil())
	decodedPair2, err := models.NewRequestResponsePairFromBytes(pairBytes)
	Expect(err).To(BeNil())
	Expect(*decodedPair2).To(Equal(models.NewRequestResponsePairFromRequestResponsePairView(originalPair2)))

	pairBytes, err = cache.Get([]byte("fd099332afee48101edb7441b098cd4a"))
	Expect(err).To(BeNil())
	decodedPair3, err := models.NewRequestResponsePairFromBytes(pairBytes)
	Expect(err).To(BeNil())
	Expect(*decodedPair3).To(Equal(models.NewRequestResponsePairFromRequestResponsePairView(originalPair3)))
}
Exemplo n.º 2
0
func ExecuteMiddlewareRemotely(middleware string, pair models.RequestResponsePair) (models.RequestResponsePair, error) {
	pairViewBytes, err := json.Marshal(pair.ConvertToRequestResponsePairView())

	req, err := http.NewRequest("POST", middleware, bytes.NewBuffer(pairViewBytes))
	if err != nil {
		log.WithFields(log.Fields{
			"error": err.Error(),
		}).Error("Error when building request to remote middleware")
		return pair, err
	}

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		log.WithFields(log.Fields{
			"error": err.Error(),
		}).Error("Error when communicating with remote middleware")
		return pair, err
	}

	if resp.StatusCode != 200 {
		log.Error("Remote middleware did not process payload")
		return pair, errors.New("Error when communicating with remote middleware")
	}

	returnedPairViewBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.WithFields(log.Fields{
			"error": err.Error(),
		}).Error("Error when process response from remote middleware")
		return pair, err
	}

	var newPairView views.RequestResponsePairView

	err = json.Unmarshal(returnedPairViewBytes, &newPairView)
	if err != nil {
		log.WithFields(log.Fields{
			"error": err.Error(),
		}).Error("Error when trying to serialize response from remote middleware")
		return pair, err
	}
	return models.NewRequestResponsePairFromRequestResponsePairView(newPairView), nil
}
Exemplo n.º 3
0
// ExecuteMiddleware - takes command (middleware string) and payload, which is passed to middleware
func ExecuteMiddlewareLocally(middlewares string, pair models.RequestResponsePair) (models.RequestResponsePair, error) {

	mws := strings.Split(middlewares, "|")
	var cmdList []*exec.Cmd

	for _, v := range mws {
		commands := strings.Split(strings.TrimSpace(v), " ")

		cmd := exec.Command(commands[0], commands[1:]...)
		cmdList = append(cmdList, cmd)
	}

	// getting payload
	pairViewBytes, err := json.Marshal(pair.ConvertToRequestResponsePairView())

	if log.GetLevel() == log.DebugLevel {
		log.WithFields(log.Fields{
			"middlewares": mws,
			"count":       len(mws),
			"payload":     string(pairViewBytes),
		}).Debug("preparing to modify payload")
	}

	if err != nil {
		log.WithFields(log.Fields{
			"error": err.Error(),
		}).Error("Failed to marshal json")
		return pair, err
	}

	//
	cmdList[0].Stdin = bytes.NewReader(pairViewBytes)

	// Run the pipeline
	mwOutput, stderr, err := Pipeline(cmdList...)

	// middleware failed to execute
	if err != nil {
		if len(stderr) > 0 {
			log.WithFields(log.Fields{
				"sdtderr": string(stderr),
				"error":   err.Error(),
			}).Error("Middleware error")
		} else {
			log.WithFields(log.Fields{
				"error": err.Error(),
			}).Error("Middleware error")
		}
		return pair, err
	}

	// log stderr, middleware executed successfully
	if len(stderr) > 0 {
		log.WithFields(log.Fields{
			"sdtderr": string(stderr),
		}).Info("Information from middleware")
	}

	if len(mwOutput) > 0 {
		var newPairView views.RequestResponsePairView

		err = json.Unmarshal(mwOutput, &newPairView)

		if err != nil {
			log.WithFields(log.Fields{
				"mwOutput": string(mwOutput),
				"error":    err.Error(),
			}).Error("Failed to unmarshal JSON from middleware")
		} else {
			if log.GetLevel() == log.DebugLevel {
				log.WithFields(log.Fields{
					"middlewares": middlewares,
					"count":       len(middlewares),
					"payload":     string(mwOutput),
				}).Debug("payload after modifications")
			}
			// payload unmarshalled into RequestResponsePair struct, returning it
			return models.NewRequestResponsePairFromRequestResponsePairView(newPairView), nil
		}
	} else {

		log.WithFields(log.Fields{
			"mwOutput": string(mwOutput),
		}).Warn("No response from middleware.")
	}

	return pair, nil

}
Exemplo n.º 4
0
// ImportRequestResponsePairViews - a function to save given pairs into the database.
func (hf *Hoverfly) ImportRequestResponsePairViews(pairViews []views.RequestResponsePairView) error {
	if len(pairViews) > 0 {
		success := 0
		failed := 0
		for _, pairView := range pairViews {

			// Convert PayloadView back to Payload for internal storage
			pair := models.NewRequestResponsePairFromRequestResponsePairView(pairView)

			if len(pair.Request.Headers) == 0 {
				pair.Request.Headers = make(map[string][]string)
			}

			if _, present := pair.Request.Headers["Content-Type"]; !present {
				// sniffing content types
				if isJSON(pair.Request.Body) {
					pair.Request.Headers["Content-Type"] = []string{"application/json"}
				} else {
					ct := http.DetectContentType([]byte(pair.Request.Body))
					pair.Request.Headers["Content-Type"] = []string{ct}
				}
			}

			pairBytes, err := pair.Encode()
			if err != nil {
				log.WithFields(log.Fields{
					"error": err.Error(),
				}).Error("Failed to encode payload")
				failed++
			} else {
				// hook
				var en Entry
				en.ActionType = ActionTypeRequestCaptured
				en.Message = "imported"
				en.Time = time.Now()
				en.Data = pairBytes

				if err := hf.Hooks.Fire(ActionTypeRequestCaptured, &en); err != nil {
					log.WithFields(log.Fields{
						"error":      err.Error(),
						"message":    en.Message,
						"actionType": ActionTypeRequestCaptured,
					}).Error("failed to fire hook")
				}

				err := hf.RequestMatcher.SaveRequestResponsePair(&pair)
				if err != nil {
					log.WithFields(log.Fields{
						"error": err.Error(),
					}).Error("Failed to save payload")
				}

				if err == nil {
					success++
				} else {
					failed++
				}
			}
		}
		log.WithFields(log.Fields{
			"total":      len(pairViews),
			"successful": success,
			"failed":     failed,
		}).Info("payloads imported")
		return nil
	}
	return fmt.Errorf("Bad request. Nothing to import!")
}
Exemplo n.º 5
0
// ImportRequestResponsePairViews - a function to save given pairs into the database.
func (hf *Hoverfly) ImportRequestResponsePairViews(pairViews []interfaces.RequestResponsePair) error {
	if len(pairViews) > 0 {
		success := 0
		failed := 0
		for _, pairView := range pairViews {

			if pairView.GetRequest().GetRequestType() != nil && *pairView.GetRequest().GetRequestType() == *StringToPointer("template") {
				responseDetails := models.NewResponseDetailsFromResponse(pairView.GetResponse())

				requestTemplate := matching.RequestTemplate{
					Path:        pairView.GetRequest().GetPath(),
					Method:      pairView.GetRequest().GetMethod(),
					Destination: pairView.GetRequest().GetDestination(),
					Scheme:      pairView.GetRequest().GetScheme(),
					Query:       pairView.GetRequest().GetQuery(),
					Body:        pairView.GetRequest().GetBody(),
					Headers:     pairView.GetRequest().GetHeaders(),
				}

				requestTemplateResponsePair := matching.RequestTemplateResponsePair{
					RequestTemplate: requestTemplate,
					Response:        responseDetails,
				}

				hf.RequestMatcher.TemplateStore = append(hf.RequestMatcher.TemplateStore, requestTemplateResponsePair)
				success++
				continue
			}

			// Convert PayloadView back to Payload for internal storage
			pair := models.NewRequestResponsePairFromRequestResponsePairView(pairView)

			if len(pair.Request.Headers) == 0 {
				pair.Request.Headers = make(map[string][]string)
			}

			if _, present := pair.Request.Headers["Content-Type"]; !present {
				// sniffing content types
				if isJSON(pair.Request.Body) {
					pair.Request.Headers["Content-Type"] = []string{"application/json"}
				} else {
					ct := http.DetectContentType([]byte(pair.Request.Body))
					pair.Request.Headers["Content-Type"] = []string{ct}
				}
			}

			pairBytes, err := pair.Encode()
			if err != nil {
				log.WithFields(log.Fields{
					"error": err.Error(),
				}).Error("Failed to encode payload")
				failed++
			} else {
				// hook
				var en Entry
				en.ActionType = ActionTypeRequestCaptured
				en.Message = "imported"
				en.Time = time.Now()
				en.Data = pairBytes

				if err := hf.Hooks.Fire(ActionTypeRequestCaptured, &en); err != nil {
					log.WithFields(log.Fields{
						"error":      err.Error(),
						"message":    en.Message,
						"actionType": ActionTypeRequestCaptured,
					}).Error("failed to fire hook")
				}

				err := hf.RequestMatcher.SaveRequestResponsePair(&pair)
				if err != nil {
					log.WithFields(log.Fields{
						"error": err.Error(),
					}).Error("Failed to save payload")
				}

				if err == nil {
					success++
				} else {
					failed++
				}
			}
		}
		log.WithFields(log.Fields{
			"total":      len(pairViews),
			"successful": success,
			"failed":     failed,
		}).Info("payloads imported")
		return nil
	}
	return nil
}
Exemplo n.º 6
0
// ExecuteMiddleware - takes command (middleware string) and payload, which is passed to middleware
func (this Middleware) executeMiddlewareLocally(pair models.RequestResponsePair) (models.RequestResponsePair, error) {
	var commandAndArgs []string
	if this.Binary == "" {
		commandAndArgs = strings.Split(strings.TrimSpace(this.FullCommand), " ")
	} else {
		commandAndArgs = []string{this.Binary, this.Script.Name()}
	}

	middlewareCommand := exec.Command(commandAndArgs[0], commandAndArgs[1:]...)

	// getting payload
	pairViewBytes, err := json.Marshal(pair.ConvertToRequestResponsePairView())

	if err != nil {
		log.WithFields(log.Fields{
			"error": err.Error(),
		}).Error("Failed to marshal json")
		return pair, err
	}

	if log.GetLevel() == log.DebugLevel {
		log.WithFields(log.Fields{
			"middleware": this.FullCommand,
			"stdin":      string(pairViewBytes),
		}).Debug("preparing to modify payload")
	}

	var stdout bytes.Buffer
	var stderr bytes.Buffer

	// Redirect standard streams
	middlewareCommand.Stdin = bytes.NewReader(pairViewBytes)
	middlewareCommand.Stdout = &stdout
	middlewareCommand.Stderr = &stderr

	if err := middlewareCommand.Start(); err != nil {
		log.WithFields(log.Fields{
			"sdtdout": string(stdout.Bytes()),
			"sdtderr": string(stderr.Bytes()),
			"error":   err.Error(),
		}).Error("Middleware failed to start")
		return pair, err
	}

	if err := middlewareCommand.Wait(); err != nil {
		log.WithFields(log.Fields{
			"sdtdout": string(stdout.Bytes()),
			"sdtderr": string(stderr.Bytes()),
			"error":   err.Error(),
		}).Error("Middleware failed to stop successfully")
		return pair, err
	}

	// log stderr, middleware executed successfully
	if len(stderr.Bytes()) > 0 {
		log.WithFields(log.Fields{
			"sdtderr": string(stderr.Bytes()),
		}).Info("Information from middleware")
	}

	if len(stdout.Bytes()) > 0 {
		var newPairView v2.RequestResponsePairView

		err = json.Unmarshal(stdout.Bytes(), &newPairView)

		if err != nil {
			log.WithFields(log.Fields{
				"stdout": string(stdout.Bytes()),
				"error":  err.Error(),
			}).Error("Failed to unmarshal JSON from middleware")
		} else {
			if log.GetLevel() == log.DebugLevel {
				log.WithFields(log.Fields{
					"middleware": this.FullCommand,
					"payload":    string(stdout.Bytes()),
				}).Debug("payload after modifications")
			}
			// payload unmarshalled into RequestResponsePair struct, returning it
			return models.NewRequestResponsePairFromRequestResponsePairView(newPairView), nil
		}
	} else {
		log.WithFields(log.Fields{
			"stdout": string(stdout.Bytes()),
		}).Warn("No response from middleware.")
	}

	return pair, nil

}