Commit 778478c
fix: handle Content-Type with charset parameter for JSON payload (#32)
* fix: handle Content-Type with charset parameter for JSON payload
The JSON payload case used exact string match against "application/json",
so requests with parameters like "application/json; charset=utf-8" fell
through to the default branch and the body was rendered as a single raw
line, breaking the table layout. Switched to strings.HasPrefix to match
the same approach already used for x-www-form-urlencoded and
multipart/form-data, and added tests for charset-suffixed JSON.
Also addressed pre-existing lint issues touched along the way:
sort.Strings → slices.Sort, WriteString(fmt.Sprintf) → fmt.Fprintf,
and a nolint on the text/plain response Fprintf flagged by gosec G705.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: render JSON and raw payload outside the table
Long lines inside an AutoMerge'd payload row (e.g. an Azure DevOps
webhook with a long URL inside detailedMessage.html) were inflating
column 1's max width, pushing the value column past the terminal width
and making 2-column rows wrap so values like "0.6.2" appeared empty
on narrow terminals.
The table now renders only metadata, headers, secret/HMAC validation
and the incoming Content-Type. The pretty-printed JSON body and any
default raw body are written below the table, framed by separator
lines, so the table stays compact at any terminal width and the body
follows the terminal's natural flow.
Form-urlencoded and multipart key=value rows are unchanged — they are
short and fit naturally inside the table.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: parse media type and unmarshal arbitrary JSON for payload classification
Address review feedback from Codex and Copilot on PR #32:
- Parse Content-Type with mime.ParseMediaType once and dispatch on the
parsed media type with a tagged switch. application/json-patch+json,
application/jsonp and other types whose subtype merely starts with
"json" no longer fall into the JSON branch and incorrectly emit
json.Unmarshal errors; they go through the raw-body path instead.
- Hoist the multipart media-type parsing out of its case (it is now
done once at the top) and reuse the parsed boundary parameter.
- Switch the JSON unmarshal target from map[string]any to any, so
arrays and primitives (e.g. JSON Patch, [1,2,3], "hello") are
pretty-printed instead of erroring with "cannot unmarshal array
into Go value of type map[string]any".
- Upgrade the JSON-charset tests to write through WithOutputWriter
to a temp file and assert observable handler output: pretty-printed
multi-line JSON for valid input, json.Unmarshal error for invalid
input. Add tests for JSON arrays and application/json-patch+json
to lock in the new behaviour.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(webui): add copy-to-clipboard for body and individual header values
Adds a copy button next to the Body section heading that copies the
displayed body text (raw text or pretty-printed JSON) to the clipboard.
Each row in the Headers table also gets an inline copy button that
appears on row hover and copies the raw header value.
Both buttons flash a "Copied!" confirmation for 1.5s on success and
fall back to a hidden-textarea + execCommand path when
navigator.clipboard is unavailable (older browsers / non-secure
contexts).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* add copy
* fix: surface mime.ParseMediaType errors instead of swallowing them
Previously the parse error was discarded with `_`, so a malformed
non-empty Content-Type would silently fall through to the raw-body
default branch — losing the explicit error feedback the old multipart
branch used to provide.
Now any parse failure on a non-empty Content-Type renders an error
row and short-circuits to RENDER. An absent Content-Type still falls
through to raw body as before, since "no media type" is not a parse
failure worth surfacing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: address Copilot review feedback
- Show the request body under the "Payload" section even when
mime.ParseMediaType fails. Previously the parse-error short-circuit
jumped to RENDER without rendering the body, leaving the malformed
payload visible only in the Raw HTTP dump. Set payloadAfterTable
before goto RENDER so it still appears below the table.
- Replace the hard-coded white background on .headers-table tr:hover
with var(--highlight-bg) so the dark theme keeps usable contrast.
- Make the per-header copy button discoverable for keyboard users by
also revealing it on tr:focus-within / .copy-btn:focus-visible, and
give every copy button a visible focus outline.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: address Copilot review feedback (round 2)
- Close server.OutputWriter before reading the temp output file in
WithOutputWriter-based subtests. Avoids potential file-locking
failures on Windows and guarantees writes are flushed before the
assertions run.
- Keep the per-header copy button visible on touch devices via a
@media (hover: none) rule, so the affordance is discoverable when
no hover state is available.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: address Copilot review feedback (round 3)
- Set payloadAfterTable = bodyAsString on json.Unmarshal and
json.MarshalIndent failures so the raw request body still appears
under the table when JSON parsing fails, matching the
mime.ParseMediaType error path.
- Drop the .trim() on the body copy handler so the clipboard receives
the body's exact textContent (no leading/trailing whitespace lost).
- Extend the invalid-JSON subtest to assert the raw body is rendered
below the table on the unmarshal-error path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 7d4dc0d commit 778478c
3 files changed
Lines changed: 316 additions & 43 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | | - | |
| 21 | + | |
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| |||
292 | 292 | | |
293 | 293 | | |
294 | 294 | | |
295 | | - | |
| 295 | + | |
296 | 296 | | |
297 | 297 | | |
298 | 298 | | |
299 | 299 | | |
300 | 300 | | |
301 | 301 | | |
302 | 302 | | |
| 303 | + | |
303 | 304 | | |
304 | 305 | | |
305 | 306 | | |
| |||
365 | 366 | | |
366 | 367 | | |
367 | 368 | | |
368 | | - | |
369 | | - | |
370 | | - | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
371 | 386 | | |
372 | 387 | | |
373 | 388 | | |
| |||
376 | 391 | | |
377 | 392 | | |
378 | 393 | | |
| 394 | + | |
| 395 | + | |
379 | 396 | | |
380 | 397 | | |
381 | 398 | | |
| |||
388 | 405 | | |
389 | 406 | | |
390 | 407 | | |
| 408 | + | |
| 409 | + | |
391 | 410 | | |
392 | 411 | | |
393 | 412 | | |
394 | | - | |
395 | | - | |
396 | | - | |
397 | | - | |
398 | | - | |
399 | | - | |
400 | | - | |
| 413 | + | |
| 414 | + | |
401 | 415 | | |
402 | 416 | | |
403 | 417 | | |
| |||
421 | 435 | | |
422 | 436 | | |
423 | 437 | | |
424 | | - | |
| 438 | + | |
425 | 439 | | |
426 | 440 | | |
427 | 441 | | |
428 | 442 | | |
429 | 443 | | |
430 | 444 | | |
431 | | - | |
432 | | - | |
433 | | - | |
434 | | - | |
435 | | - | |
436 | | - | |
437 | | - | |
438 | | - | |
439 | | - | |
440 | | - | |
441 | | - | |
442 | | - | |
443 | | - | |
444 | | - | |
| 445 | + | |
| 446 | + | |
445 | 447 | | |
446 | 448 | | |
447 | 449 | | |
| |||
549 | 551 | | |
550 | 552 | | |
551 | 553 | | |
552 | | - | |
| 554 | + | |
553 | 555 | | |
554 | 556 | | |
555 | 557 | | |
| |||
600 | 602 | | |
601 | 603 | | |
602 | 604 | | |
603 | | - | |
604 | | - | |
605 | | - | |
606 | | - | |
607 | | - | |
608 | | - | |
609 | | - | |
610 | | - | |
611 | | - | |
| 605 | + | |
612 | 606 | | |
613 | 607 | | |
614 | 608 | | |
615 | 609 | | |
616 | 610 | | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
617 | 617 | | |
618 | 618 | | |
619 | 619 | | |
| |||
628 | 628 | | |
629 | 629 | | |
630 | 630 | | |
631 | | - | |
| 631 | + | |
| 632 | + | |
632 | 633 | | |
633 | 634 | | |
634 | 635 | | |
| |||
855 | 856 | | |
856 | 857 | | |
857 | 858 | | |
858 | | - | |
| 859 | + | |
859 | 860 | | |
860 | 861 | | |
861 | 862 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
176 | 177 | | |
177 | 178 | | |
178 | 179 | | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
179 | 312 | | |
180 | 313 | | |
181 | 314 | | |
| |||
0 commit comments