私はウサギの穴に落ちたと思うし、私が試みているものよりはるかに簡単な解決策があると思われる。基本的に私の.netのコアMVCアプリケーション内で、私は外部のAPIからストリーミングビデオファイルを取得したい。.netコアのリモートサーバからの応答を転送するには?
これは、私の行動へのリクエストに対して、私は外部API関数を呼び出したいと思っています。リクエストにヘッダーを追加する必要がありますが、リクエストされている他のヘッダーをすべて渡してから、APIから返信したら、レスポンス全体をコンシューマーに転送します。これは、基本的にStatusCodeのないリダイレクトのようなもので、リダイレクトされたソースにヘッダを追加します。
私がやっているやり方は次のとおりです。
var client = await this.FileAssetsApiContext.GetHttpClient();
//Copy the Headers
foreach (var header in Request.Headers)
{
header.Value.ToList().ForEach(p => {
if (client.DefaultRequestHeaders.Contains(header.Key))
{
client.DefaultRequestHeaders.Remove(header.Key);
client.DefaultRequestHeaders.Add(header.Key, p);
}
else
{
client.DefaultRequestHeaders.Add(header.Key, p);
}});
}
var fullPath = Url.Combine(VideosRootPath, path);
var response = await client.GetAsync(url);
return new ForwardedResponseResult(response);
そして私は、転送クラスを持っている:私のコントローラでは、私はForwardedResponseResultを呼び出す
public class ForwardedResponseResult : ActionResult
{
public override void ExecuteResult(ActionContext context)
{
throw new NotImplementedException();
}
public ForwardedResponseResult(HttpResponseMessage httpResponseMessage)
{
this.HttpResponseMessage = httpResponseMessage;
}
public override async Task ExecuteResultAsync(ActionContext context)
{
var responseToCopy = this.HttpResponseMessage;
var responseToCopyHeaders = responseToCopy.Headers.ToArray();
var responseToCopyContentHeaders = responseToCopy.Content.Headers.ToArray();
var streamToCopy = await responseToCopy.Content.ReadAsStreamAsync();
var responseToReturnTo = context.HttpContext.Response;
var streamToCopyTo = responseToReturnTo.Body;
var headers = responseToCopy.Headers.ToArray();
var contentHeaders = responseToCopy.Content.Headers.ToArray();
var headersTo = responseToReturnTo.Headers.ToArray();
foreach (var header in responseToCopy.Headers)
{
header.Value.ToList().ForEach(p => responseToReturnTo.Headers.Add(header.Key, p));
}
responseToReturnTo.StatusCode = (int) responseToCopy.StatusCode;
foreach (var header in responseToCopy.Content.Headers)
{
header.Value.ToList().ForEach(p => responseToReturnTo.Headers.Add(header.Key, p));
}
//Copy to the output buffer
var remainingBytes = streamToCopy.Length;
while (remainingBytes > 0)
{
//var bufferSize = 1024;
var bufferSize = 8096;
var buffLen = remainingBytes > bufferSize ? bufferSize : remainingBytes;
var buffer = new byte[buffLen];
streamToCopy.Read(buffer, 0, (int)buffLen);
streamToCopyTo.Write(buffer, 0, (int)buffLen);
remainingBytes -= buffLen;
}
//streamToCopy.CopyTo(streamToCopyTo);
//await streamToCopyTo.FlushAsync();
}
public HttpResponseMessage HttpResponseMessage { get; }
}
これは、大規模なやり過ぎのように思える、と範囲要求のパフォーマンスは悲惨です。私は明白な何かを欠いていますかもっと簡単にこれを行う方法はありますか?
スティーブンありがとうございます。その変更ははるかに良く機能します。私はこれを行うための直接的な方法はないと思っていますが、少なくとも私はそれを働かせています –