Repository: prometheus/prometheus
File: storage/remote/write_handler.go (Go)

Code before:
	contentType = strings.TrimSpace(contentType)

	parts := strings.Split(contentType, ";")
	if parts[0] != appProtoContentType {
		return "", fmt.Errorf("expected %v as the first (media) part, got %v content-type", appProtoContentType, contentType)
	}
	// Parse potential https://www.rfc-editor.org/rfc/rfc9110#parameter
	for _, p := range parts[1:] {
		pair := strings.Split(p, "=")
		if len(pair) != 2 {
			return "", fmt.Errorf("as per https://www.rfc-editor.org/rfc/rfc9110#parameter expected parameters to be key-values, got %v in %v content-type", p, contentType)
		}
		if pair[0] == "proto" {
			ret := config.RemoteWriteProtoMsg(pair[1])
			if err := ret.Validate(); err != nil {
				return "", fmt.Errorf("got %v content type; %w", contentType, err)
			}
			return ret, nil
		}
	}
	// No "proto=" parameter, assuming v1.
	return config.RemoteWriteProtoMsgV1, nil
}

// isHistogramValidationError checks if the error is a native histogram validation error.
func isHistogramValidationError(err error) bool {
	return errors.Is(err, histogram.ErrHistogramCountMismatch) ||
		errors.Is(err, histogram.ErrHistogramCountNotBigEnough) ||
		errors.Is(err, histogram.ErrHistogramNegativeBucketCount) ||
		errors.Is(err, histogram.ErrHistogramSpanNegativeOffset) ||
		errors.Is(err, histogram.ErrHistogramSpansBucketsMismatch) ||
		errors.Is(err, histogram.ErrHistogramCustomBucketsMismatch) ||
		errors.Is(err, histogram.ErrHistogramCustomBucketsInvalid) ||
		errors.Is(err, histogram.ErrHistogramCustomBucketsInfinite) ||
		errors.Is(err, histogram.ErrHistogramCustomBucketsZeroCount) ||
		errors.Is(err, histogram.ErrHistogramCustomBucketsZeroThresh) ||
		errors.Is(err, histogram.ErrHistogramCustomBucketsNegSpans) ||
		errors.Is(err, histogram.ErrHistogramCustomBucketsNegBuckets) ||
		errors.Is(err, histogram.ErrHistogramExpSchemaCustomBounds)
}

func (h *writeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	contentType := r.Header.Get("Content-Type")
	if contentType == "" {
		// Don't break yolo 1.0 clients if not needed. This is similar to what we did
		// before 2.0: https://github.com/prometheus/prometheus/blob/d78253319daa62c8f28ed47e40bafcad2dd8b586/storage/remote/write_handler.go#L62
		// We could give http.StatusUnsupportedMediaType, but let's assume 1.0 message by default.
		contentType = appProtoContentType
	}

	msgType, err := h.parseProtoMsg(contentType)

Review comment (suggestion):
At some point it would be easier (and faster) to have one type that cover all histogram cases to make this check cheaper. I doubt anyone cares about individual error sentinels in our code... so having those almost as a enum feels like an overkill (: 

It's fine for now, unless you want to add a quick TODO about this e.g.

```suggestion
func isHistogramValidationError(err error) bool {
         // TODO: Considering adding single histogram error type instead of individual sentinel errors.
```

Code after:
	contentType = strings.TrimSpace(contentType)

	parts := strings.Split(contentType, ";")
	if parts[0] != appProtoContentType {
		return "", fmt.Errorf("expected %v as the first (media) part, got %v content-type", appProtoContentType, contentType)
	}
	// Parse potential https://www.rfc-editor.org/rfc/rfc9110#parameter
	for _, p := range parts[1:] {
		pair := strings.Split(p, "=")
		if len(pair) != 2 {
			return "", fmt.Errorf("as per https://www.rfc-editor.org/rfc/rfc9110#parameter expected parameters to be key-values, got %v in %v content-type", p, contentType)
		}
		if pair[0] == "proto" {
			ret := config.RemoteWriteProtoMsg(pair[1])
			if err := ret.Validate(); err != nil {
				return "", fmt.Errorf("got %v content type; %w", contentType, err)
			}
			return ret, nil
		}
	}
	// No "proto=" parameter, assuming v1.
	return config.RemoteWriteProtoMsgV1, nil
}

// isHistogramValidationError checks if the error is a native histogram validation error.
func isHistogramValidationError(err error) bool {
	// TODO: Consider adding single histogram error type instead of individual sentinel errors.
	return errors.Is(err, histogram.ErrHistogramCountMismatch) ||
		errors.Is(err, histogram.ErrHistogramCountNotBigEnough) ||
		errors.Is(err, histogram.ErrHistogramNegativeBucketCount) ||
		errors.Is(err, histogram.ErrHistogramSpanNegativeOffset) ||
		errors.Is(err, histogram.ErrHistogramSpansBucketsMismatch) ||
		errors.Is(err, histogram.ErrHistogramCustomBucketsMismatch) ||
		errors.Is(err, histogram.ErrHistogramCustomBucketsInvalid) ||
		errors.Is(err, histogram.ErrHistogramCustomBucketsInfinite) ||
		errors.Is(err, histogram.ErrHistogramCustomBucketsZeroCount) ||
		errors.Is(err, histogram.ErrHistogramCustomBucketsZeroThresh) ||
		errors.Is(err, histogram.ErrHistogramCustomBucketsNegSpans) ||
		errors.Is(err, histogram.ErrHistogramCustomBucketsNegBuckets) ||
		errors.Is(err, histogram.ErrHistogramExpSchemaCustomBounds)
}

func (h *writeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	contentType := r.Header.Get("Content-Type")
	if contentType == "" {
		// Don't break yolo 1.0 clients if not needed. This is similar to what we did
		// before 2.0: https://github.com/prometheus/prometheus/blob/d78253319daa62c8f28ed47e40bafcad2dd8b586/storage/remote/write_handler.go#L62
		// We could give http.StatusUnsupportedMediaType, but let's assume 1.0 message by default.
		contentType = appProtoContentType
	}