Because access to NuGet was too slow, I made a NuGet proxy site based on ASP before Dotnet Core RC2 was released
This is the website address: http://nuget.lzzy.net/
NuGet Source: Http://nuget.lzzy.net/api/v2
Guangxi Telecom hundred trillion bandwidth.
This site will cache all visited API pages and packages.
The principle of API page caching, the first access will wait for the server to download page information from NuGet
After downloading, the URL is replaced and saved to the database.
The second visit takes the page out of the database and determines the expiration time.
If it has expired, first return to the page information, background new thread download new page.
In this way the domestic visit will feel very fast.
Upgrade to ASPNET Core
When RC2 released, I thought it was time to study the dotnet core platform.
Let's start with this little NuGet proxy site.
Under. Net FX, the agents that are being developed are proxies through IHttpHandler
Then the ASPNET Core becomes the proxy through the middleware.
Routing also becomes different under Aspnetcore, which is easier and easier to use than the older version.
Use of Routes
Note: The use of routing requires a package Microsoft.AspNetCore.Routing
First create a static class, add a usexxxmiddleware extension method, this is the Aspnetcore use middleware conventions, of course, you can also play other names.
In the method, we need a new Routebuilder instance.
Various mapping methods are called in the instance.
Then call the build method of Routebuilder, which will generate a route.
Finally, using the extension method of Route middleware Userouter, the route just build is passed in as parameter.
public static Iapplicationbuilder Usenugetproxymiddleware (this iapplicationbuilder builder, iconfigurationroot con FIG) {if (! Directory.Exists ("Packages")) Directory.CreateDirectory ("Packages"); var cachesection = config. GetSection ("Cache"); _cachemetadata = Int. Parse (Cachesection.getsection ("Metadata"). Value); _cachelist = Int. Parse (Cachesection.getsection ("List"). Value); _cachedetail = Int. Parse (Cachesection.getsection ("Detail"). Value); _cachedefault = Int. Parse (Cachesection.getsection ("Default"). Value); var proxysection = config. GetSection ("Proxy"); _source = Proxysection.getsection ("Source"). Value; _replace = Proxysection.getsection ("Replace"). Value; _path = Proxysection.getsection ("Path"). Value; var routebuilder = new Routebuilder (builder); Routebuilder.mapget (_path + "/{action}", Pagehandler); RoutEbuilder.mapget (_path, Pagehandler); Routebuilder.mapget (_path + "/package/{id}/{version}", Packagehandler); _path = "/" + _path; var router = routebuilder.build (); Return builder. Userouter (router); } private static Async Task Pagehandler (HttpContext HttpContext) {}
Middleware usage under routing
When using the Routebuilder mapping method, the delegate that handles the HttpContext needs to be passed
This is actually the same middleware approach as the ASPNET core itself.
It's just that we need to get all kinds of data in the method, not just like the ASPNET core middleware, where we can get some services in the constructor.
The AspNet core route provides an extension method getroutevalue that HttpContext gets the route parameters.
private static Async Task Packagehandler (HttpContext HttpContext) { string id = httpcontext.getroutevalue ("id" ) As String; String version = Httpcontext.getroutevalue ("version") as String; }
There are also getroutedata extension methods, which we don't need to use here.
EntityFramework Core
RC2, there have been some changes in the use of EntityFramework core
In Startup.cs, configure EF Core
public void Configureservices (iservicecollection services) { //ADD framework services. Services. Adddbcontext<datacontext> (builder = { Builder. Usesqlserver (configuration.getconnectionstring ("DataContext"));} );
Modify the configuration of the dbcontext here.
It is important to note that you inherit the DbContext class by using a constructor with parameters and calling the base class constructor.
public class Datacontext:dbcontext {public DataContext (dbcontextoptions<datacontext> options): Base (options) {} public dbset<page> Page {get; set;} }
Mutual exclusion Lock
When multiple people visit the same new page, only one person can download the data for the new page, while others wait. The same with the new package.
Multiple people accessing the same expired page will only create a new thread to download the data for the new page.
The project encapsulates a Synchronizationhelp class that is mutually exclusive through the path in the middleware.
The rest of it is nothing special to say, some in the source code.
Github
Here is GitHub for this proxy website:
Https://github.com/Kation/NugetProxy
Oh, yes, there's one more thing.
The configuration of the proxy site.
Configuration file:
{" Logging": { "includescopes": false, "LogLevel": { "Default": "Debug", "System": "Information ", " Microsoft ":" Information " } , " ConnectionStrings ": { " DataContext ":" server= (local); Database=nuget;uid=sa; [Email protected] " }, " Cache ": { " Metadata ":" 10080 ", " List ":" $ ", " Detail ":" 1440 ", "Default": "{" }, "Proxy": { "Source": "Https://www.nuget.org/api/v2", "Replace": " Https://www.nuget.org/api/v2 ", " Path ":" Api/v2 " }}
You can set the cache time to download new pages after the time, in minutes.
The source of the proxy is the NuGet sources
Replace is the string to be replaced and will be replaced with the current web address +path
PS: I have a 20M VPS reverse proxy nuget in the United States
Http://nuget.lzzy.net/api/v2 is using the source of my VPS orientation Agent
Effect faster than direct access to nuget ...
"AspNet Core" NuGet proxy site