1
#include "source/server/admin/utils.h"
2

            
3
#include "source/common/common/enum_to_int.h"
4
#include "source/common/http/headers.h"
5

            
6
namespace Envoy {
7
namespace Server {
8
namespace Utility {
9

            
10
503
void populateFallbackResponseHeaders(Http::Code code, Http::ResponseHeaderMap& header_map) {
11
503
  header_map.setStatus(std::to_string(enumToInt(code)));
12
503
  if (header_map.ContentType() == nullptr) {
13
    // Default to text-plain if unset.
14
280
    header_map.setReferenceContentType(Http::Headers::get().ContentTypeValues.TextUtf8);
15
280
  }
16
  // Default to 'no-cache' if unset, but not 'no-store' which may break the back button.
17
503
  if (header_map.get(Http::CustomHeaders::get().CacheControl).empty()) {
18
497
    header_map.setReference(Http::CustomHeaders::get().CacheControl,
19
497
                            Http::CustomHeaders::get().CacheControlValues.NoCacheMaxAge0);
20
497
  }
21

            
22
  // Under no circumstance should browsers sniff content-type.
23
503
  header_map.addReference(Http::Headers::get().XContentTypeOptions,
24
503
                          Http::Headers::get().XContentTypeOptionValues.Nosniff);
25
503
}
26

            
27
// Helper method to get the histogram_buckets parameter. Returns an InvalidArgumentError
28
// if histogram_buckets query param is found and value is not "cumulative" or "disjoint",
29
// Ok otherwise.
30
absl::Status histogramBucketsParam(const Http::Utility::QueryParamsMulti& params,
31
138
                                   HistogramBucketsMode& histogram_buckets_mode) {
32
138
  absl::optional<std::string> histogram_buckets_query_param =
33
138
      nonEmptyQueryParam(params, "histogram_buckets");
34
138
  histogram_buckets_mode = HistogramBucketsMode::Unset;
35
138
  if (histogram_buckets_query_param.has_value()) {
36
25
    if (histogram_buckets_query_param.value() == "cumulative") {
37
7
      histogram_buckets_mode = HistogramBucketsMode::Cumulative;
38
18
    } else if (histogram_buckets_query_param.value() == "disjoint") {
39
9
      histogram_buckets_mode = HistogramBucketsMode::Disjoint;
40
13
    } else if (histogram_buckets_query_param.value() == "detailed") {
41
1
      histogram_buckets_mode = HistogramBucketsMode::Detailed;
42
      // "none" is a synonym for "summary", and exists to maintain backwards compatibility
43
8
    } else if (histogram_buckets_query_param.value() == "summary" ||
44
8
               histogram_buckets_query_param.value() == "none") {
45
3
      histogram_buckets_mode = HistogramBucketsMode::Summary;
46
5
    } else if (histogram_buckets_query_param.value() == "prometheusnative") {
47
3
      histogram_buckets_mode = HistogramBucketsMode::PrometheusNative;
48
3
    } else {
49
2
      return absl::InvalidArgumentError(
50
2
          "usage: "
51
2
          "/stats?histogram_buckets=(cumulative|disjoint|detailed|summary|prometheusnative)\n");
52
2
    }
53
25
  }
54
136
  return absl::OkStatus();
55
138
}
56

            
57
// Helper method to get a query parameter.
58
// Returns the first value for that query parameter, unless that value is empty.
59
// In that case, it returns nullopt.
60
absl::optional<std::string> nonEmptyQueryParam(const Http::Utility::QueryParamsMulti& params,
61
449
                                               const std::string& key) {
62
449
  const auto data = params.getFirstValue(key);
63
449
  if (data.has_value() && data.value().empty()) {
64
4
    return absl::nullopt;
65
4
  }
66
445
  return data;
67
449
}
68

            
69
// Helper method to get the format parameter.
70
146
absl::optional<std::string> formatParam(const Http::Utility::QueryParamsMulti& params) {
71
146
  return nonEmptyQueryParam(params, "format");
72
146
}
73

            
74
} // namespace Utility
75
} // namespace Server
76
} // namespace Envoy