http-traficからアップロードを抽出する必要があります。どうすればそれができますか?まず、request-methodはPOSTになります。次に、Content-Typeヘッダーフィールドがあります。フォーミュラデータを抽出したくありませんが、メール添付ファイルのようにアップロードします。
3 に答える
コンテンツタイプは仕様ごと multipart/form-data
です。
これは、1つの大きなリクエストで複数のサブリクエストとして視覚化できる特別なコンテンツタイプです。これらの各サブリクエスト(1つのform-data要素)には、独自のヘッダーのセットがあります。実際のデータのコンテンツタイプはそこにあります。
<input name="textfield"><input type="file" name="filefield">
これは、1つの通常フィールドと1つのファイルフィールド(HTML用語では、を使用する場合)でどのように見えるかの例です。
Content-Type: multipart/form-data;boundary=SOME_BOUNDARY
--SOME_BOUNDARY
content-disposition: form-data;name="textfield"
content-type: text/plain;charset=UTF-8
value of textfield here
--SOME_BOUNDARY
content-disposition: form-data;name="filefield";filename="some.ext"
content-type: application/octet-stream
binary file content here
--SOME_BOUNDARY--
このデータの解析と抽出に関しては、事実上すべてのプログラミング言語に、このためのサードパーティAPIが組み込まれています。どちらを使用しているのか何も言わなかったので、的を絞った答えを出すことは不可能です。たとえばJavaの場合、これはサードパーティライブラリのApache Commons FileUploadか、APIが提供request.getPart()
するメソッドであるサーブレット3.0を使用している場合のいずれかになります。
バイト配列からデータを保存したいだけの場合(そして私は決してこれが正しい方法だと言っているわけではありません)、次の場所でPOST本文を読み取る方法を確認する必要があります: bottle.pyでPOST本文を読み取る データを読み取ってから新しいファイルを作成することでうまくいくはずです。
@BalusCのソリューションに基づいて、.NETをWebClientクラスでビルドするための小さな拡張メソッドを作成しました。これは、箱から出してマルチパートアップロードをサポートしていません。
使用法
文字列値とファイルを混在させるだけです(#で囲まれています)
public void UploadMultipart()
{
var fileName = "/some/existing/file.ext";
using (var client = new WebClient())
{
var values = new NameValueCollection();
values.Add("id", Guid.NewGuid().ToString());
values.Add("name", Path.GetFileNameWithoutExtension(fileName));
values.Add("file", $"#{fileName}#");
var result = client.UploadMultipart(address, method, values);
var content = client.Encoding.GetString(result);
}
}
拡張方法
public static byte[] UploadMultipart(this WebClient client,
string address, string method, NameValueCollection values)
{
string boundary = DateTime.Now.Ticks.ToString("x");
client.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);
var sb = new StringBuilder()
.AppendLine();
foreach (var key in values.AllKeys)
{
var contentDispositon = $"form-data;name=\"{key}\"";
var contentType = $"text/plain;charset={client.Encoding.WebName}";
var value = values[key];
if (value.StartsWith("#") && value.EndsWith("#"))
{
// if a value is enclosed in hashes we expect this to be a path to a file
// file=#/path/to/file.ext#
var fileName = value.Trim('#');
var file = File.ReadAllBytes(fileName);
value = client.Encoding.GetString(file);
contentType = "application/octet-stream";
contentDispositon = $"form-data;name=\"{key}\"filename=\"{Path.GetFileName(fileName)}\"";
}
sb.AppendLine($"--{boundary}")
.AppendLine($"Content-Disposition: {contentDispositon}")
.AppendLine($"Content-Type: {contentType}")
.AppendLine()
.AppendLine(value);
}
sb.AppendLine($"--{boundary}--");
var data = client.Encoding.GetBytes(sb.ToString());
return client.UploadData(address, method, data);
}