Skip to content

Commit 3cdcb35

Browse files
authored
feat: allow specifying content-type for /base64 responses (#198)
Given that the `/base64/{data}` (and `/base64/decode/{data}`) endpoint allows decoding arbitrary data, I think it makes sense to allow the client to also specify the `Content-Type` of that data while maintaining `text/plain` as the safe default. See conversation starting here[1] for context and motivation for this change. [1] #141 (comment)
1 parent ce8d747 commit 3cdcb35

File tree

4 files changed

+26
-8
lines changed

4 files changed

+26
-8
lines changed

httpbin/handlers.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,11 @@ func (h *HTTPBin) Base64(w http.ResponseWriter, r *http.Request) {
10771077
writeError(w, http.StatusBadRequest, err)
10781078
return
10791079
}
1080-
writeResponse(w, http.StatusOK, textContentType, result)
1080+
ct := r.URL.Query().Get("content-type")
1081+
if ct == "" {
1082+
ct = textContentType
1083+
}
1084+
writeResponse(w, http.StatusOK, ct, result)
10811085
}
10821086

10831087
// DumpRequest - returns the given request in its HTTP/1.x wire representation.

httpbin/handlers_test.go

+17-3
Original file line numberDiff line numberDiff line change
@@ -2868,45 +2868,59 @@ func TestUUID(t *testing.T) {
28682868

28692869
func TestBase64(t *testing.T) {
28702870
okTests := []struct {
2871-
requestURL string
2872-
want string
2871+
requestURL string
2872+
want string
2873+
wantContentType string
28732874
}{
28742875
{
28752876
"/base64/dmFsaWRfYmFzZTY0X2VuY29kZWRfc3RyaW5n",
28762877
"valid_base64_encoded_string",
2878+
textContentType,
28772879
},
28782880
{
28792881
"/base64/decode/dmFsaWRfYmFzZTY0X2VuY29kZWRfc3RyaW5n",
28802882
"valid_base64_encoded_string",
2883+
textContentType,
28812884
},
28822885
{
28832886
"/base64/encode/valid_base64_encoded_string",
28842887
"dmFsaWRfYmFzZTY0X2VuY29kZWRfc3RyaW5n",
2888+
textContentType,
28852889
},
28862890
{
28872891
// make sure we correctly handle padding
28882892
// https://github.com/mccutchen/go-httpbin/issues/118
28892893
"/base64/dGVzdC1pbWFnZQ==",
28902894
"test-image",
2895+
textContentType,
28912896
},
28922897
{
28932898
// URL-safe base64 is used for decoding (note the - instead of + in
28942899
// encoded input string)
28952900
"/base64/decode/YWJjMTIzIT8kKiYoKSctPUB-",
28962901
"abc123!?$*&()'-=@~",
2902+
textContentType,
28972903
},
28982904
{
28992905
// Std base64 is also supported for decoding (+ instead of - in
29002906
// encoded input string). See also:
29012907
// https://github.com/mccutchen/go-httpbin/issues/152
29022908
"/base64/decode/8J+Ziywg8J+MjSEK4oCm",
29032909
"🙋, 🌍!\n…",
2910+
textContentType,
29042911
},
29052912
{
29062913
// URL-safe base64 is used for encoding (note the - instead of + in
29072914
// encoded output string)
29082915
"/base64/encode/abc123%21%3F%24%2A%26%28%29%27-%3D%40~",
29092916
"YWJjMTIzIT8kKiYoKSctPUB-",
2917+
textContentType,
2918+
},
2919+
{
2920+
// Custom content type
2921+
"/base64/eyJzZXJ2ZXIiOiAiZ28taHR0cGJpbiJ9Cg==?content-type=application/json",
2922+
`{"server": "go-httpbin"}` + "\n",
2923+
"application/json",
29102924
},
29112925
}
29122926

@@ -2918,7 +2932,7 @@ func TestBase64(t *testing.T) {
29182932
resp := must.DoReq(t, client, req)
29192933
defer consumeAndCloseBody(resp)
29202934
assert.StatusCode(t, resp, http.StatusOK)
2921-
assert.ContentType(t, resp, textContentType)
2935+
assert.ContentType(t, resp, test.wantContentType)
29222936
assert.BodyEquals(t, resp, test.want)
29232937
})
29242938
}

httpbin/helpers_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ func TestParseWeightedChoices(t *testing.T) {
486486
tc := tc
487487
t.Run(tc.given, func(t *testing.T) {
488488
t.Parallel()
489-
got, err := parseWeightedChoices[int](tc.given, strconv.Atoi)
489+
got, err := parseWeightedChoices(tc.given, strconv.Atoi)
490490
assert.Error(t, err, tc.wantErr)
491491
assert.DeepEqual(t, got, tc.want, "incorrect weighted choices")
492492
})

httpbin/static/index.html.tmpl

+3-3
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@
6161
<li><a href="{{.Prefix}}/"><code>{{.Prefix}}/</code></a> This page.</li>
6262
<li><a href="{{.Prefix}}/absolute-redirect/6"><code>{{.Prefix}}/absolute-redirect/:n</code></a> 302 Absolute redirects <em>n</em> times.</li>
6363
<li><a href="{{.Prefix}}/anything"><code>{{.Prefix}}/anything/:anything</code></a> Returns anything that is passed to request.</li>
64-
<li><a href="{{.Prefix}}/base64/aHR0cGJpbmdvLm9yZw=="><code>{{.Prefix}}/base64/:value</code></a> Decodes a Base64-encoded string.</li>
65-
<li><a href="{{.Prefix}}/base64/decode/aHR0cGJpbmdvLm9yZw=="><code>{{.Prefix}}/base64/decode/:value</code></a> Explicit URL for decoding a Base64 encoded string.</li>
64+
<li><a href="{{.Prefix}}/base64/eyJzZXJ2ZXIiOiAiZ28taHR0cGJpbiJ9Cg==?content-type=application/json"><code>{{.Prefix}}/base64/:value?content-type=ct</code></a> Decodes a Base64-encoded string, with optional Content-Type.</li>
65+
<li><a href="{{.Prefix}}/base64/decode/aHR0cGJpbmdvLm9yZw=="><code>{{.Prefix}}/base64/decode/:value?content-type=ct</code></a> Explicit URL for decoding a Base64 encoded string.</li>
6666
<li><a href="{{.Prefix}}/base64/encode/httpbingo.org"><code>{{.Prefix}}/base64/encode/:value</code></a> Encodes a string into URL-safe Base64.</li>
6767
<li><a href="{{.Prefix}}/basic-auth/user/password"><code>{{.Prefix}}/basic-auth/:user/:password</code></a> Challenges HTTPBasic Auth.</li>
6868
<li><a href="{{.Prefix}}/bearer"><code>{{.Prefix}}/bearer</code></a> Checks Bearer token header - returns 401 if not set.</li>
@@ -193,7 +193,7 @@ Content-Length: 0
193193

194194
</div>
195195

196-
<a href="https://github.com/mccutchen/go-httpbin"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/38ef81f8aca64bb9a64448d0d70f1308ef5341ab/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6461726b626c75655f3132313632312e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"></a>
196+
<a href="https://github.com/mccutchen/go-httpbin" class="github-corner" aria-label="Fork me on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#ff0083; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"/><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"/><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"/></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
197197

198198
</body>
199199
</html>

0 commit comments

Comments
 (0)