deno_fcgi

2025-12-07 0 108

FCGI- DENO的FASTCGI协议实现

文档索引

该库允许以下内容:

  1. 要在具有FASTCGI的Web服务器(例如Apache或Nginx)后面创建DENO后端应用程序
  2. 要查询FastCGI服务,例如PHP(如Web服务器)。
  3. 要创建2个DENO应用程序,并通过FastCGI协议在它们之间进行通信。

FastCGI是一个简单的协议,旨在转发HTTP请求。通常,它用于将不同的HTTP请求转发到从单主/端口上听的一台HTTP服务器的不同应用程序。拥有主HTTP服务器很方便。它允许在一个地方控制所有www动作。

后端应用程序示例(FastCGI服务器)

 // File: backend.ts

import { fcgi } from \'https://d*e*n*o.land/x/fcgi@v2.1.1/mod.ts\' ;

const listener = fcgi . listen
(	\'localhost:9988\' , // FastCGI service will listen on this address
	\'\' , // Handle all URL paths
	async req =>
	{	// Handle the request
		console . log ( req . url ) ;
		req . responseHeaders . set ( \'Content-Type\' , \'text/html\' ) ;
		await req . respond ( { body : \'Hello world!\' } ) ;
	}
) ;

console . log ( `Started on ${ listener . addr . transport == \'tcp\' ? listener . addr . hostname + \':\' + listener . addr . port : listener . addr . transport } ` ) ;

您可以将Web服务器设置为将HTTP请求转发到localhost:9988 ,并且该应用程序将获取它们。

前端应用程序示例(FastCGI客户端)

或者,您可以使用DENO创建Web服务器,并向某些FastCGI服务器提出请求。这可以是php-fpm,也可以是上面显示的DENO后端应用程序。

在下面的示例中,我将使用X/Oak在DeNo中创建HTTP服务器:

 // File: frontend.ts

import { Application } from \'https://den*o.lan**d/x/oak@v9.0.1/mod.ts\' ;
import { fcgi } from \'https://d*e*n*o.land/x/fcgi@v2.1.1/mod.ts\' ;

const app = new Application ;

app . use
(	async ctx =>
	{	const resp = await fcgi . fetch
		(	{	addr : \'localhost:9988\' ,
				scriptFilename : \'\' , // PHP requires this parameter to be set to path of an existing *.php file
			} ,
			new Request
			(	ctx . request . url . href ,
				{	method : ctx . request . method ,
					headers : ctx . request . headers ,
					body : ctx . request . hasBody ? ctx . request . body ( { type : \'stream\' } ) . value : undefined ,
				}
			)
		) ;
		ctx . response . status = resp . status ;
		ctx . response . headers = resp . headers ;
		ctx . response . body = resp . body ;
	}
) ;

app . listen ( \'localhost:8123\' ) ;
console . log ( `Started on http://*localho**st:8123` ) ;

这是运行前两个示例的方法:

deno run --allow-net backend.ts &
deno run --allow-net frontend.ts

现在http://l*ocal*ho*st:8123将转发到fcgi://localhost:9988 ,并通过后端申请进行处理。

设置示例:

  • Nginx → Deno :如何设置NGINX HTTP服务器。
  • Apache → Deno :如何设置Apache HTTP服务器。
  • Deno → PHP :如何设置PHP-FPM并转发请求。
  • Deno → spawn-fcgi + Perl :如何设置Perl Fastcgi并向它提出请求。

使用API

该库提供一流的对象,您可以通过该对象进行所有支持的FastCGI操作:启动FastCGI服务器,并对FastCGI服务进行查询。

此对象称为FCGI。

 import { fcgi } from \'https://d*e*n*o.land/x/fcgi@v2.1.1/mod.ts\' ;

方法:

听()

⚙fcgi.listen(addr_or_listener:fcgiaddr |侦听器,path_pattern:pathpattern:pathpattern,callback:callback):侦听器

在指定的网络地址上注册FastCGI服务器。该地址可以:

  • 端口号( 8000 ),
  • 带有可选端口的主机名( localhost:8000 0.0.0.0:8000[::1]:8000::1 ),
  • 一个Unix-Domain插座文件名( /run/deno-fcgi-server.sock ),
  • Deno.Addr{transport: \'tcp\', hostname: \'127.0.0.1\', port: 8000} ),
  • 或者也可以给出一个现成的Deno.Listener对象。

该功能可以多次使用相同或不同的地址调用。带有相同地址的呼叫添加了另一个处理程序回调,该回调将尝试处理匹配请求。使用不同地址的呼叫会创建另一台FastCGI服务器。

第二个参数允许过滤到达请求。它使用X/path_to_regexp库,就像X/Oak一样。

第三个参数是带有签名的回调函数(request: ServerRequest, params: any) => Promise<unknown>该>将被要求用于匹配过滤器的传入请求。 params包含来自路径滤波器的REGEXP组。

“回调”可以处理请求并调用其req.respond()方法(等待结果),或者它可以决定不处理此请求,而无需致电req.respond()返回,因此其他处理程序(在FCGI.LISTEN()注册)将有机会处理此请求。如果没有处理,将返回404响应。

例子:

 fcgi . listen
(	9988 ,
	\'/page-1.html\' ,
	async req =>
	{	await req . respond ( { body : \'Hello world\' } ) ;
	}
) ;

fcgi . listen
(	9988 ,
	\'/catalog/:item\' ,
	async ( req , params ) =>
	{	await req . respond ( { body : `Item ${ params . item } ` } ) ;
	}
) ;

fcgi . listen
(	9988 ,
	\'\' , // match all paths
	async req =>
	{	await req . respond ( { body : \'Something else\' } ) ;
	}
) ;

unlisten()

⚙fcgi.unlisten(addr?:fcgiaddr): void

在指定地址或所有地址上停止服务请求(如果ADDR参数未定义)。删除所有听众将触发“结束”事件。

onerror()

⚙fcgi.onerror(呼叫?:(错误:错误)=> unknown ):Promise void

捕获FastCGI服务器错误。可以添加多个事件处理程序。

onend()

⚙fcgi.onend(callback?:()=> unknown ):Promise void

await onEnd() – 捕获FastCGI服务器停止接受连接的时刻(当所有侦听器删除和正在进行的请求完成时)。

OffError()

⚙fcgi.offerror(呼叫?:(错误:错误)=> unknown ): void

删除通过onError(callback)添加的回调。

fcgi.offError() – 删除所有回调。

得罪()

⚙fcgi.offend(呼叫?:()=> unknown ): void

删除通过onEnd(callback)

fcgi.offEnd() – 删除所有回调。

选项()

⚙fcgi.options(选项?:服务器和客户端):ServerOptions&ClientOptions

允许修改服务器和/或Client选项。未指定的选项将保留其先前的值。即使在服务器开始运行后,也可以随时调用此功能,并且在可能的情况下将生效新的选项值。此功能在修改后返回所有选项。

 console . log ( `maxConns= ${ fcgi . options ( ) . maxConns } ` ) ;
fcgi . options ( { maxConns : 123 } ) ;
console . log ( `Now maxConns= ${ fcgi . options ( ) . maxConns } ` ) ;

拿来()

⚙fcgi.fetch(request_options:requestOptions,输入:request | url | string ,init?:requestInit):Promise <Response WithWithCookies>

像Apache和Nginx一样,将请求发送到FASTCGI服务,例如PHP。

第一个参数( request_options )指定如何连接到服务以及发送到哪些参数。 2最重要的参数是request_options.addr (服务套接字地址)和request_options.scriptFilename (服务必须执行的脚本文件的路径)。

第二个( input )和第三( init )参数与内置fetch()函数中的参数相同。

返回的响应对象通过添加包含所有Set-Cookie标头的cookies属性来扩展内置Response (定期fetch()返回)。也response.body对象通过添加Deno.Reader实现来扩展常规的ReadableStream<Uint8Array>

在指定的request_options.timeout期间通过之前,必须明确阅读响应主体。在此期间之后,连接将被迫关闭。每个未封闭的连接都计入clientoptions.maxconns。 response.body后。doby读取到结尾,连接返回到池,可以重复使用(除了将现有Deno.Conn提供给request_options.addr的情况外 – 在这种情况下,此对象的创建者决定该对象如何处理该对象)。

request_options.keepAliveTimeout milliseconds以及request_options.keepAliveMax times使用的时间。

fetchcapabilities()

⚙fcgi.fetchcapabilities(addr:fcgiaddr | conn):promise <{fcgi_max_conns?: number number fcgi_max_reqs number :fcgi_mpxs_conns?

向FASTCGI服务(例如PHP)询问其协议功能。这不是那么有用的信息。仅适用于那些好奇的人。众所周知,Apache和Nginx在协议使用过程中甚至都不要求此。

canfetch()

⚙fcgi.canfetch(): boolean

当正在进行的请求的数量大于配置的值(MaxConns)时,Fetch()和FetchCapabilities()将等待。 canFetch()检查是否有免费插槽,如果是的,则返回true。建议不要将fetch() untill canFetch()授予绿灯。例子:

 if ( ! fcgi . canFetch ( ) )
{	await fcgi . waitCanFetch ( ) ;
}
await fcgi . fetch ( ... ) ;

waitcanfetch()

⚙fcgi.waitcanfetch():Promise void

Closeidle()

⚙fcgi.closeidle(): void

如果keepAliveTimeout选项为> 0,则FCGI.Fetch()将重复使用连接。每次获取后,连接将等待指定的毫秒数以进行下一个获取。空闲连接不允许Deno应用自然退出。您可以致电fcgi.closeIdle()关闭所有空闲连接。

使用低级API

提到的FCGI对象只是围绕低级功能和类的包装器。可以直接使用它们。

 import { Server } from \'https://d*e*n*o.land/x/fcgi@v2.1.1/mod.ts\' ;

const listener = Deno . listen ( { hostname : \"::1\" , port : 9988 } ) ;
const server = new Server ( listener ) ;
console . log ( `Started on ${ listener . addr . transport == \'tcp\' ? listener . addr . hostname + \':\' + listener . addr . port : listener . addr } ` ) ;

for await ( let req of server )
{	queueMicrotask
	(	async ( ) =>
		{	console . log ( req . url ) ;
			req . responseHeaders . set ( \'Content-Type\' , \'text/html\' ) ;
			await req . respond ( { body : \'Your cookies: \' + JSON . stringify ( [ ... req . cookies . entries ( ) ] ) } ) ;
		}
	) ;
} 

ServerRequest对象

给出的fcgi.listen()的回调接收到传入的请求作为serverRequest对象。服务器上的异步迭代也会产生此类对象。 ServerRequest包含从FastCGI服务器发送的信息。

  • url (string) – 请求的request_uri,例如\’/path/index.html?a=1\’
  • method (字符串) – 喜欢GET
  • proto (字符串) – 例如HTTP/1.1HTTP/2
  • protoMinor (数字)
  • protoMajor (数字)
  • params (标题) – 从FastCGI Frontend发送的环境参数。这通常包括“ request_uri”,“ script_uri”,“ script_filename”,“ document_root”,可以包含“ context_document_root”(如果使用apache multiviews),等等。
  • headers (标题) – 请求HTTP标头。
  • get (MAP) – 查询字符串参数。
  • post (地图) – 发布参数,可以包含上传的文件。要初始化此属性,请致电await req.post.parse()
  • cookies (地图) – 请求cookie。添加并删除它们添加了相应的响应HTTP标头。
  • body (Deno.Reader) – 如果未调用req.post.parse()则允许阅读原始的帖子主体。也可以从ServerRequest对象本身中读取身体,因为它实现了Deno.Readerreq.body == req )。
  • responseStatus (number) – 在调用respond()之前将其设置为HTTP状态代码。但是, respond()如果给出)给出的状态覆盖了这一状态。
  • responseHeaders (标题) – 在调用响应之前,将响应HTTP标头设置respond()标头,然后/或将它们传递给respond() (后者具有优先级)。
  • headersSent (布尔值) – 表示已经发送响应标头。如果您将数据写入serverRequest对象(它实现Deno.Writer ),则它们将通过respond()或更早发送。

要响应请求,您需要调用req.respond()方法,该方法将所有未决数据发送到FastCGI服务器,并终止请求,释放所有资源,并删除所有上传的文件(您需要将它们移动到其他位置以保持它们)。调用respond()

如果使用服务器对象,则在完成此请求后respond()是您的责任。 FCGI.LISTEN()API如果您不在任何注册的请求处理程序中调用它,将自动拨打respond()为404状态。

可以在调用respond()之前设置响应标头和数据,也可以将其发送给response() 。可以给出响应主体以respond() ,也可以将其写入ServerRequest对象。

 // test like this: curl --data \'INPUT DATA\' http://*deno-se*rve*r.loc/test.ts

import { fcgi } from \'https://d*e*n*o.land/x/fcgi@v2.1.1/mod.ts\' ;

console . log ( `Started on [::1]:9988` ) ;
fcgi . listen
(	\'[::1]:9988\' ,
	\'\' ,
	async req =>
	{	console . log ( req . url ) ;
		// read raw POST input
		const raw_input = await req . readable . uint8Array ( ) ;
		// write response
		req . responseHeaders . set ( \'Content-Type\' , \'text/plain\' ) ;
		await req . writable . write ( \'The POST input was:\\n\' ) ;
		await req . writable . write ( raw_input ) ;
		await req . respond ( ) ;
	}
) ;

下载源码

通过命令行克隆项目:

git clone https://github.com/jeremiah-shaulov/deno_fcgi.git

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

左子网 开发教程 deno_fcgi https://www.zuozi.net/31811.html

CrontabManager
上一篇: CrontabManager
angular recaptcha
下一篇: angular recaptcha
常见问题
  • 1、自动:拍下后,点击(下载)链接即可下载;2、手动:拍下后,联系卖家发放即可或者联系官方找开发者发货。
查看详情
  • 1、源码默认交易周期:手动发货商品为1-3天,并且用户付款金额将会进入平台担保直到交易完成或者3-7天即可发放,如遇纠纷无限期延长收款金额直至纠纷解决或者退款!;
查看详情
  • 1、描述:源码描述(含标题)与实际源码不一致的(例:货不对板); 2、演示:有演示站时,与实际源码小于95%一致的(但描述中有”不保证完全一样、有变化的可能性”类似显著声明的除外); 3、发货:不发货可无理由退款; 4、安装:免费提供安装服务的源码但卖家不履行的; 5、收费:价格虚标,额外收取其他费用的(但描述中有显著声明或双方交易前有商定的除外); 6、其他:如质量方面的硬性常规问题BUG等。 注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。
查看详情
  • 1、左子会对双方交易的过程及交易商品的快照进行永久存档,以确保交易的真实、有效、安全! 2、左子无法对如“永久包更新”、“永久技术支持”等类似交易之后的商家承诺做担保,请买家自行鉴别; 3、在源码同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外); 4、在没有”无任何正当退款依据”的前提下,商品写有”一旦售出,概不支持退款”等类似的声明,视为无效声明; 5、在未拍下前,双方在QQ上所商定的交易内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准); 6、因聊天记录可作为纠纷评判依据,故双方联系时,只与对方在左子上所留的QQ、手机号沟通,以防对方不承认自我承诺。 7、虽然交易产生纠纷的几率很小,但一定要保留如聊天记录、手机短信等这样的重要信息,以防产生纠纷时便于左子介入快速处理。
查看详情

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务