/
HttpDebugUtils.cs
89 lines (71 loc) · 3.01 KB
/
HttpDebugUtils.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
using System.Net.Http.Headers;
using System.Text;
namespace HttpClientExample.Utils
{
public static class HttpDebugUtils
{
/// <summary>
/// HTTP要求の生データを取得する。
/// </summary>
/// <remarks>Hostヘッダは含まれません。</remarks>
/// <param name="req">HTTP要求メッセージ</param>
/// <returns>HTTP要求の生データ</returns>
public static async Task<string> GetRawRequestAsync(HttpRequestMessage req)
{
var sb = new StringBuilder();
// スタートライン
sb.AppendLine($"{req.Method} {req.RequestUri.PathAndQuery} HTTP/{req.Version}");
// HTTPヘッダ(HttpRequestMessageとHttpContentを対象)
sb.Append(GetHeadersString(req.Headers));
sb.Append(GetHeadersString(req.Content?.Headers));
// HTTPヘッダ・ボディを分離する空行
sb.AppendLine();
// HTTPボディ
if( req.Content != null)
{
var bytes = await req.Content.ReadAsByteArrayAsync();
sb.Append(GetContentAsPrintable(bytes));
}
return sb.ToString();
}
/// <summary>
/// HTTP応答の生データを取得する。
/// </summary>
/// <param name="res">HTTP応答メッセージ</param>
/// <returns>HTTP応答の生データ</returns>
public static async Task<string> GetRawResponseAsync(HttpResponseMessage res)
{
var sb = new StringBuilder();
// スタートライン
sb.AppendLine($"HTTP/{res.Version} {(int)res.StatusCode} {res.ReasonPhrase}");
// HTTPヘッダ(HttpRequestMessageとHttpContentを対象)
sb.Append(GetHeadersString(res.Headers));
sb.Append(GetHeadersString(res.Content.Headers));
// HTTPヘッダ・ボディを分離する空行
sb.AppendLine();
// HTTPボディ
var bytes = await res.Content.ReadAsByteArrayAsync();
sb.Append(GetContentAsPrintable(bytes));
return sb.ToString();
}
private static string GetHeadersString(HttpHeaders headers)
{
var sb = new StringBuilder();
if (headers == null) return sb.ToString();
foreach (var header in headers)
foreach (var val in header.Value)
sb.AppendLine($"{header.Key}: {val}");
return sb.ToString();
}
private static string GetContentAsPrintable(byte[] bytes)
{
var sb = new StringBuilder();
if (bytes == null) return sb.ToString();
// 印刷可能文字のみ出力(印刷不可は"."で出力)
foreach (var c in bytes.Select(e => (char)e))
sb.Append(char.IsAscii(c) &&
(c == '\r' || c == '\n' || c == ' ' || !char.IsControl((char)c)) ? c : ".");
return sb.ToString();
}
}
}