func NewSearchRequest()

in internal/search/search.go [51:122]


func NewSearchRequest(r *http.Request) (*SearchRequest, error) {
	body, err := io.ReadAll(r.Body)
	if err != nil {
		return nil, fmt.Errorf("failed to read request body: %w", err)
	}

	var req SearchRequest
	err = json.Unmarshal(body, &req) // nolint:musttag
	if err != nil {
		return nil, fmt.Errorf("failed to parse request body: %w", err)
	}

	if len(req.ForwardTo) == 0 {
		return nil, errors.New("no forward-to connections specified")
	}

	for _, conn := range req.ForwardTo {
		if conn.Endpoint == "" {
			return nil, errors.New("forward-to endpoint is empty")
		}

		if len(conn.RepoIds) == 0 {
			return nil, errors.New("no repo IDs specified for forward-to connection")
		}
	}

	for _, conn := range req.ForwardTo {
		if conn.Endpoint == "" {
			return nil, errors.New("forward-to endpoint is empty")
		}

		if len(conn.RepoIds) == 0 {
			return nil, errors.New("no repo IDs specified for forward-to connection")
		}
	}

	if req.Query == "" {
		return nil, errors.New("search query is empty")
	}

	if req.TimeoutString == "" {
		req.TimeoutString = defaultSearchTimeout
	}

	timeout, err := time.ParseDuration(req.TimeoutString)
	if err != nil {
		return nil, fmt.Errorf("failed to parse Timeout: %v with error %w", req.TimeoutString, err)
	}

	req.Timeout = timeout

	if req.Options.MaxLineMatchWindow == 0 {
		if req.Options.TotalMaxMatchCount == 0 {
			req.Options.MaxLineMatchWindow = defaultMaxLineMatchWindow
		} else {
			req.Options.MaxLineMatchWindow = req.Options.TotalMaxMatchCount
		}
	}

	req.Headers = map[string]string{
		"Content-Type": "application/json",
		"Accept":       "application/json",
	}

	for _, header := range forwardedHeaders {
		if values := r.Header.Values(header); len(values) > 0 {
			req.Headers[header] = strings.Join(values, ",")
		}
	}

	return &req, nil
}