mormot2 http路由
mormot2 http路由
mormot.net.server.pas
重写包括2部分:重写URL+重写HTTP METHOD。如果你用过GO就会惊喜地发现它与GO的HTTP路由非常相似以及更加方便。
mormot2官方关于路由的博客:https://blog.synopse.info/?post/2022/12/25/Efficient-Routing-for-Christmas
/// efficient server-side URI routing for THttpServerGeneric // - Process() is done with no memory allocation for a static route, // using a very efficient Radix Tree for path lookup, over a thread-safe // non-blocking URI parsing with values extractions for rewrite or execution // - here are some numbers from TNetworkProtocols._TUriTree on my laptop: // $ 1000 URI lookups in 37us i.e. 25.7M/s, aver. 37ns // $ 1000 URI static rewrites in 80us i.e. 11.9M/s, aver. 80ns // $ 1000 URI parametrized rewrites in 117us i.e. 8.1M/s, aver. 117ns // $ 1000 URI static execute in 91us i.e. 10.4M/s, aver. 91ns // $ 1000 URI parametrized execute in 162us i.e. 5.8M/s, aver. 162ns TUriRouter = class(TSynPersistentRWLightLock) protected fTree: TUriRouterTree; fTreeOptions: TRadixTreeOptions; fEntries: array[urmGet .. high(TUriRouterMethod)] of integer; procedure Setup(aFrom: TUriRouterMethod; const aFromUri: RawUtf8; aTo: TUriRouterMethod; const aToUri: RawUtf8; const aExecute: TOnHttpServerRequest); public /// initialize this URI routing engine constructor Create(aOptions: TRadixTreeOptions = []); reintroduce; /// finalize this URI routing engine destructor Destroy; override; /// register an URI rewrite with optional <param> place holders // - <param> will be replaced in aToUri // - if aToUri is an '200'..'599' integer, it will return it as HTTP error // - otherwise, the URI will be rewritten into aToUri, e.g. // $ Rewrite(urmGet, '/info', urmGet, 'root/timestamp/info'); // $ Rewrite(urmGet, '/path/from/<from>/to/<to>', urmPost, // $ '/root/myservice/convert?from=<from>&to=<to>'); // for IMyService.Convert // $ Rewrite(urmGet, '/index.php', '400'); // to avoid fuzzing // $ Rewrite(urmGet, '/*', '/static/*' // '*' synonymous to '<path:path>' procedure Rewrite(aFrom: TUriRouterMethod; const aFromUri: RawUtf8; aTo: TUriRouterMethod; const aToUri: RawUtf8); /// just a wrapper around Rewrite(urmGet, aFrom, aToMethod, aTo) // - e.g. Route.Get('/info', 'root/timestamp/info'); // - e.g. Route.Get('/user/<id>', '/root/userservice/new?id=<id>'); will // rewrite internally '/user/1234' URI as '/root/userservice/new?id=1234' // - e.g. Route.Get('/user/<int:id>', '/root/userservice/new?id=<id>'); // to ensure id is a real integer before redirection // - e.g. Route.Get('/admin.php', '403'); // - e.g. Route.Get('/*', '/static/*'); with '*' synonymous to '<path:path>' procedure Get(const aFrom, aTo: RawUtf8; aToMethod: TUriRouterMethod = urmGet); overload; /// just a wrapper around Rewrite(urmPost, aFrom, aToMethod, aTo) // - e.g. Route.Post('/doconvert', '/root/myservice/convert'); procedure Post(const aFrom, aTo: RawUtf8; aToMethod: TUriRouterMethod = urmPost); overload; /// just a wrapper around Rewrite(urmPut, aFrom, aToMethod, aTo) // - e.g. Route.Put('/domodify', '/root/myservice/update', urmPost); procedure Put(const aFrom, aTo: RawUtf8; aToMethod: TUriRouterMethod = urmPut); overload; /// just a wrapper around Rewrite(urmDelete, aFrom, aToMethod, aTo) // - e.g. Route.Delete('/doremove', '/root/myservice/delete', urmPost); procedure Delete(const aFrom, aTo: RawUtf8; aToMethod: TUriRouterMethod = urmDelete); overload; /// just a wrapper around Rewrite(urmOptions, aFrom, aToMethod, aTo) // - e.g. Route.Options('/doremove', '/root/myservice/Options', urmPost); procedure Options(const aFrom, aTo: RawUtf8; aToMethod: TUriRouterMethod = urmOptions); overload; /// just a wrapper around Rewrite(urmHead, aFrom, aToMethod, aTo) // - e.g. Route.Head('/doremove', '/root/myservice/Head', urmPost); procedure Head(const aFrom, aTo: RawUtf8; aToMethod: TUriRouterMethod = urmHead); overload; /// assign a TOnHttpServerRequest callback with a given URI // - <param> place holders will be parsed and available in callback // as Ctxt['param'] default property or Ctxt.RouteInt64/RouteEquals methods // - could be used e.g. for standard REST process as // $ Route.Run([urmGet], '/user/<user>/pic', DoUserPic) // retrieve a list // $ Route.Run([urmGet, urmPost, urmPut, urmDelete], // $ '/user/<user>/pic/<id>', DoUserPic) // CRUD picture access procedure Run(aFrom: TUriRouterMethods; const aFromUri: RawUtf8; const aExecute: TOnHttpServerRequest); /// just a wrapper around Run([urmGet], aUri, aExecute) registration method // - e.g. Route.Get('/plaintext', DoPlainText); procedure Get(const aUri: RawUtf8; const aExecute: TOnHttpServerRequest); overload; /// just a wrapper around Run([urmPost], aUri, aExecute) registration method procedure Post(const aUri: RawUtf8; const aExecute: TOnHttpServerRequest); overload; /// just a wrapper around Run([urmPut], aUri, aExecute) registration method procedure Put(const aUri: RawUtf8; const aExecute: TOnHttpServerRequest); overload; /// just a wrapper around Run([urmDelete], aUri, aExecute) registration method procedure Delete(const aUri: RawUtf8; const aExecute: TOnHttpServerRequest); overload; /// just a wrapper around Run([urmOptions], aUri, aExecute) registration method procedure Options(const aUri: RawUtf8; const aExecute: TOnHttpServerRequest); overload; /// just a wrapper around Run([urmHead], aUri, aExecute) registration method procedure Head(const aUri: RawUtf8; const aExecute: TOnHttpServerRequest); overload; /// assign the published methods of a class instance to their URI via RTTI // - the signature of each method should match TOnHttpServerRequest // - the method name is used for the URI, e.g. Instance.user as '/user', // with exact case matching, and replacing _ in the method name by '-', e.g. // Instance.cached_query as '/cached-query' procedure RunMethods(RouterMethods: TUriRouterMethods; Instance: TObject; const Prefix: RawUtf8 = '/'); /// perform URI parsing and rewrite/execution within HTTP server Ctxt members // - should return 0 to continue the process, on a HTTP status code to abort // if the request has been handled by a TOnHttpServerRequest callback function Process(Ctxt: THttpServerRequestAbstract): integer; /// erase all previous registrations, optionally for a given HTTP method // - currently, there is no way to delete a route once registered, to // optimize the process thread-safety: use Clear then re-register procedure Clear(aMethods: TUriRouterMethods = [urmGet .. high(TUriRouterMethod)]); /// access to the internal per-method TUriTree instance // - some Tree[] may be nil if the HTTP method has not been registered yet property Tree: TUriRouterTree read fTree; /// how the TUriRouter instance should be created // - should be set before calling Run/Rewrite registration methods property TreeOptions: TRadixTreeOptions read fTreeOptions write fTreeOptions; published /// how many GET rules have been registered property Gets: integer read fEntries[urmGet]; /// how many POST rules have been registered property Posts: integer read fEntries[urmPost]; /// how many PUT rules have been registered property Puts: integer read fEntries[urmPut]; /// how many DELETE rules have been registered property Deletes: integer read fEntries[urmDelete]; /// how many HEAD rules have been registered property Heads: integer read fEntries[urmHead]; /// how many OPTIONS rules have been registered property Optionss: integer read fEntries[urmOptions]; end;
本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/p/17135268.html
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 我与微信审核的“相爱相杀”看个人小程序副业
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~
2022-02-19 中间件在WINDOWS开发
2022-02-19 中间件在LINUX开发
2022-02-19 客户端RESTFUL演示程序
2022-02-19 客户端二进制演示程序
2022-02-19 中间件压力测试
2022-02-19 中间件部署WINDOWS
2022-02-19 中间件部署LINUX