diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml
new file mode 100644
index 0000000..96414af
--- /dev/null
+++ b/.github/workflows/pr.yaml
@@ -0,0 +1,28 @@
+name: Pull-Request Testing
+on:
+ pull_request:
+ workflow_dispatch:
+
+jobs:
+ build:
+ name: Build
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Build docker image
+ run: docker build .
+
+ lint:
+ name: Lint
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 2
+ - uses: actions/setup-go@v5
+ with:
+ go-version-file: 'go.mod'
+ - name: golangci-lint
+ uses: golangci/golangci-lint-action@v6
+ with:
+ version: v1.61.0
diff --git a/.github/workflows/release-please.yaml b/.github/workflows/release-please.yaml
new file mode 100644
index 0000000..866d724
--- /dev/null
+++ b/.github/workflows/release-please.yaml
@@ -0,0 +1,107 @@
+on:
+ push:
+ branches:
+ - main
+ - release
+
+permissions:
+ contents: write
+ pull-requests: write
+ packages: write
+
+name: Release
+
+jobs:
+ release-please:
+ runs-on: ubuntu-latest
+ outputs:
+ version: ${{steps.release.outputs.version }}
+ release_created: ${{steps.release.outputs.release_created }}
+
+ steps:
+ - uses: actions/checkout@v4
+ - uses: googleapis/release-please-action@v4
+ id: release
+ with:
+ target-branch: 'release'
+
+ release-container:
+ runs-on: ubuntu-latest
+ needs: release-please
+ env:
+ REGISTRY: ghcr.io
+ IMAGE_NAME: ${{ github.repository }}
+ TAG: ${{ needs.release-please.outputs.version }}
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Log in to the Container registry
+ uses: docker/login-action@v3
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Build and push Docker image
+ uses: docker/build-push-action@v6
+ if: ${{needs.release-please.outputs.release_created == 'true'}}
+ with:
+ context: .
+ file: ./Dockerfile
+ push: true
+ tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.TAG }}
+ platforms: |
+ linux/amd64
+ linux/arm64
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
+
+ - name: Extract metadata (tags, labels) for Docker
+ id: meta
+ if: ${{ needs.release-please.outputs.release_created != 'true' }}
+ uses: docker/metadata-action@v5
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+ tags: |
+ type=raw,value=latest-{{date 'YYYYMMDDHHmmss'}}-{{sha}}
+
+ - name: Build and push Docker image
+ uses: docker/build-push-action@v6
+ if: ${{ needs.release-please.outputs.release_created != 'true' }}
+ with:
+ context: .
+ file: ./Dockerfile
+ push: true
+ tags: ${{ steps.meta.outputs.tags }}
+ platforms: |
+ linux/amd64
+ linux/arm64
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
+
+ release-helm:
+ runs-on: ubuntu-latest
+ needs: release-please
+ if: ${{needs.release-please.outputs.release_created == 'true'}}
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0 # important parameter
+
+ - name: Configure Git
+ run: |
+ git config user.name "$GITHUB_ACTOR"
+ git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
+
+ - name: Install Helm
+ uses: azure/setup-helm@v4
+ env:
+ GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
+
+ - name: Run chart-releaser
+ uses: helm/chart-releaser-action@v1.6.0
+ env:
+ CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
diff --git a/.golangci.yaml b/.golangci.yaml
new file mode 100644
index 0000000..810cb8c
--- /dev/null
+++ b/.golangci.yaml
@@ -0,0 +1,15 @@
+run:
+ timeout: 30m
+
+linters:
+ enable:
+ - errcheck
+ - gosimple
+ - govet
+ - ineffassign
+ - staticcheck
+ - unused
+ - zerologlint
+
+issues:
+ max-same-issues: 0
\ No newline at end of file
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
new file mode 100644
index 0000000..2b6f978
--- /dev/null
+++ b/.release-please-manifest.json
@@ -0,0 +1,3 @@
+{
+ ".": "1.9.1"
+}
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..9b78146
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,28 @@
+FROM --platform=$BUILDPLATFORM golang:1.23-alpine3.20 AS builder
+# Define target arch variables so we can use them while crosscompiling, will be set automatically
+ARG TARGETARCH
+ENV CGO_ENABLED=0 \
+ GOOS=linux \
+ GOARCH=${TARGETARCH}
+
+WORKDIR /go/src/
+
+# get dependencies
+COPY go.mod go.sum ./
+RUN go mod download
+
+# copy code
+COPY . .
+
+# Build project
+RUN go build -ldflags "-s -w" -a -installsuffix cgo -o /radix-ingress-default-backend
+
+# Final stage, ref https://github.com/GoogleContainerTools/distroless/blob/main/base/README.md for distroless
+FROM gcr.io/distroless/static
+COPY www /www
+COPY mime.types /etc/
+COPY --from=builder /radix-ingress-default-backend /radix-ingress-default-backend
+
+EXPOSE 8000
+USER 1000
+ENTRYPOINT ["/radix-ingress-default-backend"]
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..7e25af7
--- /dev/null
+++ b/README.md
@@ -0,0 +1,8 @@
+# Radix Ingress Defailt Backend
+
+Responds with the default backend based on namespace header
+
+## How we work
+
+Commits to the main branch must follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) and uses Release Please to create new versions.
+
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..6e8bf73
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+0.1.0
diff --git a/charts/radix-ingress-deafult-backend/.helmignore b/charts/radix-ingress-deafult-backend/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++ b/charts/radix-ingress-deafult-backend/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/charts/radix-ingress-deafult-backend/Chart.yaml b/charts/radix-ingress-deafult-backend/Chart.yaml
new file mode 100644
index 0000000..0d3d324
--- /dev/null
+++ b/charts/radix-ingress-deafult-backend/Chart.yaml
@@ -0,0 +1,15 @@
+apiVersion: v2
+name: ingress-deafult-backend
+icon: https://radix.equinor.com/images/logos/logo.svg
+description: Simple Prometheus Proxy to expose a simple metric
+version: 1.9.1
+appVersion: 1.9.1
+kubeVersion: '>=1.24.0'
+keywords:
+ - radix
+home: radix.equinor.com
+sources:
+ - https://github.com/equinor/ingress-deafult-backend
+maintainers:
+ - name: Omnia Radix
+ email: Radix@StatoilSRM.onmicrosoft.com
diff --git a/charts/radix-ingress-deafult-backend/templates/_helpers.tpl b/charts/radix-ingress-deafult-backend/templates/_helpers.tpl
new file mode 100644
index 0000000..7f0ede3
--- /dev/null
+++ b/charts/radix-ingress-deafult-backend/templates/_helpers.tpl
@@ -0,0 +1,58 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "prometheus-proxy.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "prometheus-proxy.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "prometheus-proxy.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels
+*/}}
+{{- define "prometheus-proxy.labels" -}}
+helm.sh/chart: {{ include "prometheus-proxy.chart" . }}
+{{ include "prometheus-proxy.selectorLabels" . }}
+{{- if .Chart.Version }}
+app.kubernetes.io/version: {{ .Chart.Version | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "prometheus-proxy.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "prometheus-proxy.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "prometheus-proxy.serviceAccountName" -}}
+{{- default (include "prometheus-proxy.fullname" .) .Values.serviceAccount.name }}
+{{- end }}
diff --git a/charts/radix-ingress-deafult-backend/templates/deployment.yaml b/charts/radix-ingress-deafult-backend/templates/deployment.yaml
new file mode 100644
index 0000000..a883649
--- /dev/null
+++ b/charts/radix-ingress-deafult-backend/templates/deployment.yaml
@@ -0,0 +1,66 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ template "prometheus-proxy.fullname" . }}
+ namespace: {{ .Release.Namespace | quote }}
+ labels:
+ {{- include "prometheus-proxy.labels" . | nindent 4 }}
+ {{- with .Values.deploymentAnnotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ {{- include "prometheus-proxy.selectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ labels:
+ {{- include "prometheus-proxy.selectorLabels" . | nindent 8 }}
+ {{- with .Values.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ spec:
+ securityContext:
+ runAsNonRoot: true
+ runAsUser: 1000
+ runAsGroup: 1000
+ fsGroup: 1000
+ supplementalGroups:
+ - 1000
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ .Values.image.repository }}:{{ default .Chart.Version .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ ports:
+ - containerPort: 8000
+ name: http
+ env:
+ - name: LOG_PRETTY
+ value: {{ .Values.logPretty | quote }}
+ - name: LOG_LEVEL
+ value: {{ .Values.logLevel | quote }}
+ - name: PROMETHEUS
+ value: {{ .Values.prometheusUrl | quote }}
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ securityContext:
+ privileged: false
+ readOnlyRootFilesystem: true
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
diff --git a/charts/radix-ingress-deafult-backend/templates/ingress.api.yaml b/charts/radix-ingress-deafult-backend/templates/ingress.api.yaml
new file mode 100644
index 0000000..86a6a58
--- /dev/null
+++ b/charts/radix-ingress-deafult-backend/templates/ingress.api.yaml
@@ -0,0 +1,38 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ annotations:
+ ingress.kubernetes.io/force-ssl-redirect: "true"
+ labels:
+ radix-app: radix-api
+ radix-component: server
+ name: server.custom-domain
+ namespace: radix-api-${RADIX_APP_ENV:=tba}
+spec:
+ ingressClassName: nginx
+ rules:
+ - host: api.${AZ_RESOURCE_DNS:=tba}
+ http:
+ paths:
+ - path: "/"
+ pathType: Prefix
+ backend:
+ service:
+ name: server
+ port:
+ number: 3002
+ - host: api.${clusterName:=tba}.${AZ_RESOURCE_DNS:=tba}
+ http:
+ paths:
+ - path: "/"
+ pathType: Prefix
+ backend:
+ service:
+ name: server
+ port:
+ number: 3002
+ tls:
+ - hosts:
+ - api.${AZ_RESOURCE_DNS:=tba}
+ - api.${clusterName:=tba}.${AZ_RESOURCE_DNS:=tba}
+ secretName: "radix-wildcard-tls-cert"
diff --git a/charts/radix-ingress-deafult-backend/templates/service.yaml b/charts/radix-ingress-deafult-backend/templates/service.yaml
new file mode 100644
index 0000000..03ca879
--- /dev/null
+++ b/charts/radix-ingress-deafult-backend/templates/service.yaml
@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "prometheus-proxy.fullname" . }}
+ namespace: {{ .Release.Namespace | quote }}
+spec:
+ selector:
+ {{- include "prometheus-proxy.selectorLabels" . | nindent 6 }}
+ ports:
+ - name: http
+ port: 8000
diff --git a/charts/radix-ingress-deafult-backend/values.yaml b/charts/radix-ingress-deafult-backend/values.yaml
new file mode 100644
index 0000000..f911b6b
--- /dev/null
+++ b/charts/radix-ingress-deafult-backend/values.yaml
@@ -0,0 +1,37 @@
+# Default values for charts.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+nameOverride: ""
+fullnameOverride: ""
+
+image:
+ repository: ghcr.io/equinor/ingress-deafult-backend
+ tag: ""
+ pullPolicy: Always
+
+# Annotations to add to the Deployment
+deploymentAnnotations: {}
+# Extra pod labels
+podLabels: {}
+
+# Logging
+logLevel: info
+logPretty: "False"
+prometheusUrl: ""
+
+resources:
+ limits:
+ cpu: 50m
+ memory: 10Mi
+ requests:
+ cpu: 50m
+ memory: 10Mi
+
+# Affinity for pod scheduling
+affinity: {}
+
+# Node selector for pod scheduling
+nodeSelector: {}
+
+# Tolerations for pod scheduling
+tolerations: []
diff --git a/config.go b/config.go
new file mode 100644
index 0000000..b4ceec1
--- /dev/null
+++ b/config.go
@@ -0,0 +1,35 @@
+package main
+
+import (
+ "github.com/kelseyhightower/envconfig"
+ "github.com/rs/zerolog/log"
+)
+
+type Config struct {
+ LogLevel string `envconfig:"LOG_LEVEL" default:"info"`
+ LogPretty bool `envconfig:"LOG_PRETTY" default:"false"`
+ Port int `envconfig:"PORT" default:"8000"`
+ Debug bool `envconfig:"DEBUG" default:"false"`
+
+ ErrorFilesPath string `envconfig:"ERROR_FILES_PATH" default:"./www"`
+ DefaultFormat string `envconfig:"DEFAULT_RESPONSE_FORMAT" default:"text/html"`
+}
+
+func MustParseConfig() Config {
+ var c Config
+ err := envconfig.Process("", &c)
+ if err != nil {
+ _ = envconfig.Usage("", &c)
+ log.Fatal().Msg(err.Error())
+ }
+
+ initLogger(c)
+ log.Info().Msg("Starting")
+ log.Info().Int("Port", c.Port).Send()
+ log.Info().Str("Log level", c.LogLevel).Send()
+ log.Info().Bool("Log pretty", c.LogPretty).Send()
+ log.Info().Str("Error Files path", c.ErrorFilesPath).Send()
+ log.Info().Str("Default format", c.DefaultFormat).Send()
+
+ return c
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..2154d09
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,26 @@
+module github.com/equinor/radix-ingress-default-backend
+
+go 1.23.2
+
+require (
+ github.com/felixge/httpsnoop v1.0.4
+ github.com/kelseyhightower/envconfig v1.4.0
+ github.com/prometheus/client_golang v1.20.5
+ github.com/rs/xid v1.6.0
+ github.com/rs/zerolog v1.33.0
+ github.com/urfave/negroni v1.0.0
+ golang.org/x/sys v0.26.0
+)
+
+require (
+ github.com/beorn7/perks v1.0.1 // indirect
+ github.com/cespare/xxhash/v2 v2.3.0 // indirect
+ github.com/klauspost/compress v1.17.9 // indirect
+ github.com/mattn/go-colorable v0.1.13 // indirect
+ github.com/mattn/go-isatty v0.0.19 // indirect
+ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
+ github.com/prometheus/client_model v0.6.1 // indirect
+ github.com/prometheus/common v0.55.0 // indirect
+ github.com/prometheus/procfs v0.15.1 // indirect
+ google.golang.org/protobuf v1.34.2 // indirect
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..a545ad6
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,46 @@
+github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
+github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
+github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
+github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
+github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
+github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
+github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
+github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
+github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
+github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
+github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
+github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
+github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
+github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
+github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
+github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
+github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
+github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
+github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
+github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
+github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
+github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
+golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
+google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
diff --git a/logger.go b/logger.go
new file mode 100644
index 0000000..edea984
--- /dev/null
+++ b/logger.go
@@ -0,0 +1,50 @@
+package main
+
+import (
+ "io"
+ "net/http"
+ "os"
+ "time"
+
+ "github.com/felixge/httpsnoop"
+ "github.com/rs/zerolog"
+ "github.com/rs/zerolog/log"
+ "github.com/urfave/negroni"
+)
+
+func initLogger(opts Config) {
+ logLevel, err := zerolog.ParseLevel(opts.LogLevel)
+ if err != nil {
+ logLevel = zerolog.InfoLevel
+ log.Warn().Msgf("Invalid log level '%s', fallback to '%s'", opts.LogLevel, logLevel.String())
+ }
+
+ if logLevel == zerolog.NoLevel {
+ logLevel = zerolog.InfoLevel
+ }
+ opts.LogLevel = logLevel.String()
+
+ var logWriter io.Writer = os.Stderr
+ if opts.LogPretty {
+ logWriter = &zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.TimeOnly}
+ }
+
+ zerolog.DurationFieldUnit = time.Millisecond
+ logger := zerolog.New(logWriter).Level(logLevel).With().Timestamp().Logger()
+
+ log.Logger = logger
+ zerolog.DefaultContextLogger = &logger
+}
+
+func NewLoggingMiddleware() negroni.HandlerFunc {
+ return func(writer http.ResponseWriter, request *http.Request, next http.HandlerFunc) {
+ metrics := httpsnoop.CaptureMetrics(next, writer, request)
+ log.Info().
+ Str("path", request.URL.Path).
+ Str("referer", request.Referer()).
+ Dur("duration", metrics.Duration).
+ Int("status_code", metrics.Code).
+ Int64("response_size", metrics.Written).
+ Msg("Handled request")
+ }
+}
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..4725432
--- /dev/null
+++ b/main.go
@@ -0,0 +1,173 @@
+package main
+
+import (
+ "context"
+ "fmt"
+ "io"
+ "mime"
+ "net/http"
+ "os"
+ "os/signal"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/rs/zerolog"
+ "github.com/rs/zerolog/log"
+ "golang.org/x/sys/unix"
+
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/prometheus/client_golang/prometheus/promhttp"
+)
+
+const (
+ // FormatHeader name of the header used to extract the format
+ FormatHeader = "X-Format"
+
+ // CodeHeader name of the header used as source of the HTTP status code to return
+ CodeHeader = "X-Code"
+
+ // ContentType name of the header that defines the format of the reply
+ ContentType = "Content-Type"
+
+ // OriginalURI name of the header with the original URL from NGINX
+ OriginalURI = "X-Original-URI"
+
+ // Namespace name of the header that contains information about the Ingress namespace
+ Namespace = "X-Namespace"
+
+ // IngressName name of the header that contains the matched Ingress
+ IngressName = "X-Ingress-Name"
+
+ // ServiceName name of the header that contains the matched Service in the Ingress
+ ServiceName = "X-Service-Name"
+
+ // ServicePort name of the header that contains the matched Service port in the Ingress
+ ServicePort = "X-Service-Port"
+
+ // RequestId is a unique ID that identifies the request - same as for backend service
+ RequestId = "X-Request-ID"
+)
+
+func init() {
+ prometheus.MustRegister(requestCount)
+ prometheus.MustRegister(requestDuration)
+}
+
+func main() {
+ ctx, cancel := signal.NotifyContext(context.Background(), unix.SIGTERM, unix.SIGINT)
+ defer cancel()
+
+ config := MustParseConfig()
+ metricsController := NewMetricsController()
+ backendController := NewBackendController(config.ErrorFilesPath, config.DefaultFormat, config.Debug)
+ healthzController := NewHealthzController()
+
+ router := NewRouter(backendController, metricsController, healthzController)
+
+ log.Ctx(ctx).Info().Msgf("Starting server on http://localhost:%d", config.Port)
+ err := Serve(ctx, config.Port, router)
+ log.Err(err).Msg("Terminated")
+}
+
+func NewMetricsController() RouteMapper {
+ return func(mux *http.ServeMux) {
+ mux.Handle("GET /metrics", promhttp.Handler())
+ }
+}
+func NewHealthzController() RouteMapper {
+ return func(mux *http.ServeMux) {
+ mux.HandleFunc("GET /healthz", func(w http.ResponseWriter, _ *http.Request) {
+ w.WriteHeader(http.StatusOK)
+ })
+ }
+}
+
+func NewBackendController(path, defaultFormat string, debug bool) RouteMapper {
+ defaultExts, err := mime.ExtensionsByType(defaultFormat)
+ if err != nil || len(defaultExts) == 0 {
+ panic("couldn't get file extension for default format")
+ }
+ defaultExt := defaultExts[0]
+
+ return func(mux *http.ServeMux) {
+ mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+ logger := zerolog.Ctx(r.Context())
+ start := time.Now()
+ ext := defaultExt
+
+ if debug {
+ w.Header().Set(FormatHeader, r.Header.Get(FormatHeader))
+ w.Header().Set(CodeHeader, r.Header.Get(CodeHeader))
+ w.Header().Set(ContentType, r.Header.Get(ContentType))
+ w.Header().Set(OriginalURI, r.Header.Get(OriginalURI))
+ w.Header().Set(Namespace, r.Header.Get(Namespace))
+ w.Header().Set(IngressName, r.Header.Get(IngressName))
+ w.Header().Set(ServiceName, r.Header.Get(ServiceName))
+ w.Header().Set(ServicePort, r.Header.Get(ServicePort))
+ w.Header().Set(RequestId, r.Header.Get(RequestId))
+ }
+
+ format := r.Header.Get(FormatHeader)
+ if format == "" {
+ format = defaultFormat
+ logger.Printf("format not specified. Using %v", format)
+ }
+
+ cext, err := mime.ExtensionsByType(format)
+ if err != nil {
+ logger.Printf("unexpected error reading media type extension: %v. Using %v", err, ext)
+ format = defaultFormat
+ } else if len(cext) == 0 {
+ logger.Printf("couldn't get media type extension. Using %v", ext)
+ } else {
+ ext = cext[0]
+ }
+ w.Header().Set(ContentType, format)
+
+ errCode := r.Header.Get(CodeHeader)
+ code, err := strconv.Atoi(errCode)
+ if err != nil {
+ code = 404
+ logger.Error().Err(err).Str("code", errCode).Msg("unexpected error reading return code")
+ }
+ w.WriteHeader(code)
+
+ if !strings.HasPrefix(ext, ".") {
+ ext = "." + ext
+ }
+ // special case for compatibility
+ if ext == ".htm" {
+ ext = ".html"
+ }
+ file := fmt.Sprintf("%v/%v%v", path, code, ext)
+ f, err := os.Open(file)
+ if err != nil {
+ logger.Trace().Err(err).Msg("unexpected error opening file")
+ scode := strconv.Itoa(code)
+ file := fmt.Sprintf("%v/%cxx%v", path, scode[0], ext)
+ f, err := os.Open(file)
+ if err != nil {
+ logger.Error().Err(err).Msg("unexpected error opening file")
+ http.NotFound(w, r)
+ return
+ }
+ defer f.Close()
+ logger.Trace().Str("file", file).Int("code", code).Str("format", format).Msg("serving custom error response")
+ _, _ = io.Copy(w, f)
+ return
+ }
+ defer f.Close()
+ logger.Trace().Str("file", file).Int("code", code).Str("format", format).Msg("serving custom error response")
+ _, _ = io.Copy(w, f)
+
+ duration := time.Now().Sub(start).Seconds()
+
+ proto := strconv.Itoa(r.ProtoMajor)
+ proto = fmt.Sprintf("%s.%s", proto, strconv.Itoa(r.ProtoMinor))
+
+ requestCount.WithLabelValues(proto).Inc()
+ requestDuration.WithLabelValues(proto).Observe(duration)
+ })
+ }
+}
diff --git a/metrics.go b/metrics.go
new file mode 100644
index 0000000..1ca3b2a
--- /dev/null
+++ b/metrics.go
@@ -0,0 +1,45 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Collect and display prometheus metrics
+
+package main
+
+import (
+ "github.com/prometheus/client_golang/prometheus"
+)
+
+const (
+ namespace = "default_http_backend"
+ subsystem = "http"
+)
+
+var (
+ requestCount = prometheus.NewCounterVec(prometheus.CounterOpts{
+ Namespace: namespace,
+ Subsystem: subsystem,
+ Name: "request_count_total",
+ Help: "Counter of HTTP requests made.",
+ }, []string{"proto"})
+
+ requestDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{
+ Namespace: namespace,
+ Subsystem: subsystem,
+ Name: "request_duration_milliseconds",
+ Help: "Histogram of the time (in milliseconds) each request took.",
+ Buckets: append([]float64{.001, .003}, prometheus.DefBuckets...),
+ }, []string{"proto"})
+)
diff --git a/middleware.go b/middleware.go
new file mode 100644
index 0000000..7badb07
--- /dev/null
+++ b/middleware.go
@@ -0,0 +1,18 @@
+package main
+
+import (
+ "net/http"
+
+ "github.com/rs/xid"
+ "github.com/rs/zerolog/log"
+ "github.com/urfave/negroni"
+)
+
+func NewZerologRequestIdMiddleware() negroni.HandlerFunc {
+ return func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
+ logger := log.Ctx(r.Context()).With().Str("request_id", xid.New().String()).Logger()
+ r = r.WithContext(logger.WithContext(r.Context()))
+
+ next(w, r)
+ }
+}
diff --git a/mime.types b/mime.types
new file mode 100644
index 0000000..4c5804d
--- /dev/null
+++ b/mime.types
@@ -0,0 +1,1830 @@
+# extracted from mailcap-2.1.48.tar.xz @ https://releases.pagure.org/mailcap/
+
+# This is a comment. I love comments. -*- indent-tabs-mode: t -*-
+
+# This file controls what Internet media types are sent to the client for
+# given file extension(s). Sending the correct media type to the client
+# is important so they know how to handle the content of the file.
+# Extra types can either be added here or by using an AddType directive
+# in your config files. For more information about Internet media types,
+# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type
+# registry is at .
+
+# IANA types
+
+# MIME type Extensions
+application/1d-interleaved-parityfec
+application/3gpdash-qoe-report+xml
+application/3gpp-ims+xml
+application/A2L a2l
+application/activemessage
+application/alto-costmap+json
+application/alto-costmapfilter+json
+application/alto-directory+json
+application/alto-endpointcost+json
+application/alto-endpointcostparams+json
+application/alto-endpointprop+json
+application/alto-endpointpropparams+json
+application/alto-error+json
+application/alto-networkmap+json
+application/alto-networkmapfilter+json
+application/AML aml
+application/andrew-inset ez
+application/applefile
+application/ATF atf
+application/ATFX atfx
+application/ATXML atxml
+application/atom+xml atom
+application/atomcat+xml atomcat
+application/atomdeleted+xml atomdeleted
+application/atomicmail
+application/atomsvc+xml atomsvc
+application/auth-policy+xml apxml
+application/bacnet-xdd+zip xdd
+application/batch-SMTP
+application/beep+xml
+application/calendar+json
+application/calendar+xml xcs
+application/call-completion
+application/cals-1840
+application/cbor cbor
+application/ccmp+xml ccmp
+application/ccxml+xml ccxml
+application/CDFX+XML cdfx
+application/cdmi-capability cdmia
+application/cdmi-container cdmic
+application/cdmi-domain cdmid
+application/cdmi-object cdmio
+application/cdmi-queue cdmiq
+application/cdni
+application/CEA cea
+application/cea-2018+xml
+application/cellml+xml cellml cml
+application/cfw
+application/clue_info+xml clue
+application/cms cmsc
+application/cnrp+xml
+application/coap-group+json
+application/coap-payload
+application/commonground
+application/conference-info+xml
+application/cpl+xml cpl
+application/cose
+application/cose-key
+application/cose-key-set
+application/csrattrs csrattrs
+application/csta+xml
+application/CSTAdata+xml
+application/csvm+json
+application/cybercash
+application/dash+xml mpd
+application/dashdelta mpdd
+application/davmount+xml davmount
+application/dca-rft
+application/DCD dcd
+application/dec-dx
+application/dialog-info+xml
+application/dicom dcm
+application/dicom+json
+application/dicom+xml
+application/DII dii
+application/DIT dit
+application/dns
+application/dskpp+xml xmls
+application/dssc+der dssc
+application/dssc+xml xdssc
+application/dvcs dvc
+application/ecmascript es
+application/EDI-Consent
+application/EDI-X12
+application/EDIFACT
+application/efi efi
+application/EmergencyCallData.Comment+xml
+application/EmergencyCallData.Control+xml
+application/EmergencyCallData.DeviceInfo+xml
+application/EmergencyCallData.eCall.MSD
+application/EmergencyCallData.ProviderInfo+xml
+application/EmergencyCallData.ServiceInfo+xml
+application/EmergencyCallData.SubscriberInfo+xml
+application/EmergencyCallData.VEDS+xml
+application/emma+xml emma
+application/emotionml+xml emotionml
+application/encaprtp
+application/epp+xml
+application/epub+zip epub
+application/eshop
+application/exi exi
+application/fastinfoset finf
+application/fastsoap
+application/fdt+xml fdt
+# fits, fit, fts: image/fits
+application/fits
+# application/font-sfnt deprecated in favor of font/sfnt
+application/font-tdpfr pfr
+# application/font-woff deprecated in favor of font/woff
+application/framework-attributes+xml
+application/geo+json geojson
+application/geo+json-seq
+application/gml+xml gml
+application/gzip gz tgz
+application/H224
+application/held+xml
+application/http
+application/hyperstudio stk
+application/ibe-key-request+xml
+application/ibe-pkg-reply+xml
+application/ibe-pp-data
+application/iges
+application/im-iscomposing+xml
+application/index
+application/index.cmd
+application/index.obj
+application/index.response
+application/index.vnd
+application/inkml+xml ink inkml
+application/iotp
+application/ipfix ipfix
+application/ipp
+application/isup
+application/its+xml its
+application/javascript js
+application/jose
+application/jose+json
+application/jrd+json jrd
+application/json json
+application/json-patch+json json-patch
+application/json-seq
+application/jwk+json
+application/jwk-set+json
+application/jwt
+application/kpml-request+xml
+application/kpml-response+xml
+application/ld+json jsonld
+application/lgr+xml lgr
+application/link-format wlnk
+application/load-control+xml
+application/lost+xml lostxml
+application/lostsync+xml lostsyncxml
+application/LXF lxf
+application/mac-binhex40 hqx
+application/macwriteii
+application/mads+xml mads
+application/marc mrc
+application/marcxml+xml mrcx
+application/mathematica nb ma mb
+application/mathml-content+xml
+application/mathml-presentation+xml
+application/mathml+xml mml
+application/mbms-associated-procedure-description+xml
+application/mbms-deregister+xml
+application/mbms-envelope+xml
+application/mbms-msk-response+xml
+application/mbms-msk+xml
+application/mbms-protection-description+xml
+application/mbms-reception-report+xml
+application/mbms-register-response+xml
+application/mbms-register+xml
+application/mbms-schedule+xml
+application/mbms-user-service-description+xml
+application/mbox mbox
+application/media_control+xml
+# mpf: text/vnd.ms-mediapackage
+application/media-policy-dataset+xml
+application/mediaservercontrol+xml
+application/merge-patch+json
+application/metalink4+xml meta4
+application/mets+xml mets
+application/MF4 mf4
+application/mikey
+application/mods+xml mods
+application/moss-keys
+application/moss-signature
+application/mosskey-data
+application/mosskey-request
+application/mp21 m21 mp21
+# mp4, mpg4: video/mp4, see RFC 4337
+application/mp4
+application/mpeg4-generic
+application/mpeg4-iod
+application/mpeg4-iod-xmt
+# xdf: application/xcap-diff+xml
+application/mrb-consumer+xml
+application/mrb-publish+xml
+application/msc-ivr+xml
+application/msc-mixer+xml
+application/msword doc
+application/mud+json
+application/mxf mxf
+application/n-quads nq
+application/n-triples nt
+application/nasdata
+application/news-checkgroups
+application/news-groupinfo
+application/news-transmission
+application/nlsml+xml
+application/nss
+application/ocsp-request orq
+application/ocsp-response ors
+application/octet-stream bin lha lzh exe class so dll img iso
+application/oda oda
+application/ODX odx
+application/oebps-package+xml opf
+application/ogg ogx
+application/oxps oxps
+application/p2p-overlay+xml relo
+application/parityfec
+# xer: application/xcap-error+xml
+application/patch-ops-error+xml
+application/pdf pdf
+application/PDX pdx
+application/pgp-encrypted pgp
+application/pgp-keys
+application/pgp-signature sig
+application/pidf-diff+xml
+application/pidf+xml
+application/pkcs10 p10
+application/pkcs12 p12 pfx
+application/pkcs7-mime p7m p7c
+application/pkcs7-signature p7s
+application/pkcs8 p8
+# ac: application/vnd.nokia.n-gage.ac+xml
+application/pkix-attr-cert
+application/pkix-cert cer
+application/pkix-crl crl
+application/pkix-pkipath pkipath
+application/pkixcmp pki
+application/pls+xml pls
+application/poc-settings+xml
+application/postscript ps eps ai
+application/ppsp-tracker+json
+application/problem+json
+application/problem+xml
+application/provenance+xml provx
+application/prs.alvestrand.titrax-sheet
+application/prs.cww cw cww
+application/prs.hpub+zip hpub
+application/prs.nprend rnd rct
+application/prs.plucker
+application/prs.rdf-xml-crypt rdf-crypt
+application/prs.xsf+xml xsf
+application/pskc+xml pskcxml
+application/qsig
+application/raptorfec
+application/rdap+json
+application/rdf+xml rdf
+application/reginfo+xml rif
+application/relax-ng-compact-syntax rnc
+application/remote-printing
+application/reputon+json
+application/resource-lists-diff+xml rld
+application/resource-lists+xml rl
+application/rfc+xml rfcxml
+application/riscos
+application/rlmi+xml
+application/rls-services+xml rs
+application/rpki-ghostbusters gbr
+application/rpki-manifest mft
+application/rpki-publication
+application/rpki-roa roa
+application/rpki-updown
+application/rtf rtf
+application/rtploopback
+application/rtx
+application/samlassertion+xml
+application/samlmetadata+xml
+application/sbml+xml
+application/scaip+xml
+# scm: application/vnd.lotus-screencam
+application/scim+json scim
+application/scvp-cv-request scq
+application/scvp-cv-response scs
+application/scvp-vp-request spq
+application/scvp-vp-response spp
+application/sdp sdp
+application/sep+xml
+application/sep-exi
+application/session-info
+application/set-payment
+application/set-payment-initiation
+application/set-registration
+application/set-registration-initiation
+application/sgml
+application/sgml-open-catalog soc
+application/shf+xml shf
+application/sieve siv sieve
+application/simple-filter+xml cl
+application/simple-message-summary
+application/simpleSymbolContainer
+application/slate
+# application/smil obsoleted by application/smil+xml
+application/smil+xml smil smi sml
+application/smpte336m
+application/soap+fastinfoset
+application/soap+xml
+application/sparql-query rq
+application/sparql-results+xml srx
+application/spirits-event+xml
+application/sql sql
+application/srgs gram
+application/srgs+xml grxml
+application/sru+xml sru
+application/ssml+xml ssml
+application/tamp-apex-update tau
+application/tamp-apex-update-confirm auc
+application/tamp-community-update tcu
+application/tamp-community-update-confirm cuc
+application/tamp-error ter
+application/tamp-sequence-adjust tsa
+application/tamp-sequence-adjust-confirm sac
+# tsq: application/timestamp-query
+application/tamp-status-query
+# tsr: application/timestamp-reply
+application/tamp-status-response
+application/tamp-update tur
+application/tamp-update-confirm tuc
+application/tei+xml tei teiCorpus odd
+application/thraud+xml tfi
+application/timestamp-query tsq
+application/timestamp-reply tsr
+application/timestamped-data tsd
+application/trig trig
+application/ttml+xml ttml
+application/tve-trigger
+application/ulpfec
+application/urc-grpsheet+xml gsheet
+application/urc-ressheet+xml rsheet
+application/urc-targetdesc+xml td
+application/urc-uisocketdesc+xml uis
+application/vcard+json
+application/vcard+xml
+application/vemmi
+application/vnd.3gpp.access-transfer-events+xml
+application/vnd.3gpp.bsf+xml
+application/vnd.3gpp.mid-call+xml
+application/vnd.3gpp.pic-bw-large plb
+application/vnd.3gpp.pic-bw-small psb
+application/vnd.3gpp.pic-bw-var pvb
+application/vnd.3gpp-prose+xml
+application/vnd.3gpp-prose-pc3ch+xml
+# sms: application/vnd.3gpp2.sms
+application/vnd.3gpp.sms
+application/vnd.3gpp.sms+xml
+application/vnd.3gpp.srvcc-ext+xml
+application/vnd.3gpp.SRVCC-info+xml
+application/vnd.3gpp.state-and-event-info+xml
+application/vnd.3gpp.ussd+xml
+application/vnd.3gpp2.bcmcsinfo+xml
+application/vnd.3gpp2.sms sms
+application/vnd.3gpp2.tcap tcap
+application/vnd.3lightssoftware.imagescal imgcal
+application/vnd.3M.Post-it-Notes pwn
+application/vnd.accpac.simply.aso aso
+application/vnd.accpac.simply.imp imp
+application/vnd.acucobol acu
+application/vnd.acucorp atc acutc
+application/vnd.adobe.flash.movie swf
+application/vnd.adobe.formscentral.fcdt fcdt
+application/vnd.adobe.fxp fxp fxpl
+application/vnd.adobe.partial-upload
+application/vnd.adobe.xdp+xml xdp
+application/vnd.adobe.xfdf xfdf
+application/vnd.aether.imp
+application/vnd.ah-barcode
+application/vnd.ahead.space ahead
+application/vnd.airzip.filesecure.azf azf
+application/vnd.airzip.filesecure.azs azs
+application/vnd.amazon.mobi8-ebook azw3
+application/vnd.americandynamics.acc acc
+application/vnd.amiga.ami ami
+application/vnd.amundsen.maze+xml
+application/vnd.anki apkg
+application/vnd.anser-web-certificate-issue-initiation cii
+# Not in IANA listing, but is on FTP site?
+application/vnd.anser-web-funds-transfer-initiation fti
+# atx: audio/ATRAC-X
+application/vnd.antix.game-component
+application/vnd.apache.thrift.binary
+application/vnd.apache.thrift.compact
+application/vnd.apache.thrift.json
+application/vnd.api+json
+application/vnd.apothekende.reservation+json
+application/vnd.apple.installer+xml dist distz pkg mpkg
+# m3u: audio/x-mpegurl for now
+application/vnd.apple.mpegurl m3u8
+# application/vnd.arastra.swi obsoleted by application/vnd.aristanetworks.swi
+application/vnd.aristanetworks.swi swi
+application/vnd.artsquare
+application/vnd.astraea-software.iota iota
+application/vnd.audiograph aep
+application/vnd.autopackage package
+application/vnd.avistar+xml
+application/vnd.balsamiq.bmml+xml bmml
+application/vnd.balsamiq.bmpr bmpr
+application/vnd.bekitzur-stech+json
+application/vnd.bint.med-content
+application/vnd.biopax.rdf+xml
+application/vnd.blueice.multipass mpm
+application/vnd.bluetooth.ep.oob ep
+application/vnd.bluetooth.le.oob le
+application/vnd.bmi bmi
+application/vnd.businessobjects rep
+application/vnd.cab-jscript
+application/vnd.canon-cpdl
+application/vnd.canon-lips
+application/vnd.capasystems-pg+json
+application/vnd.cendio.thinlinc.clientconf tlclient
+application/vnd.century-systems.tcp_stream
+application/vnd.chemdraw+xml cdxml
+application/vnd.chess-pgn pgn
+application/vnd.chipnuts.karaoke-mmd mmd
+application/vnd.cinderella cdy
+application/vnd.cirpack.isdn-ext
+application/vnd.citationstyles.style+xml csl
+application/vnd.claymore cla
+application/vnd.cloanto.rp9 rp9
+application/vnd.clonk.c4group c4g c4d c4f c4p c4u
+application/vnd.cluetrust.cartomobile-config c11amc
+application/vnd.cluetrust.cartomobile-config-pkg c11amz
+application/vnd.coffeescript coffee
+application/vnd.collection+json
+application/vnd.collection.doc+json
+application/vnd.collection.next+json
+application/vnd.comicbook+zip cbz
+# icc: application/vnd.iccprofile
+application/vnd.commerce-battelle ica icf icd ic0 ic1 ic2 ic3 ic4 ic5 ic6 ic7 ic8
+application/vnd.commonspace csp cst
+application/vnd.contact.cmsg cdbcmsg
+application/vnd.coreos.ignition+json ign ignition
+application/vnd.cosmocaller cmc
+application/vnd.crick.clicker clkx
+application/vnd.crick.clicker.keyboard clkk
+application/vnd.crick.clicker.palette clkp
+application/vnd.crick.clicker.template clkt
+application/vnd.crick.clicker.wordbank clkw
+application/vnd.criticaltools.wbs+xml wbs
+application/vnd.ctc-posml pml
+application/vnd.ctct.ws+xml
+application/vnd.cups-pdf
+application/vnd.cups-postscript
+application/vnd.cups-ppd ppd
+application/vnd.cups-raster
+application/vnd.cups-raw
+application/vnd.curl curl
+application/vnd.cyan.dean.root+xml
+application/vnd.cybank
+application/vnd.d2l.coursepackage1p0+zip
+application/vnd.dart dart
+application/vnd.data-vision.rdz rdz
+application/vnd.datapackage+json
+application/vnd.dataresource+json
+application/vnd.debian.binary-package deb udeb
+application/vnd.dece.data uvf uvvf uvd uvvd
+application/vnd.dece.ttml+xml uvt uvvt
+application/vnd.dece.unspecified uvx uvvx
+application/vnd.dece.zip uvz uvvz
+application/vnd.denovo.fcselayout-link fe_launch
+application/vnd.desmume.movie dsm
+application/vnd.dir-bi.plate-dl-nosuffix
+application/vnd.dm.delegation+xml
+application/vnd.dna dna
+application/vnd.document+json docjson
+application/vnd.dolby.mobile.1
+application/vnd.dolby.mobile.2
+application/vnd.doremir.scorecloud-binary-document scld
+application/vnd.dpgraph dpg mwc dpgraph
+application/vnd.dreamfactory dfac
+application/vnd.drive+json
+application/vnd.dtg.local
+application/vnd.dtg.local.flash fla
+application/vnd.dtg.local.html
+application/vnd.dvb.ait ait
+# class: application/octet-stream
+application/vnd.dvb.dvbj
+application/vnd.dvb.esgcontainer
+application/vnd.dvb.ipdcdftnotifaccess
+application/vnd.dvb.ipdcesgaccess
+application/vnd.dvb.ipdcesgaccess2
+application/vnd.dvb.ipdcesgpdd
+application/vnd.dvb.ipdcroaming
+application/vnd.dvb.iptv.alfec-base
+application/vnd.dvb.iptv.alfec-enhancement
+application/vnd.dvb.notif-aggregate-root+xml
+application/vnd.dvb.notif-container+xml
+application/vnd.dvb.notif-generic+xml
+application/vnd.dvb.notif-ia-msglist+xml
+application/vnd.dvb.notif-ia-registration-request+xml
+application/vnd.dvb.notif-ia-registration-response+xml
+application/vnd.dvb.notif-init+xml
+# pfr: application/font-tdpfr
+application/vnd.dvb.pfr
+application/vnd.dvb.service svc
+# dxr: application/x-director
+application/vnd.dxr
+application/vnd.dynageo geo
+application/vnd.dzr dzr
+application/vnd.easykaraoke.cdgdownload
+application/vnd.ecdis-update
+application/vnd.ecowin.chart mag
+application/vnd.ecowin.filerequest
+application/vnd.ecowin.fileupdate
+application/vnd.ecowin.series
+application/vnd.ecowin.seriesrequest
+application/vnd.ecowin.seriesupdate
+# img: application/octet-stream
+application/vnd.efi-img
+# iso: application/octet-stream
+application/vnd.efi-iso
+application/vnd.enliven nml
+application/vnd.enphase.envoy
+application/vnd.eprints.data+xml
+application/vnd.epson.esf esf
+application/vnd.epson.msf msf
+application/vnd.epson.quickanime qam
+application/vnd.epson.salt slt
+application/vnd.epson.ssf ssf
+application/vnd.ericsson.quickcall qcall qca
+application/vnd.espass-espass+zip espass
+application/vnd.eszigno3+xml es3 et3
+application/vnd.etsi.aoc+xml
+application/vnd.etsi.asic-e+zip asice sce
+# scs: application/scvp-cv-response
+application/vnd.etsi.asic-s+zip asics
+application/vnd.etsi.cug+xml
+application/vnd.etsi.iptvcommand+xml
+application/vnd.etsi.iptvdiscovery+xml
+application/vnd.etsi.iptvprofile+xml
+application/vnd.etsi.iptvsad-bc+xml
+application/vnd.etsi.iptvsad-cod+xml
+application/vnd.etsi.iptvsad-npvr+xml
+application/vnd.etsi.iptvservice+xml
+application/vnd.etsi.iptvsync+xml
+application/vnd.etsi.iptvueprofile+xml
+application/vnd.etsi.mcid+xml
+application/vnd.etsi.mheg5
+application/vnd.etsi.overload-control-policy-dataset+xml
+application/vnd.etsi.pstn+xml
+application/vnd.etsi.sci+xml
+application/vnd.etsi.simservs+xml
+application/vnd.etsi.timestamp-token tst
+application/vnd.etsi.tsl.der
+application/vnd.etsi.tsl+xml
+application/vnd.eudora.data
+application/vnd.ezpix-album ez2
+application/vnd.ezpix-package ez3
+application/vnd.f-secure.mobile
+application/vnd.fastcopy-disk-image dim
+application/vnd.fdf fdf
+application/vnd.fdsn.mseed msd mseed
+application/vnd.fdsn.seed seed dataless
+application/vnd.ffsns
+application/vnd.filmit.zfc zfc
+# all extensions: application/vnd.hbci
+application/vnd.fints
+application/vnd.firemonkeys.cloudcell
+application/vnd.FloGraphIt gph
+application/vnd.fluxtime.clip ftc
+application/vnd.font-fontforge-sfd sfd
+application/vnd.framemaker fm
+application/vnd.frogans.fnc fnc
+application/vnd.frogans.ltf ltf
+application/vnd.fsc.weblaunch fsc
+application/vnd.fujitsu.oasys oas
+application/vnd.fujitsu.oasys2 oa2
+application/vnd.fujitsu.oasys3 oa3
+application/vnd.fujitsu.oasysgp fg5
+application/vnd.fujitsu.oasysprs bh2
+application/vnd.fujixerox.ART-EX
+application/vnd.fujixerox.ART4
+application/vnd.fujixerox.ddd ddd
+application/vnd.fujixerox.docuworks xdw
+application/vnd.fujixerox.docuworks.binder xbd
+application/vnd.fujixerox.docuworks.container xct
+application/vnd.fujixerox.HBPL
+application/vnd.fut-misnet
+application/vnd.fuzzysheet fzs
+application/vnd.genomatix.tuxedo txd
+# application/vnd.geo+json obsoleted by application/geo+json
+application/vnd.geocube+xml g3 g³
+application/vnd.geogebra.file ggb
+application/vnd.geogebra.tool ggt
+application/vnd.geometry-explorer gex gre
+application/vnd.geonext gxt
+application/vnd.geoplan g2w
+application/vnd.geospace g3w
+# gbr: application/rpki-ghostbusters
+application/vnd.gerber
+application/vnd.globalplatform.card-content-mgt
+application/vnd.globalplatform.card-content-mgt-response
+application/vnd.gmx gmx
+application/vnd.google-earth.kml+xml kml
+application/vnd.google-earth.kmz kmz
+application/vnd.gov.sk.e-form+xml
+application/vnd.gov.sk.e-form+zip
+application/vnd.gov.sk.xmldatacontainer+xml
+application/vnd.grafeq gqf gqs
+application/vnd.gridmp
+application/vnd.groove-account gac
+application/vnd.groove-help ghf
+application/vnd.groove-identity-message gim
+application/vnd.groove-injector grv
+application/vnd.groove-tool-message gtm
+application/vnd.groove-tool-template tpl
+application/vnd.groove-vcard vcg
+application/vnd.hal+json
+application/vnd.hal+xml hal
+application/vnd.HandHeld-Entertainment+xml zmm
+application/vnd.hbci hbci hbc kom upa pkd bpd
+application/vnd.hc+json
+# rep: application/vnd.businessobjects
+application/vnd.hcl-bireports
+application/vnd.hdt hdt
+application/vnd.heroku+json
+application/vnd.hhe.lesson-player les
+application/vnd.hp-HPGL hpgl
+application/vnd.hp-hpid hpi hpid
+application/vnd.hp-hps hps
+application/vnd.hp-jlyt jlt
+application/vnd.hp-PCL pcl
+application/vnd.hp-PCLXL
+application/vnd.httphone
+application/vnd.hydrostatix.sof-data sfd-hdstx
+application/vnd.hyperdrive+json
+application/vnd.hzn-3d-crossword x3d
+application/vnd.ibm.afplinedata
+application/vnd.ibm.electronic-media emm
+application/vnd.ibm.MiniPay mpy
+application/vnd.ibm.modcap list3820 listafp afp pseg3820
+application/vnd.ibm.rights-management irm
+application/vnd.ibm.secure-container sc
+application/vnd.iccprofile icc icm
+application/vnd.ieee.1905 1905.1
+application/vnd.igloader igl
+application/vnd.imagemeter.folder+zip imf
+application/vnd.imagemeter.image+zip imi
+application/vnd.immervision-ivp ivp
+application/vnd.immervision-ivu ivu
+application/vnd.ims.imsccv1p1 imscc
+application/vnd.ims.imsccv1p2
+application/vnd.ims.imsccv1p3
+application/vnd.ims.lis.v2.result+json
+application/vnd.ims.lti.v2.toolconsumerprofile+json
+application/vnd.ims.lti.v2.toolproxy.id+json
+application/vnd.ims.lti.v2.toolproxy+json
+application/vnd.ims.lti.v2.toolsettings+json
+application/vnd.ims.lti.v2.toolsettings.simple+json
+application/vnd.informedcontrol.rms+xml
+# application/vnd.informix-visionary obsoleted by application/vnd.visionary
+application/vnd.infotech.project
+application/vnd.infotech.project+xml
+application/vnd.innopath.wamp.notification
+application/vnd.insors.igm igm
+application/vnd.intercon.formnet xpw xpx
+application/vnd.intergeo i2g
+application/vnd.intertrust.digibox
+application/vnd.intertrust.nncp
+application/vnd.intu.qbo qbo
+application/vnd.intu.qfx qfx
+application/vnd.iptc.g2.catalogitem+xml
+application/vnd.iptc.g2.conceptitem+xml
+application/vnd.iptc.g2.knowledgeitem+xml
+application/vnd.iptc.g2.newsitem+xml
+application/vnd.iptc.g2.newsmessage+xml
+application/vnd.iptc.g2.packageitem+xml
+application/vnd.iptc.g2.planningitem+xml
+application/vnd.ipunplugged.rcprofile rcprofile
+application/vnd.irepository.package+xml irp
+application/vnd.is-xpr xpr
+application/vnd.isac.fcs fcs
+application/vnd.jam jam
+application/vnd.japannet-directory-service
+application/vnd.japannet-jpnstore-wakeup
+application/vnd.japannet-payment-wakeup
+application/vnd.japannet-registration
+application/vnd.japannet-registration-wakeup
+application/vnd.japannet-setstore-wakeup
+application/vnd.japannet-verification
+application/vnd.japannet-verification-wakeup
+application/vnd.jcp.javame.midlet-rms rms
+application/vnd.jisp jisp
+application/vnd.joost.joda-archive joda
+application/vnd.jsk.isdn-ngn
+application/vnd.kahootz ktz ktr
+application/vnd.kde.karbon karbon
+application/vnd.kde.kchart chrt
+application/vnd.kde.kformula kfo
+application/vnd.kde.kivio flw
+application/vnd.kde.kontour kon
+application/vnd.kde.kpresenter kpr kpt
+application/vnd.kde.kspread ksp
+application/vnd.kde.kword kwd kwt
+application/vnd.kenameaapp htke
+application/vnd.kidspiration kia
+application/vnd.Kinar kne knp sdf
+application/vnd.koan skp skd skm skt
+application/vnd.kodak-descriptor sse
+application/vnd.las.las+json lasjson
+application/vnd.las.las+xml lasxml
+application/vnd.liberty-request+xml
+application/vnd.llamagraphics.life-balance.desktop lbd
+application/vnd.llamagraphics.life-balance.exchange+xml lbe
+application/vnd.lotus-1-2-3 123 wk4 wk3 wk1
+application/vnd.lotus-approach apr vew
+application/vnd.lotus-freelance prz pre
+application/vnd.lotus-notes nsf ntf ndl ns4 ns3 ns2 nsh nsg
+application/vnd.lotus-organizer or3 or2 org
+application/vnd.lotus-screencam scm
+application/vnd.lotus-wordpro lwp sam
+application/vnd.macports.portpkg portpkg
+application/vnd.mapbox-vector-tile mvt
+application/vnd.marlin.drm.actiontoken+xml
+application/vnd.marlin.drm.conftoken+xml
+application/vnd.marlin.drm.license+xml
+application/vnd.marlin.drm.mdcf mdc
+application/vnd.mason+json
+application/vnd.maxmind.maxmind-db mmdb
+application/vnd.mcd mcd
+application/vnd.medcalcdata mc1
+application/vnd.mediastation.cdkey cdkey
+application/vnd.meridian-slingshot
+application/vnd.MFER mwf
+application/vnd.mfmp mfm
+application/vnd.micro+json
+application/vnd.micrografx.flo flo
+application/vnd.micrografx.igx igx
+application/vnd.microsoft.portable-executable
+application/vnd.microsoft.windows.thumbnail-cache
+application/vnd.miele+json
+application/vnd.mif mif
+application/vnd.minisoft-hp3000-save
+application/vnd.mitsubishi.misty-guard.trustweb
+application/vnd.Mobius.DAF daf
+application/vnd.Mobius.DIS dis
+application/vnd.Mobius.MBK mbk
+application/vnd.Mobius.MQY mqy
+application/vnd.Mobius.MSL msl
+application/vnd.Mobius.PLC plc
+application/vnd.Mobius.TXF txf
+application/vnd.mophun.application mpn
+application/vnd.mophun.certificate mpc
+application/vnd.motorola.flexsuite
+application/vnd.motorola.flexsuite.adsi
+application/vnd.motorola.flexsuite.fis
+application/vnd.motorola.flexsuite.gotap
+application/vnd.motorola.flexsuite.kmr
+application/vnd.motorola.flexsuite.ttc
+application/vnd.motorola.flexsuite.wem
+application/vnd.motorola.iprm
+application/vnd.mozilla.xul+xml xul
+application/vnd.ms-3mfdocument 3mf
+application/vnd.ms-artgalry cil
+application/vnd.ms-asf asf
+application/vnd.ms-cab-compressed cab
+application/vnd.ms-excel xls xlm xla xlc xlt xlw
+application/vnd.ms-excel.template.macroEnabled.12 xltm
+application/vnd.ms-excel.addin.macroEnabled.12 xlam
+application/vnd.ms-excel.sheet.binary.macroEnabled.12 xlsb
+application/vnd.ms-excel.sheet.macroEnabled.12 xlsm
+application/vnd.ms-fontobject eot
+application/vnd.ms-htmlhelp chm
+application/vnd.ms-ims ims
+application/vnd.ms-lrm lrm
+application/vnd.ms-office.activeX+xml
+application/vnd.ms-officetheme thmx
+application/vnd.ms-playready.initiator+xml
+application/vnd.ms-powerpoint ppt pps pot
+application/vnd.ms-powerpoint.addin.macroEnabled.12 ppam
+application/vnd.ms-powerpoint.presentation.macroEnabled.12 pptm
+application/vnd.ms-powerpoint.slide.macroEnabled.12 sldm
+application/vnd.ms-powerpoint.slideshow.macroEnabled.12 ppsm
+application/vnd.ms-powerpoint.template.macroEnabled.12 potm
+application/vnd.ms-PrintDeviceCapabilities+xml
+application/vnd.ms-PrintSchemaTicket+xml
+application/vnd.ms-project mpp mpt
+application/vnd.ms-tnef tnef tnf
+application/vnd.ms-windows.devicepairing
+application/vnd.ms-windows.nwprinting.oob
+application/vnd.ms-windows.printerpairing
+application/vnd.ms-windows.wsd.oob
+application/vnd.ms-wmdrm.lic-chlg-req
+application/vnd.ms-wmdrm.lic-resp
+application/vnd.ms-wmdrm.meter-chlg-req
+application/vnd.ms-wmdrm.meter-resp
+application/vnd.ms-word.document.macroEnabled.12 docm
+application/vnd.ms-word.template.macroEnabled.12 dotm
+application/vnd.ms-works wcm wdb wks wps
+application/vnd.ms-wpl wpl
+application/vnd.ms-xpsdocument xps
+application/vnd.msa-disk-image msa
+application/vnd.mseq mseq
+application/vnd.msign
+application/vnd.multiad.creator crtr
+application/vnd.multiad.creator.cif cif
+application/vnd.music-niff
+application/vnd.musician mus
+application/vnd.muvee.style msty
+application/vnd.mynfc taglet
+application/vnd.ncd.control
+application/vnd.ncd.reference
+application/vnd.nearst.inv+json
+application/vnd.nervana entity request bkm kcm
+application/vnd.netfpx
+# ntf: application/vnd.lotus-notes
+application/vnd.nitf nitf
+application/vnd.neurolanguage.nlu nlu
+application/vnd.nintendo.nitro.rom nds
+application/vnd.nintendo.snes.rom sfc smc
+application/vnd.noblenet-directory nnd
+application/vnd.noblenet-sealer nns
+application/vnd.noblenet-web nnw
+application/vnd.nokia.catalogs
+application/vnd.nokia.conml+wbxml
+application/vnd.nokia.conml+xml
+application/vnd.nokia.iptv.config+xml
+application/vnd.nokia.iSDS-radio-presets
+application/vnd.nokia.landmark+wbxml
+application/vnd.nokia.landmark+xml
+application/vnd.nokia.landmarkcollection+xml
+application/vnd.nokia.n-gage.ac+xml ac
+application/vnd.nokia.n-gage.data ngdat
+application/vnd.nokia.n-gage.symbian.install n-gage
+application/vnd.nokia.ncd
+application/vnd.nokia.pcd+wbxml
+application/vnd.nokia.pcd+xml
+application/vnd.nokia.radio-preset rpst
+application/vnd.nokia.radio-presets rpss
+application/vnd.novadigm.EDM edm
+application/vnd.novadigm.EDX edx
+application/vnd.novadigm.EXT ext
+application/vnd.ntt-local.content-share
+application/vnd.ntt-local.file-transfer
+application/vnd.ntt-local.ogw_remote-access
+application/vnd.ntt-local.sip-ta_remote
+application/vnd.ntt-local.sip-ta_tcp_stream
+application/vnd.oasis.opendocument.chart odc
+application/vnd.oasis.opendocument.chart-template otc
+application/vnd.oasis.opendocument.database odb
+application/vnd.oasis.opendocument.formula odf
+# otf: font/otf
+application/vnd.oasis.opendocument.formula-template
+application/vnd.oasis.opendocument.graphics odg
+application/vnd.oasis.opendocument.graphics-template otg
+application/vnd.oasis.opendocument.image odi
+application/vnd.oasis.opendocument.image-template oti
+application/vnd.oasis.opendocument.presentation odp
+application/vnd.oasis.opendocument.presentation-template otp
+application/vnd.oasis.opendocument.spreadsheet ods
+application/vnd.oasis.opendocument.spreadsheet-template ots
+application/vnd.oasis.opendocument.text odt
+application/vnd.oasis.opendocument.text-master odm
+application/vnd.oasis.opendocument.text-template ott
+application/vnd.oasis.opendocument.text-web oth
+application/vnd.obn
+application/vnd.ocf+cbor
+application/vnd.oftn.l10n+json
+application/vnd.oipf.contentaccessdownload+xml
+application/vnd.oipf.contentaccessstreaming+xml
+application/vnd.oipf.cspg-hexbinary
+application/vnd.oipf.dae.svg+xml
+application/vnd.oipf.dae.xhtml+xml
+application/vnd.oipf.mippvcontrolmessage+xml
+application/vnd.oipf.pae.gem
+application/vnd.oipf.spdiscovery+xml
+application/vnd.oipf.spdlist+xml
+application/vnd.oipf.ueprofile+xml
+application/vnd.olpc-sugar xo
+application/vnd.oma.bcast.associated-procedure-parameter+xml
+application/vnd.oma.bcast.drm-trigger+xml
+application/vnd.oma.bcast.imd+xml
+application/vnd.oma.bcast.ltkm
+application/vnd.oma.bcast.notification+xml
+application/vnd.oma.bcast.provisioningtrigger
+application/vnd.oma.bcast.sgboot
+application/vnd.oma.bcast.sgdd+xml
+application/vnd.oma.bcast.sgdu
+application/vnd.oma.bcast.simple-symbol-container
+application/vnd.oma.bcast.smartcard-trigger+xml
+application/vnd.oma.bcast.sprov+xml
+application/vnd.oma.bcast.stkm
+application/vnd.oma.cab-address-book+xml
+application/vnd.oma.cab-feature-handler+xml
+application/vnd.oma.cab-pcc+xml
+application/vnd.oma.cab-subs-invite+xml
+application/vnd.oma.cab-user-prefs+xml
+application/vnd.oma.dcd
+application/vnd.oma.dcdc
+application/vnd.oma.dd2+xml dd2
+application/vnd.oma.drm.risd+xml
+application/vnd.oma.group-usage-list+xml
+application/vnd.oma.lwm2m+json
+application/vnd.oma.lwm2m+tlv
+application/vnd.oma.pal+xml
+application/vnd.oma.poc.detailed-progress-report+xml
+application/vnd.oma.poc.final-report+xml
+application/vnd.oma.poc.groups+xml
+application/vnd.oma.poc.invocation-descriptor+xml
+application/vnd.oma.poc.optimized-progress-report+xml
+application/vnd.oma.push
+application/vnd.oma.scidm.messages+xml
+application/vnd.oma.xcap-directory+xml
+application/vnd.oma-scws-config
+application/vnd.oma-scws-http-request
+application/vnd.oma-scws-http-response
+application/vnd.omads-email+xml
+application/vnd.omads-file+xml
+application/vnd.omads-folder+xml
+application/vnd.omaloc-supl-init
+application/vnd.onepager tam
+application/vnd.onepagertamp tamp
+application/vnd.onepagertamx tamx
+application/vnd.onepagertat tat
+application/vnd.onepagertatp tatp
+application/vnd.onepagertatx tatx
+application/vnd.openblox.game+xml obgx
+application/vnd.openblox.game-binary obg
+application/vnd.openeye.oeb oeb
+application/vnd.openofficeorg.extension oxt
+application/vnd.openstreetmap.data+xml osm
+application/vnd.openxmlformats-officedocument.custom-properties+xml
+application/vnd.openxmlformats-officedocument.customXmlProperties+xml
+application/vnd.openxmlformats-officedocument.drawing+xml
+application/vnd.openxmlformats-officedocument.drawingml.chart+xml
+application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml
+application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml
+application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml
+application/vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml
+application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml
+application/vnd.openxmlformats-officedocument.extended-properties+xml
+application/vnd.openxmlformats-officedocument.presentationml.commentAuthors+xml
+application/vnd.openxmlformats-officedocument.presentationml.comments+xml
+application/vnd.openxmlformats-officedocument.presentationml.handoutMaster+xml
+application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml
+application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml
+application/vnd.openxmlformats-officedocument.presentationml.presProps+xml
+application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
+application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml
+application/vnd.openxmlformats-officedocument.presentationml.slide sldx
+application/vnd.openxmlformats-officedocument.presentationml.slide+xml
+application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml
+application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml
+application/vnd.openxmlformats-officedocument.presentationml.slideUpdateInfo+xml
+application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx
+application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml
+application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml
+application/vnd.openxmlformats-officedocument.presentationml.tags+xml
+application/vnd.openxmlformats-officedocument.presentationml.template potx
+application/vnd.openxmlformats-officedocument.presentationml.template.main+xml
+application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.revisionHeaders+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
+application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.tableSingleCells+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx
+application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.volatileDependencies+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml
+application/vnd.openxmlformats-officedocument.theme+xml
+application/vnd.openxmlformats-officedocument.themeOverride+xml
+application/vnd.openxmlformats-officedocument.vmlDrawing
+application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
+application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx
+application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml
+application/vnd.openxmlformats-package.core-properties+xml
+application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml
+application/vnd.openxmlformats-package.relationships+xml
+application/vnd.oracle.resource+json
+application/vnd.orange.indata
+application/vnd.osa.netdeploy ndc
+application/vnd.osgeo.mapguide.package mgp
+# jar: application/x-java-archive
+application/vnd.osgi.bundle
+application/vnd.osgi.dp dp
+application/vnd.osgi.subsystem esa
+application/vnd.otps.ct-kip+xml
+application/vnd.oxli.countgraph oxlicg
+application/vnd.pagerduty+json
+application/vnd.palm prc pdb pqa oprc
+application/vnd.panoply plp
+application/vnd.paos+xml
+application/vnd.pawaafile paw
+application/vnd.pcos
+application/vnd.pg.format str
+application/vnd.pg.osasli ei6
+application/vnd.piaccess.application-license pil
+application/vnd.picsel efif
+application/vnd.pmi.widget wg
+application/vnd.poc.group-advertisement+xml
+application/vnd.pocketlearn plf
+application/vnd.powerbuilder6 pbd
+application/vnd.powerbuilder6-s
+application/vnd.powerbuilder7
+application/vnd.powerbuilder7-s
+application/vnd.powerbuilder75
+application/vnd.powerbuilder75-s
+application/vnd.preminet preminet
+application/vnd.previewsystems.box box vbox
+application/vnd.proteus.magazine mgz
+application/vnd.publishare-delta-tree qps
+# pti: image/prs.pti
+application/vnd.pvi.ptid1 ptid
+application/vnd.pwg-multiplexed
+application/vnd.pwg-xhtml-print+xml
+application/vnd.qualcomm.brew-app-res bar
+application/vnd.quarantainenet
+application/vnd.Quark.QuarkXPress qxd qxt qwd qwt qxl qxb
+application/vnd.quobject-quoxdocument quox quiz
+application/vnd.radisys.moml+xml
+application/vnd.radisys.msml-audit-conf+xml
+application/vnd.radisys.msml-audit-conn+xml
+application/vnd.radisys.msml-audit-dialog+xml
+application/vnd.radisys.msml-audit-stream+xml
+application/vnd.radisys.msml-audit+xml
+application/vnd.radisys.msml-conf+xml
+application/vnd.radisys.msml-dialog-base+xml
+application/vnd.radisys.msml-dialog-fax-detect+xml
+application/vnd.radisys.msml-dialog-fax-sendrecv+xml
+application/vnd.radisys.msml-dialog-group+xml
+application/vnd.radisys.msml-dialog-speech+xml
+application/vnd.radisys.msml-dialog-transform+xml
+application/vnd.radisys.msml-dialog+xml
+application/vnd.radisys.msml+xml
+application/vnd.rainstor.data tree
+application/vnd.rapid
+application/vnd.rar rar
+application/vnd.realvnc.bed bed
+application/vnd.recordare.musicxml mxl
+application/vnd.recordare.musicxml+xml
+application/vnd.RenLearn.rlprint
+application/vnd.rig.cryptonote cryptonote
+application/vnd.route66.link66+xml link66
+# gbr: application/rpki-ghostbusters
+application/vnd.rs-274x
+application/vnd.ruckus.download
+application/vnd.s3sms
+application/vnd.sailingtracker.track st
+application/vnd.sbm.cid
+application/vnd.sbm.mid2
+application/vnd.scribus scd sla slaz
+application/vnd.sealed.3df s3df
+application/vnd.sealed.csf scsf
+application/vnd.sealed.doc sdoc sdo s1w
+application/vnd.sealed.eml seml sem
+application/vnd.sealed.mht smht smh
+application/vnd.sealed.net
+# spp: application/scvp-vp-response
+application/vnd.sealed.ppt sppt s1p
+application/vnd.sealed.tiff stif
+application/vnd.sealed.xls sxls sxl s1e
+# stm: audio/x-stm
+application/vnd.sealedmedia.softseal.html stml s1h
+application/vnd.sealedmedia.softseal.pdf spdf spd s1a
+application/vnd.seemail see
+application/vnd.sema sema
+application/vnd.semd semd
+application/vnd.semf semf
+application/vnd.shana.informed.formdata ifm
+application/vnd.shana.informed.formtemplate itp
+application/vnd.shana.informed.interchange iif
+application/vnd.shana.informed.package ipk
+application/vnd.SimTech-MindMapper twd twds
+application/vnd.siren+json
+application/vnd.smaf mmf
+application/vnd.smart.notebook notebook
+application/vnd.smart.teacher teacher
+application/vnd.software602.filler.form+xml fo
+application/vnd.software602.filler.form-xml-zip zfo
+application/vnd.solent.sdkm+xml sdkm sdkd
+application/vnd.spotfire.dxp dxp
+application/vnd.spotfire.sfs sfs
+application/vnd.sss-cod
+application/vnd.sss-dtf
+application/vnd.sss-ntf
+application/vnd.stepmania.package smzip
+application/vnd.stepmania.stepchart sm
+application/vnd.street-stream
+application/vnd.sun.wadl+xml wadl
+application/vnd.sus-calendar sus susp
+application/vnd.svd
+application/vnd.swiftview-ics
+application/vnd.syncml+xml xsm
+application/vnd.syncml.dm+wbxml bdm
+application/vnd.syncml.dm+xml xdm
+application/vnd.syncml.dm.notification
+application/vnd.syncml.dmddf+wbxml
+application/vnd.syncml.dmddf+xml ddf
+application/vnd.syncml.dmtnds+wbxml
+application/vnd.syncml.dmtnds+xml
+application/vnd.syncml.ds.notification
+application/vnd.tableschema+json
+application/vnd.tao.intent-module-archive tao
+application/vnd.tcpdump.pcap pcap cap dmp
+application/vnd.theqvd qvd
+application/vnd.tmd.mediaflex.api+xml
+application/vnd.tml vfr viaframe
+application/vnd.tmobile-livetv tmo
+application/vnd.tri.onesource
+application/vnd.trid.tpt tpt
+application/vnd.triscape.mxs mxs
+application/vnd.trueapp tra
+application/vnd.truedoc
+# cab: application/vnd.ms-cab-compressed
+application/vnd.ubisoft.webplayer
+application/vnd.ufdl ufdl ufd frm
+application/vnd.uiq.theme utz
+application/vnd.umajin umj
+application/vnd.unity unityweb
+application/vnd.uoml+xml uoml uo
+application/vnd.uplanet.alert
+application/vnd.uplanet.alert-wbxml
+application/vnd.uplanet.bearer-choice
+application/vnd.uplanet.bearer-choice-wbxml
+application/vnd.uplanet.cacheop
+application/vnd.uplanet.cacheop-wbxml
+application/vnd.uplanet.channel
+application/vnd.uplanet.channel-wbxml
+application/vnd.uplanet.list
+application/vnd.uplanet.list-wbxml
+application/vnd.uplanet.listcmd
+application/vnd.uplanet.listcmd-wbxml
+application/vnd.uplanet.signal
+application/vnd.uri-map urim urimap
+application/vnd.valve.source.material vmt
+application/vnd.vcx vcx
+# sxi: application/vnd.sun.xml.impress
+application/vnd.vd-study mxi study-inter model-inter
+# mcd: application/vnd.mcd
+application/vnd.vectorworks vwx
+application/vnd.vel+json
+application/vnd.verimatrix.vcas
+application/vnd.vidsoft.vidconference vsc
+application/vnd.visio vsd vst vsw vss
+application/vnd.visionary vis
+# vsc: application/vnd.vidsoft.vidconference
+application/vnd.vividence.scriptfile
+application/vnd.vsf vsf
+application/vnd.wap.sic sic
+application/vnd.wap.slc slc
+application/vnd.wap.wbxml wbxml
+application/vnd.wap.wmlc wmlc
+application/vnd.wap.wmlscriptc wmlsc
+application/vnd.webturbo wtb
+application/vnd.wfa.p2p p2p
+application/vnd.wfa.wsc wsc
+application/vnd.windows.devicepairing
+application/vnd.wmc wmc
+application/vnd.wmf.bootstrap
+# nb: application/mathematica for now
+application/vnd.wolfram.mathematica
+application/vnd.wolfram.mathematica.package m
+application/vnd.wolfram.player nbp
+application/vnd.wordperfect wpd
+application/vnd.wqd wqd
+application/vnd.wrq-hp3000-labelled
+application/vnd.wt.stf stf
+application/vnd.wv.csp+xml
+application/vnd.wv.csp+wbxml wv
+application/vnd.wv.ssp+xml
+application/vnd.xacml+json
+application/vnd.xara xar
+application/vnd.xfdl xfdl xfd
+application/vnd.xfdl.webform
+application/vnd.xmi+xml
+application/vnd.xmpie.cpkg cpkg
+application/vnd.xmpie.dpkg dpkg
+# dpkg: application/vnd.xmpie.dpkg
+application/vnd.xmpie.plan
+application/vnd.xmpie.ppkg ppkg
+application/vnd.xmpie.xlim xlim
+application/vnd.yamaha.hv-dic hvd
+application/vnd.yamaha.hv-script hvs
+application/vnd.yamaha.hv-voice hvp
+application/vnd.yamaha.openscoreformat osf
+application/vnd.yamaha.openscoreformat.osfpvg+xml
+application/vnd.yamaha.remote-setup
+application/vnd.yamaha.smaf-audio saf
+application/vnd.yamaha.smaf-phrase spf
+application/vnd.yamaha.through-ngn
+application/vnd.yamaha.tunnel-udpencap
+application/vnd.yaoweme yme
+application/vnd.yellowriver-custom-menu cmp
+application/vnd.zul zir zirz
+application/vnd.zzazz.deck+xml zaz
+application/voicexml+xml vxml
+application/vq-rtcp-xr
+application/watcherinfo+xml wif
+application/whoispp-query
+application/whoispp-response
+application/widget wgt
+application/wita
+application/wordperfect5.1
+application/wsdl+xml wsdl
+application/wspolicy+xml wspolicy
+# yes, this *is* IANA registered despite of x-
+application/x-www-form-urlencoded
+application/x400-bp
+application/xacml+xml
+application/xcap-att+xml xav
+application/xcap-caps+xml xca
+application/xcap-diff+xml xdf
+application/xcap-el+xml xel
+application/xcap-error+xml xer
+application/xcap-ns+xml xns
+application/xcon-conference-info-diff+xml
+application/xcon-conference-info+xml
+application/xenc+xml
+application/xhtml+xml xhtml xhtm xht
+# xml, xsd, rng: text/xml
+application/xml
+# mod: audio/x-mod
+application/xml-dtd dtd
+# ent: text/xml-external-parsed-entity
+application/xml-external-parsed-entity
+application/xml-patch+xml
+application/xmpp+xml
+application/xop+xml xop
+application/xslt+xml xsl xslt
+application/xv+xml mxml xhvml xvml xvm
+application/yang yang
+application/yang-data+json
+application/yang-data+xml
+application/yang-patch+json
+application/yang-patch+xml
+application/yin+xml yin
+application/zip zip
+application/zlib
+audio/1d-interleaved-parityfec
+audio/32kadpcm 726
+# 3gp, 3gpp: video/3gpp
+audio/3gpp
+# 3g2, 3gpp2: video/3gpp2
+audio/3gpp2
+audio/ac3 ac3
+audio/AMR amr
+audio/AMR-WB awb
+audio/amr-wb+
+audio/aptx
+audio/asc acn
+# aa3, omg: audio/ATRAC3
+audio/ATRAC-ADVANCED-LOSSLESS aal
+# aa3, omg: audio/ATRAC3
+audio/ATRAC-X atx
+audio/ATRAC3 at3 aa3 omg
+audio/basic au snd
+audio/BV16
+audio/BV32
+audio/clearmode
+audio/CN
+audio/DAT12
+audio/dls dls
+audio/dsr-es201108
+audio/dsr-es202050
+audio/dsr-es202211
+audio/dsr-es202212
+audio/DV
+audio/DVI4
+audio/eac3
+audio/encaprtp
+audio/EVRC evc
+# qcp: audio/qcelp
+audio/EVRC-QCP
+audio/EVRC0
+audio/EVRC1
+audio/EVRCB evb
+audio/EVRCB0
+audio/EVRCB1
+audio/EVRCNW enw
+audio/EVRCNW0
+audio/EVRCNW1
+audio/EVRCWB evw
+audio/EVRCWB0
+audio/EVRCWB1
+audio/EVS
+audio/example
+audio/fwdred
+audio/G711-0
+audio/G719
+audio/G722
+audio/G7221
+audio/G723
+audio/G726-16
+audio/G726-24
+audio/G726-32
+audio/G726-40
+audio/G728
+audio/G729
+audio/G7291
+audio/G729D
+audio/G729E
+audio/GSM
+audio/GSM-EFR
+audio/GSM-HR-08
+audio/iLBC lbc
+audio/ip-mr_v2.5
+# wav: audio/x-wav
+audio/L16 l16
+audio/L20
+audio/L24
+audio/L8
+audio/LPC
+audio/MELP
+audio/MELP600
+audio/MELP1200
+audio/MELP2400
+audio/mobile-xmf mxmf
+# mp4, mpg4: video/mp4, see RFC 4337
+audio/mp4 m4a
+audio/MP4A-LATM
+audio/MPA
+audio/mpa-robust
+audio/mpeg mp3 mpga mp1 mp2
+audio/mpeg4-generic
+audio/ogg oga ogg opus spx
+audio/opus
+audio/parityfec
+audio/PCMA
+audio/PCMA-WB
+audio/PCMU
+audio/PCMU-WB
+audio/prs.sid sid psid
+audio/qcelp qcp
+audio/raptorfec
+audio/RED
+audio/rtp-enc-aescm128
+audio/rtp-midi
+audio/rtploopback
+audio/rtx
+audio/SMV smv
+# qcp: audio/qcelp, see RFC 3625
+audio/SMV-QCP
+audio/SMV0
+# mid: audio/midi
+audio/sp-midi
+audio/speex
+audio/t140c
+audio/t38
+audio/telephone-event
+audio/tone
+audio/UEMCLIP
+audio/ulpfec
+audio/VDVI
+audio/VMR-WB
+audio/vnd.3gpp.iufp
+audio/vnd.4SB
+audio/vnd.audikoz koz
+audio/vnd.CELP
+audio/vnd.cisco.nse
+audio/vnd.cmles.radio-events
+audio/vnd.cns.anp1
+audio/vnd.cns.inf1
+audio/vnd.dece.audio uva uvva
+audio/vnd.digital-winds eol
+audio/vnd.dlna.adts
+audio/vnd.dolby.heaac.1
+audio/vnd.dolby.heaac.2
+audio/vnd.dolby.mlp mlp
+audio/vnd.dolby.mps
+audio/vnd.dolby.pl2
+audio/vnd.dolby.pl2x
+audio/vnd.dolby.pl2z
+audio/vnd.dolby.pulse.1
+audio/vnd.dra
+# wav: audio/x-wav, cpt: application/mac-compactpro
+audio/vnd.dts dts
+audio/vnd.dts.hd dtshd
+# dvb: video/vnd.dvb.file
+audio/vnd.dvb.file
+audio/vnd.everad.plj plj
+# rm: audio/x-pn-realaudio
+audio/vnd.hns.audio
+audio/vnd.lucent.voice lvp
+audio/vnd.ms-playready.media.pya pya
+# mxmf: audio/mobile-xmf
+audio/vnd.nokia.mobile-xmf
+audio/vnd.nortel.vbk vbk
+audio/vnd.nuera.ecelp4800 ecelp4800
+audio/vnd.nuera.ecelp7470 ecelp7470
+audio/vnd.nuera.ecelp9600 ecelp9600
+audio/vnd.octel.sbc
+# audio/vnd.qcelp deprecated in favour of audio/qcelp
+audio/vnd.rhetorex.32kadpcm
+audio/vnd.rip rip
+audio/vnd.sealedmedia.softseal.mpeg smp3 smp s1m
+audio/vnd.vmx.cvsd
+audio/vorbis
+audio/vorbis-config
+font/collection ttc
+font/otf otf
+font/sfnt
+font/ttf ttf
+font/woff woff
+font/woff2 woff2
+image/bmp bmp dib
+image/cgm cgm
+image/dicom-rle drle
+image/emf emf
+image/example
+image/fits fits fit fts
+image/g3fax
+image/gif gif
+image/ief ief
+image/jls jls
+image/jp2 jp2 jpg2
+image/jpeg jpg jpeg jpe jfif
+image/jpm jpm jpgm
+image/jpx jpx jpf
+image/ktx ktx
+image/naplps
+image/png png
+image/prs.btif btif btf
+image/prs.pti pti
+image/pwg-raster
+image/svg+xml svg svgz
+image/t38 t38
+image/tiff tiff tif
+image/tiff-fx tfx
+image/vnd.adobe.photoshop psd
+image/vnd.airzip.accelerator.azv azv
+image/vnd.cns.inf2
+image/vnd.dece.graphic uvi uvvi uvg uvvg
+image/vnd.djvu djvu djv
+# sub: text/vnd.dvb.subtitle
+image/vnd.dvb.subtitle
+image/vnd.dwg dwg
+image/vnd.dxf dxf
+image/vnd.fastbidsheet fbs
+image/vnd.fpx fpx
+image/vnd.fst fst
+image/vnd.fujixerox.edmics-mmr mmr
+image/vnd.fujixerox.edmics-rlc rlc
+image/vnd.globalgraphics.pgb pgb
+image/vnd.microsoft.icon ico
+image/vnd.mix
+image/vnd.mozilla.apng apng
+image/vnd.ms-modi mdi
+image/vnd.net-fpx
+image/vnd.radiance hdr rgbe xyze
+image/vnd.sealed.png spng spn s1n
+image/vnd.sealedmedia.softseal.gif sgif sgi s1g
+image/vnd.sealedmedia.softseal.jpg sjpg sjp s1j
+image/vnd.svf
+image/vnd.tencent.tap tap
+image/vnd.valve.source.texture vtf
+image/vnd.wap.wbmp wbmp
+image/vnd.xiff xif
+image/vnd.zbrush.pcx pcx
+image/wmf wmf
+message/CPIM
+message/delivery-status
+message/disposition-notification
+message/example
+message/external-body
+message/feedback-report
+message/global u8msg
+message/global-delivery-status u8dsn
+message/global-disposition-notification u8mdn
+message/global-headers u8hdr
+message/http
+# cl: application/simple-filter+xml
+message/imdn+xml
+# message/news obsoleted by message/rfc822
+message/partial
+message/rfc822 eml mail art
+message/s-http
+message/sip
+message/sipfrag
+message/tracking-status
+message/vnd.si.simp
+# wsc: application/vnd.wfa.wsc
+message/vnd.wfa.wsc
+model/example
+model/gltf+json gltf
+model/iges igs iges
+model/mesh msh mesh silo
+model/vnd.collada+xml dae
+model/vnd.dwf dwf
+# 3dml, 3dm: text/vnd.in3d.3dml
+model/vnd.flatland.3dml
+model/vnd.gdl gdl gsm win dor lmp rsm msm ism
+model/vnd.gs-gdl
+model/vnd.gtw gtw
+model/vnd.moml+xml moml
+model/vnd.mts mts
+model/vnd.opengex ogex
+model/vnd.parasolid.transmit.binary x_b xmt_bin
+model/vnd.parasolid.transmit.text x_t xmt_txt
+model/vnd.rosette.annotated-data-model
+model/vnd.valve.source.compiled-map bsp
+model/vnd.vtu vtu
+model/vrml wrl vrml
+# x3db: model/x3d+xml
+model/x3d+fastinfoset
+# x3d: application/vnd.hzn-3d-crossword
+model/x3d+xml x3db
+model/x3d-vrml x3dv x3dvz
+multipart/alternative
+multipart/appledouble
+multipart/byteranges
+multipart/digest
+multipart/encrypted
+multipart/form-data
+multipart/header-set
+multipart/mixed
+multipart/parallel
+multipart/related
+multipart/report
+multipart/signed
+multipart/vnd.bint.med-plus bmed
+multipart/voice-message vpm
+multipart/x-mixed-replace
+text/1d-interleaved-parityfec
+text/cache-manifest appcache manifest
+text/calendar ics ifb
+text/css css
+text/csv csv
+text/csv-schema csvs
+text/directory
+text/dns soa zone
+text/encaprtp
+# text/ecmascript obsoleted by application/ecmascript
+text/enriched
+text/example
+text/fwdred
+text/grammar-ref-list
+text/html html htm
+# text/javascript obsoleted by application/javascript
+text/jcr-cnd cnd
+text/markdown markdown md
+text/mizar miz
+text/n3 n3
+text/parameters
+text/parityfec
+text/plain txt asc text pm el c h cc hh cxx hxx f90 conf log
+text/provenance-notation provn
+text/prs.fallenstein.rst rst
+text/prs.lines.tag tag dsc
+text/prs.prop.logic
+text/raptorfec
+text/RED
+text/rfc822-headers
+text/richtext rtx
+# rtf: application/rtf
+text/rtf
+text/rtp-enc-aescm128
+text/rtploopback
+text/rtx
+text/sgml sgml sgm
+text/strings
+text/t140
+text/tab-separated-values tsv
+text/troff t tr roff
+text/turtle ttl
+text/ulpfec
+text/uri-list uris uri
+text/vcard vcf vcard
+text/vnd.a a
+text/vnd.abc abc
+text/vnd.ascii-art ascii
+# curl: application/vnd.curl
+text/vnd.curl
+text/vnd.debian.copyright copyright
+text/vnd.DMClientScript dms
+text/vnd.dvb.subtitle sub
+text/vnd.esmertec.theme-descriptor jtd
+text/vnd.fly fly
+text/vnd.fmi.flexstor flx
+text/vnd.graphviz gv dot
+text/vnd.in3d.3dml 3dml 3dm
+text/vnd.in3d.spot spot spo
+text/vnd.IPTC.NewsML
+text/vnd.IPTC.NITF
+text/vnd.latex-z
+text/vnd.motorola.reflex
+text/vnd.ms-mediapackage mpf
+text/vnd.net2phone.commcenter.command ccc
+text/vnd.radisys.msml-basic-layout
+text/vnd.si.uricatalogue uric
+text/vnd.sun.j2me.app-descriptor jad
+text/vnd.trolltech.linguist ts
+text/vnd.wap.si si
+text/vnd.wap.sl sl
+text/vnd.wap.wml wml
+text/vnd.wap.wmlscript wmls
+text/xml xml xsd rng
+text/xml-external-parsed-entity ent
+video/1d-interleaved-parityfec
+video/3gpp 3gp 3gpp
+video/3gpp2 3g2 3gpp2
+video/3gpp-tt
+video/BMPEG
+video/BT656
+video/CelB
+video/DV
+video/encaprtp
+video/example
+video/H261
+video/H263
+video/H263-1998
+video/H263-2000
+video/H264
+video/H264-RCDO
+video/H264-SVC
+video/H265
+video/iso.segment m4s
+video/JPEG
+video/jpeg2000
+video/mj2 mj2 mjp2
+video/MP1S
+video/MP2P
+video/MP2T
+video/mp4 mp4 mpg4 m4v
+video/MP4V-ES
+video/mpeg mpeg mpg mpe m1v m2v
+video/mpeg4-generic
+video/MPV
+video/nv
+video/ogg ogv
+video/parityfec
+video/pointer
+video/quicktime mov qt
+video/raptorfec
+video/raw
+video/rtp-enc-aescm128
+video/rtploopback
+video/rtx
+video/SMPTE292M
+video/ulpfec
+video/vc1
+video/vnd.CCTV
+video/vnd.dece.hd uvh uvvh
+video/vnd.dece.mobile uvm uvvm
+video/vnd.dece.mp4 uvu uvvu
+video/vnd.dece.pd uvp uvvp
+video/vnd.dece.sd uvs uvvs
+video/vnd.dece.video uvv uvvv
+video/vnd.directv.mpeg
+video/vnd.directv.mpeg-tts
+video/vnd.dlna.mpeg-tts
+video/vnd.dvb.file dvb
+video/vnd.fvt fvt
+# rm: audio/x-pn-realaudio
+video/vnd.hns.video
+video/vnd.iptvforum.1dparityfec-1010
+video/vnd.iptvforum.1dparityfec-2005
+video/vnd.iptvforum.2dparityfec-1010
+video/vnd.iptvforum.2dparityfec-2005
+video/vnd.iptvforum.ttsavc
+video/vnd.iptvforum.ttsmpeg2
+video/vnd.motorola.video
+video/vnd.motorola.videop
+video/vnd.mpegurl mxu m4u
+video/vnd.ms-playready.media.pyv pyv
+video/vnd.nokia.interleaved-multimedia nim
+video/vnd.nokia.videovoip
+# mp4: video/mp4
+video/vnd.objectvideo
+video/vnd.radgamettools.bink bik bk2
+video/vnd.radgamettools.smacker smk
+video/vnd.sealed.mpeg1 smpg s11
+# smpg: video/vnd.sealed.mpeg1
+video/vnd.sealed.mpeg4 s14
+video/vnd.sealed.swf sswf ssw
+video/vnd.sealedmedia.softseal.mov smov smo s1q
+# uvu, uvvu: video/vnd.dece.mp4
+video/vnd.uvvu.mp4
+video/vnd.vivo viv
+video/VP8
+
+# Non-IANA types
+
+application/mac-compactpro cpt
+application/metalink+xml metalink
+application/owl+xml owx
+application/rss+xml rss
+application/vnd.android.package-archive apk
+application/vnd.oma.dd+xml dd
+application/vnd.oma.drm.content dcf
+# odf: application/vnd.oasis.opendocument.formula
+application/vnd.oma.drm.dcf o4a o4v
+application/vnd.oma.drm.message dm
+application/vnd.oma.drm.rights+wbxml drc
+application/vnd.oma.drm.rights+xml dr
+application/vnd.sun.xml.calc sxc
+application/vnd.sun.xml.calc.template stc
+application/vnd.sun.xml.draw sxd
+application/vnd.sun.xml.draw.template std
+application/vnd.sun.xml.impress sxi
+application/vnd.sun.xml.impress.template sti
+application/vnd.sun.xml.math sxm
+application/vnd.sun.xml.writer sxw
+application/vnd.sun.xml.writer.global sxg
+application/vnd.sun.xml.writer.template stw
+application/vnd.symbian.install sis
+application/vnd.wap.mms-message mms
+application/x-annodex anx
+application/x-bcpio bcpio
+application/x-bittorrent torrent
+application/x-bzip2 bz2
+application/x-cdlink vcd
+application/x-chrome-extension crx
+application/x-cpio cpio
+application/x-csh csh
+application/x-director dcr dir dxr
+application/x-dvi dvi
+application/x-futuresplash spl
+application/x-gtar gtar
+application/x-hdf hdf
+application/x-java-archive jar
+application/x-java-jnlp-file jnlp
+application/x-java-pack200 pack
+application/x-killustrator kil
+application/x-latex latex
+application/x-netcdf nc cdf
+application/x-perl pl
+application/x-rpm rpm
+application/x-sh sh
+application/x-shar shar
+application/x-stuffit sit
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-texinfo texinfo texi
+application/x-troff-man man 1 2 3 4 5 6 7 8
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-wais-source src
+application/x-xpinstall xpi
+application/x-xspf+xml xspf
+application/x-xz xz
+audio/midi mid midi kar
+audio/x-aiff aif aiff aifc
+audio/x-annodex axa
+audio/x-flac flac
+audio/x-matroska mka
+audio/x-mod mod ult uni m15 mtm 669 med
+audio/x-mpegurl m3u
+audio/x-ms-wax wax
+audio/x-ms-wma wma
+audio/x-pn-realaudio ram rm
+audio/x-realaudio ra
+audio/x-s3m s3m
+audio/x-stm stm
+audio/x-wav wav
+chemical/x-xyz xyz
+image/webp webp
+image/x-cmu-raster ras
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-targa tga
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+text/html-sandboxed sandboxed
+text/x-pod pod
+text/x-setext etx
+video/webm webm
+video/x-annodex axv
+video/x-flv flv
+video/x-javafx fxm
+video/x-matroska mkv
+video/x-matroska-3d mk3d
+video/x-ms-asf asx
+video/x-ms-wm wm
+video/x-ms-wmv wmv
+video/x-ms-wmx wmx
+video/x-ms-wvx wvx
+video/x-msvideo avi
+video/x-sgi-movie movie
+x-conference/x-cooltalk ice
+x-epoc/x-sisx-app sisx
diff --git a/release-please-config.json b/release-please-config.json
new file mode 100644
index 0000000..810f857
--- /dev/null
+++ b/release-please-config.json
@@ -0,0 +1,22 @@
+{
+ "packages": {
+ ".": {
+ "changelog-path": "CHANGELOG.md",
+ "initial-version": "0.1.0",
+ "release-type": "simple",
+ "extra-files": [
+ {
+ "type": "yaml",
+ "path": "charts/ingress-deafult-backend/Chart.yaml",
+ "jsonpath": "$.version"
+ },
+ {
+ "type": "yaml",
+ "path": "charts/ingress-deafult-backend/Chart.yaml",
+ "jsonpath": "$.appVersion"
+ }
+ ]
+ }
+ },
+ "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
+}
diff --git a/router.go b/router.go
new file mode 100644
index 0000000..ce3bae1
--- /dev/null
+++ b/router.go
@@ -0,0 +1,49 @@
+package main
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "net/http"
+ "time"
+
+ "github.com/rs/zerolog/log"
+ "github.com/urfave/negroni"
+)
+
+type RouteMapper func(mux *http.ServeMux)
+
+func NewRouter(handlers ...RouteMapper) *negroni.Negroni {
+ mux := http.NewServeMux()
+ for _, handler := range handlers {
+ handler(mux)
+ }
+
+ return negroni.New(
+ negroni.NewRecovery(),
+ NewZerologRequestIdMiddleware(),
+ NewLoggingMiddleware(),
+ negroni.Wrap(mux),
+ )
+}
+
+func Serve(ctx context.Context, port int, router http.Handler) error {
+
+ s := &http.Server{
+ Handler: router,
+ Addr: fmt.Sprintf(":%d", port),
+ }
+ go func() {
+
+ if err := s.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
+ log.Ctx(ctx).Fatal().Msg(err.Error())
+ }
+ }()
+
+ <-ctx.Done()
+
+ shutdownCtx, cancel := context.WithTimeout(context.WithoutCancel(ctx), 10*time.Second)
+ defer cancel()
+
+ return s.Shutdown(shutdownCtx)
+}
diff --git a/www/404.html b/www/404.html
new file mode 100644
index 0000000..2a1bca3
--- /dev/null
+++ b/www/404.html
@@ -0,0 +1 @@
+4xx html
diff --git a/www/4xx.html b/www/4xx.html
new file mode 100644
index 0000000..9e6e0c7
--- /dev/null
+++ b/www/4xx.html
@@ -0,0 +1 @@
+The page you're looking for could not be found.
diff --git a/www/4xx.json b/www/4xx.json
new file mode 100644
index 0000000..48246d0
--- /dev/null
+++ b/www/4xx.json
@@ -0,0 +1 @@
+4xx json
\ No newline at end of file
diff --git a/www/503.html b/www/503.html
new file mode 100644
index 0000000..8edff4c
--- /dev/null
+++ b/www/503.html
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+ Server error - Radix
+
+
+
+
+
+
Oops, something went wrong!
+
This service seems to be offline (Error 503)
+
We're sorry. Try refreshing the page.
+
+ If you keep seeing this,
+ shout at us on Slack.
+
+
+
+
+
diff --git a/www/5xx.html b/www/5xx.html
new file mode 100644
index 0000000..298c9a6
--- /dev/null
+++ b/www/5xx.html
@@ -0,0 +1 @@
+5xx html
diff --git a/www/5xx.json b/www/5xx.json
new file mode 100644
index 0000000..4703b68
--- /dev/null
+++ b/www/5xx.json
@@ -0,0 +1 @@
+5xx json
\ No newline at end of file