mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-19 20:12:51 +08:00
* 当body 为 FileBufferingReadStream,可能会出现request.Body.Length=0的情况
* 修改package id 避免下载到原版 * 发布到nuget.org
This commit is contained in:
parent
36ad6e1e78
commit
c2eb375f91
24
nuget/build-and-push.ps1
Normal file
24
nuget/build-and-push.ps1
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# ¶¨Òå²ÎÊý
|
||||||
|
Param(
|
||||||
|
# Nuget APIKey
|
||||||
|
[string] $apikey
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($apikey -eq $null -or $apikey -eq "")
|
||||||
|
{
|
||||||
|
Write-Error "±ØÐëÖ¸¶¨apiKey";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rm -r ../src/Ocelot/bin/Release
|
||||||
|
dotnet build -c Release ../Ocelot.sln
|
||||||
|
$files = Get-ChildItem -Path ../src/Ocelot/bin/Release -Filter *-ns*.nupkg
|
||||||
|
foreach($file in $files)
|
||||||
|
{
|
||||||
|
dotnet nuget push $file.fullName --skip-duplicate --api-key $apikey --source https://api.nuget.org/v3/index.json
|
||||||
|
}
|
||||||
|
$files = Get-ChildItem -Path ../src/Ocelot/bin/Release -Filter *-ns*.snupkg
|
||||||
|
foreach($file in $files)
|
||||||
|
{
|
||||||
|
dotnet nuget push $file.fullName --skip-duplicate --api-key $apikey --source https://api.nuget.org/v3/index.json
|
||||||
|
}
|
@ -1,41 +1,41 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<NoPackageAnalysis>true</NoPackageAnalysis>
|
<NoPackageAnalysis>true</NoPackageAnalysis>
|
||||||
<Description>Ocelot is an API Gateway. The project is aimed at people using .NET running a micro services / service orientated architecture that need a unified point of entry into their system. In particular I want easy integration with IdentityServer reference and bearer tokens. reference tokens. Ocelot is a bunch of middlewares in a specific order. Ocelot manipulates the HttpRequest object into a state specified by its configuration until it reaches a request builder middleware where it creates a HttpRequestMessage object which is used to make a request to a downstream service. The middleware that makes the request is the last thing in the Ocelot pipeline. It does not call the next middleware. The response from the downstream service is stored in a per request scoped repository and retrived as the requests goes back up the Ocelot pipeline. There is a piece of middleware that maps the HttpResponseMessage onto the HttpResponse object and that is returned to the client. That is basically it with a bunch of other features.</Description>
|
<Description>Ocelot is an API Gateway. The project is aimed at people using .NET running a micro services / service orientated architecture that need a unified point of entry into their system. In particular I want easy integration with IdentityServer reference and bearer tokens. reference tokens. Ocelot is a bunch of middlewares in a specific order. Ocelot manipulates the HttpRequest object into a state specified by its configuration until it reaches a request builder middleware where it creates a HttpRequestMessage object which is used to make a request to a downstream service. The middleware that makes the request is the last thing in the Ocelot pipeline. It does not call the next middleware. The response from the downstream service is stored in a per request scoped repository and retrived as the requests goes back up the Ocelot pipeline. There is a piece of middleware that maps the HttpResponseMessage onto the HttpResponse object and that is returned to the client. That is basically it with a bunch of other features.</Description>
|
||||||
<AssemblyTitle>Ocelot</AssemblyTitle>
|
<AssemblyTitle>Ocelot</AssemblyTitle>
|
||||||
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
<VersionPrefix>18.0.1-ns1</VersionPrefix>
|
||||||
<AssemblyName>Ocelot</AssemblyName>
|
<AssemblyName>Ocelot</AssemblyName>
|
||||||
<PackageId>Ocelot</PackageId>
|
<PackageId>Ocelot.NS</PackageId>
|
||||||
<PackageTags>API Gateway;.NET core</PackageTags>
|
<PackageTags>API Gateway;.NET core</PackageTags>
|
||||||
<PackageProjectUrl>https://github.com/ThreeMammals/Ocelot</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/ThreeMammals/Ocelot</PackageProjectUrl>
|
||||||
<PackageIconUrl>http://github.com/images/ocelot_logo.png</PackageIconUrl>
|
<PackageIconUrl>http://github.com/images/ocelot_logo.png</PackageIconUrl>
|
||||||
<RuntimeIdentifiers>win10-x64;osx.10.11-x64;osx.10.12-x64;win7-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win10-x64;osx.10.11-x64;osx.10.12-x64;win7-x64</RuntimeIdentifiers>
|
||||||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
||||||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
||||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
||||||
<Authors>Tom Pallister</Authors>
|
<Authors>Tom Pallister</Authors>
|
||||||
<CodeAnalysisRuleSet>..\..\codeanalysis.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>..\..\codeanalysis.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<DebugSymbols>True</DebugSymbols>
|
<DebugSymbols>True</DebugSymbols>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="FluentValidation" Version="10.3.6" />
|
<PackageReference Include="FluentValidation" Version="10.3.6" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.MiddlewareAnalysis" Version="6.0.1" />
|
<PackageReference Include="Microsoft.AspNetCore.MiddlewareAnalysis" Version="6.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DiagnosticAdapter" Version="3.1.22">
|
<PackageReference Include="Microsoft.Extensions.DiagnosticAdapter" Version="3.1.22">
|
||||||
<NoWarn>NU1701</NoWarn>
|
<NoWarn>NU1701</NoWarn>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.1" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.1" />
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.164">
|
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.164">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0" />
|
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,119 +1,121 @@
|
|||||||
namespace Ocelot.Request.Mapper
|
namespace Ocelot.Request.Mapper
|
||||||
{
|
{
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Http.Extensions;
|
using Microsoft.AspNetCore.Http.Extensions;
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
using Ocelot.Responses;
|
using Ocelot.Responses;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
public class RequestMapper : IRequestMapper
|
public class RequestMapper : IRequestMapper
|
||||||
{
|
{
|
||||||
private readonly string[] _unsupportedHeaders = { "host" };
|
private readonly string[] _unsupportedHeaders = { "host" };
|
||||||
|
|
||||||
public async Task<Response<HttpRequestMessage>> Map(HttpRequest request, DownstreamRoute downstreamRoute)
|
public async Task<Response<HttpRequestMessage>> Map(HttpRequest request, DownstreamRoute downstreamRoute)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var requestMessage = new HttpRequestMessage()
|
var requestMessage = new HttpRequestMessage()
|
||||||
{
|
{
|
||||||
Content = await MapContent(request),
|
Content = await MapContent(request),
|
||||||
Method = MapMethod(request, downstreamRoute),
|
Method = MapMethod(request, downstreamRoute),
|
||||||
RequestUri = MapUri(request),
|
RequestUri = MapUri(request),
|
||||||
Version = downstreamRoute.DownstreamHttpVersion,
|
Version = downstreamRoute.DownstreamHttpVersion,
|
||||||
};
|
};
|
||||||
|
|
||||||
MapHeaders(request, requestMessage);
|
MapHeaders(request, requestMessage);
|
||||||
|
|
||||||
return new OkResponse<HttpRequestMessage>(requestMessage);
|
return new OkResponse<HttpRequestMessage>(requestMessage);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
return new ErrorResponse<HttpRequestMessage>(new UnmappableRequestError(ex));
|
return new ErrorResponse<HttpRequestMessage>(new UnmappableRequestError(ex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<HttpContent> MapContent(HttpRequest request)
|
private async Task<HttpContent> MapContent(HttpRequest request)
|
||||||
{
|
{
|
||||||
if (request.Body == null || (request.Body.CanSeek && request.Body.Length <= 0))
|
// if (request.Body == null || (request.Body.CanSeek && request.Body.Length)
|
||||||
{
|
// ↑ 当body 为 FileBufferingReadStream,可能会出现request.Body.Length=0的情况, 那么 就会漏掉后续的流程 。修改为 ↓
|
||||||
return null;
|
if (request.Body.CanSeek && request.Body.Length <= 0 && (request.ContentLength ?? 0) <=0)
|
||||||
}
|
{
|
||||||
|
return null;
|
||||||
// Never change this to StreamContent again, I forgot it doesnt work in #464.
|
}
|
||||||
var content = new ByteArrayContent(await ToByteArray(request.Body));
|
|
||||||
|
// Never change this to StreamContent again, I forgot it doesnt work in #464.
|
||||||
if (!string.IsNullOrEmpty(request.ContentType))
|
var content = new ByteArrayContent(await ToByteArray(request.Body));
|
||||||
{
|
|
||||||
content.Headers
|
if (!string.IsNullOrEmpty(request.ContentType))
|
||||||
.TryAddWithoutValidation("Content-Type", new[] { request.ContentType });
|
{
|
||||||
}
|
content.Headers
|
||||||
|
.TryAddWithoutValidation("Content-Type", new[] { request.ContentType });
|
||||||
AddHeaderIfExistsOnRequest("Content-Language", content, request);
|
}
|
||||||
AddHeaderIfExistsOnRequest("Content-Location", content, request);
|
|
||||||
AddHeaderIfExistsOnRequest("Content-Range", content, request);
|
AddHeaderIfExistsOnRequest("Content-Language", content, request);
|
||||||
AddHeaderIfExistsOnRequest("Content-MD5", content, request);
|
AddHeaderIfExistsOnRequest("Content-Location", content, request);
|
||||||
AddHeaderIfExistsOnRequest("Content-Disposition", content, request);
|
AddHeaderIfExistsOnRequest("Content-Range", content, request);
|
||||||
AddHeaderIfExistsOnRequest("Content-Encoding", content, request);
|
AddHeaderIfExistsOnRequest("Content-MD5", content, request);
|
||||||
|
AddHeaderIfExistsOnRequest("Content-Disposition", content, request);
|
||||||
return content;
|
AddHeaderIfExistsOnRequest("Content-Encoding", content, request);
|
||||||
}
|
|
||||||
|
return content;
|
||||||
private void AddHeaderIfExistsOnRequest(string key, HttpContent content, HttpRequest request)
|
}
|
||||||
{
|
|
||||||
if (request.Headers.ContainsKey(key))
|
private void AddHeaderIfExistsOnRequest(string key, HttpContent content, HttpRequest request)
|
||||||
{
|
{
|
||||||
content.Headers
|
if (request.Headers.ContainsKey(key))
|
||||||
.TryAddWithoutValidation(key, request.Headers[key].ToList());
|
{
|
||||||
}
|
content.Headers
|
||||||
}
|
.TryAddWithoutValidation(key, request.Headers[key].ToList());
|
||||||
|
}
|
||||||
private HttpMethod MapMethod(HttpRequest request, DownstreamRoute downstreamRoute)
|
}
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(downstreamRoute?.DownstreamHttpMethod))
|
private HttpMethod MapMethod(HttpRequest request, DownstreamRoute downstreamRoute)
|
||||||
{
|
{
|
||||||
return new HttpMethod(downstreamRoute.DownstreamHttpMethod);
|
if (!string.IsNullOrEmpty(downstreamRoute?.DownstreamHttpMethod))
|
||||||
}
|
{
|
||||||
|
return new HttpMethod(downstreamRoute.DownstreamHttpMethod);
|
||||||
return new HttpMethod(request.Method);
|
}
|
||||||
}
|
|
||||||
|
return new HttpMethod(request.Method);
|
||||||
private Uri MapUri(HttpRequest request)
|
}
|
||||||
{
|
|
||||||
return new Uri(request.GetEncodedUrl());
|
private Uri MapUri(HttpRequest request)
|
||||||
}
|
{
|
||||||
|
return new Uri(request.GetEncodedUrl());
|
||||||
private void MapHeaders(HttpRequest request, HttpRequestMessage requestMessage)
|
}
|
||||||
{
|
|
||||||
foreach (var header in request.Headers)
|
private void MapHeaders(HttpRequest request, HttpRequestMessage requestMessage)
|
||||||
{
|
{
|
||||||
if (IsSupportedHeader(header))
|
foreach (var header in request.Headers)
|
||||||
{
|
{
|
||||||
requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
|
if (IsSupportedHeader(header))
|
||||||
}
|
{
|
||||||
}
|
requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private bool IsSupportedHeader(KeyValuePair<string, StringValues> header)
|
}
|
||||||
{
|
|
||||||
return !_unsupportedHeaders.Contains(header.Key.ToLower());
|
private bool IsSupportedHeader(KeyValuePair<string, StringValues> header)
|
||||||
}
|
{
|
||||||
|
return !_unsupportedHeaders.Contains(header.Key.ToLower());
|
||||||
private async Task<byte[]> ToByteArray(Stream stream)
|
}
|
||||||
{
|
|
||||||
using (stream)
|
private async Task<byte[]> ToByteArray(Stream stream)
|
||||||
{
|
{
|
||||||
using (var memStream = new MemoryStream())
|
using (stream)
|
||||||
{
|
{
|
||||||
await stream.CopyToAsync(memStream);
|
using (var memStream = new MemoryStream())
|
||||||
return memStream.ToArray();
|
{
|
||||||
}
|
await stream.CopyToAsync(memStream);
|
||||||
}
|
return memStream.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user