FastCgiNet

2025-12-07 0 624

FastCgiNet

用C#编写的FastCGI库。 FASTCGI是一项协议,允许传统的CGI应用程序或控制台应用程序与Web服务器并肩无效(无需更改代码),从而响应用户的HTTP请求。它也可用于运行其他类型的Web应用程序(PHP,ROR和OWIN应用程序),并且出于多种原因是一个很好的托管选择(请参阅官方网站)。应该注意的是, FastCgiNet不打算在没有任何代码更改的情况下启用Console .NET应用程序运行: FastCgiNet不会重定向stdin,stdout或stderr。它为应用程序提供了其他机制,可以用作CGI应用程序。

API和安装

您可以克隆并使用Monodevelops或Visual Studio构建,也可以通过Nuget下载FastCgiNet 。提防API可能会在不久的将来发生变化,尽管并不是很糟糕。也就是说,这里有一些有关如何使用此库的文档:

请求API

FastCgiNet中有两个API:记录API和请求API。请求API是推荐的API,应满足大多数用户的需求。本节描述了它。

Web服务器的观点:

  1. 当浏览器请求页面/URL时,Web服务器必须从应用程序请求答案。
  2. 然后,应用程序将编写HTTP响应状态,HTTP响应标头和标准输出(也可以写入标准错误输出),Web服务器最终将其发送给实际访问者。

因此,如果您正在编写Web服务器,则可能需要每个访问者的请求使用WeberverSocketRequest Request,例如:

FastCgiNet;
using FastCgiNet .Streams;
using FastCgiNet .Requests;

// Let\’s simulate a GET request to http://gi*thub.**com/mzabani/FastCgiNet
var requestedUrl = new Uri(\”http://gi*thub.**com/mzabani/FastCgiNet\”);
string requestMethod = \”GET\”;

// Suppose the FastCgi application is listening on 127.0.0.1, port 9000
var sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Connect(new IPEndPoint(IPAddress.Loopback, 9000));

// There must be no two concurrent requests with the same requestid, even if in different sockets. For simplicity, this request will have request id equal to 1
ushort requestId = 1;
using (var request = new WebServerSocketRequest(sock, requestId))
{
// The BeginRequest Record defines how the application should respond. To know more read FastCgi\’s docs.
request.SendBeginRequest(Role.Responder, true);

// The Request Headers are sent with Params Records. You don\’t have to worry about the mechanisms, though: just write to the Params stream.
using (var nvpWriter = new NvpWriter(request.Params))
{
// The WriteParamsFromUri is a helper method that writes the following Name-Value Pairs:
// HTTP_HOST, HTTPS, SCRIPT_NAME, DOCUMENT_URI, REQUEST_METHOD, SERVER_NAME, QUERY_STRING, REQUEST_URI, SERVER_PROTOCOL, GATEWAY_INTERFACE
nvpWriter.WriteParamsFromUri(requestedUrl, requestMethod);

// The other http request headers, e.g. User-Agent
nvpWriter.Write(\”HTTP_USER_AGENT\”, \”Super cool Browser v1.0\”);
}

// If there is any request body, send it through the Stdin stream. If there is nothing to send, send an End-Of-Request Record (an empty record)
request.SendEmptyStdin();

// At this point, the application is processing the request and cooking up a response for us, so let\’s welcome the incoming data until the response is over
int bytesRead;
byte[] buf = new byte[4096];
while (!request.ResponseComplete)
{
bytesRead = sock.Receive(buf, SocketFlags.None);
request.FeedBytes(buf, 0, bytesRead);
}

// All the application\’s response will be in the Stdout and/or Stderr streams
// Don\’t forget that the very first line of the output is ASCII encoded text with the response status, such as \”Status: 200 OK\”
using (var reader = new StreamReader(request.Stdout))
{
Console.Write(reader.ReadToEnd());
}
}
// The socket and all other resources are automatically disposed at this point.
// This implies that WebServerSocketRequest still doesn\’t multiplex requests
// (not for long, hopefully – also, you can inherit from this class and make
// Dispose() not call CloseSocket() if you want to multiplex requests)
\”>

 using FastCgiNet ;
using FastCgiNet . Streams ;
using FastCgiNet . Requests ;

.. .

// Let\'s simulate a GET request to http://gi*thub.**com/mzabani/FastCgiNet
var requestedUrl = new Uri ( \"http://gi*thub.**com/mzabani/FastCgiNet\" ) ;
string requestMethod = \"GET\" ;

// Suppose the FastCgi application is listening on 127.0.0.1, port 9000
var sock = new Socket ( AddressFamily . InterNetwork , SocketType . Stream , ProtocolType . Tcp ) ;
sock . Connect ( new IPEndPoint ( IPAddress . Loopback , 9000 ) ) ;

// There must be no two concurrent requests with the same requestid, even if in different sockets. For simplicity, this request will have request id equal to 1
ushort requestId = 1 ;
using ( var request = new WebServerSocketRequest ( sock , requestId ) )
{
	// The BeginRequest Record defines how the application should respond. To know more read FastCgi\'s docs.
	request . SendBeginRequest ( Role . Responder , true ) ;

	// The Request Headers are sent with Params Records. You don\'t have to worry about the mechanisms, though: just write to the Params stream.
	using ( var nvpWriter = new NvpWriter ( request . Params ) )
	{
		// The WriteParamsFromUri is a helper method that writes the following Name-Value Pairs:
		// HTTP_HOST, HTTPS, SCRIPT_NAME, DOCUMENT_URI, REQUEST_METHOD, SERVER_NAME, QUERY_STRING, REQUEST_URI, SERVER_PROTOCOL, GATEWAY_INTERFACE
		nvpWriter . WriteParamsFromUri ( requestedUrl , requestMethod ) ;

		// The other http request headers, e.g. User-Agent
		nvpWriter . Write ( \"HTTP_USER_AGENT\" , \"Super cool Browser v1.0\" ) ;
	}

	// If there is any request body, send it through the Stdin stream. If there is nothing to send, send an End-Of-Request Record (an empty record)
	request . SendEmptyStdin ( ) ;

	// At this point, the application is processing the request and cooking up a response for us, so let\'s welcome the incoming data until the response is over
	int bytesRead ;
	byte [ ] buf = new byte [ 4096 ] ;
	while ( ! request . ResponseComplete )
	{
		bytesRead = sock . Receive ( buf , SocketFlags . None ) ;
		request . FeedBytes ( buf , 0 , bytesRead ) ;
	}

	// All the application\'s response will be in the Stdout and/or Stderr streams
	// Don\'t forget that the very first line of the output is ASCII encoded text with the response status, such as \"Status: 200 OK\"
	using ( var reader = new StreamReader ( request . Stdout ) )
	{
		Console . Write ( reader . ReadToEnd ( ) ) ;
	}
}
// The socket and all other resources are automatically disposed at this point.
// This implies that WebServerSocketRequest still doesn\'t multiplex requests 
// (not for long, hopefully - also, you can inherit from this class and make
// Dispose() not call CloseSocket() if you want to multiplex requests)

上面的代码示例很好地证明了使用FastCgiNet容易性!但是,不要忘记处理各种错误。例如,该应用程序可以随时突然关闭插座,如果邪恶的应用程序永远不会发送EndRequest记录,则邪恶的应用程序可能会使您进入无限循环。现在,让我们从应用程序的角度看一下它,并使用applicationsocketRequest类:

FastCgiNet;
using FastCgiNet .Streams;
using FastCgiNet .Requests;

using (var listenSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
listenSock.Bind(new IPEndPoint(IPAddress.Loopback, 9000));
listenSock.Listen(1);

// For simplicity, let\’s accept only one connection
var sock = listenSock.Accept();
using (var request = new ApplicationSocketRequest(sock))
{
// Now let\’s wait until we have received the Params and Stdin streams completely
int bytesRead;
byte[] buf = new byte[4096];
while (!request.Params.IsComplete || !request.Stdin.IsComplete)
{
bytesRead = sock.Receive(buf, SocketFlags.None);
request.FeedBytes(buf, 0, bytesRead);
}

// Let\’s look for the requested path and ignore everything else
string requestedPath = null;
using (var nvpReader = new NvpReader(request.Params))
{
NameValuePair nvp;
while ((nvp = nvpReader.Read()) != null)
{
if (nvp.Name == \”DOCUMENT_URI\”)
requestedPath = nvp.Value;
}
}

// Let\’s write a classic response
using (var writer = new StreamWriter(request.Stdout))
{
// The headers first
writer.NewLine = \”\\r\\n\”;
writer.Write(\”Status: 200 OK\”);
writer.WriteLine(\”Content-Type: text/html\”);
writer.WriteLine();

// Now the body
writer.Write(\”<html><head><title>Hello World</title></head><body><h1>Hello FastCgiNet !</h1>The requested path was {0}</body></html>\”, requestedPath);
}

// Our application status and end of request. The FastCgi Standard defines that returning 0 indicates there were no errors
request.SendEndRequest(0, ProtocolStatus.RequestComplete);
}

// The connection socket and all other resources (except for the
// listen socket) are automatically disposed at this point. This
// implies that ApplicationSocketRequest still doesn\’t multiplex
// requests (not for long, hopefully – also, you can inherit from
// this class and make Dispose() not call CloseSocket() if
// you want to multiplex requests).
}
\”>

 using FastCgiNet ;
using FastCgiNet . Streams ;
using FastCgiNet . Requests ;

.. .

using ( var listenSock = new Socket ( AddressFamily . InterNetwork , SocketType . Stream , ProtocolType . Tcp ) )
{
	listenSock . Bind ( new IPEndPoint ( IPAddress . Loopback , 9000 ) ) ;
	listenSock . Listen ( 1 ) ;

	// For simplicity, let\'s accept only one connection
	var sock = listenSock . Accept ( ) ;
	using ( var request = new ApplicationSocketRequest ( sock ) )
	{
		// Now let\'s wait until we have received the Params and Stdin streams completely
		int bytesRead ;
		byte [ ] buf = new byte [ 4096 ] ;
		while ( ! request . Params . IsComplete || ! request . Stdin . IsComplete )
		{
			bytesRead = sock . Receive ( buf , SocketFlags . None ) ;
			request . FeedBytes ( buf , 0 , bytesRead ) ;
		}

		// Let\'s look for the requested path and ignore everything else
		string requestedPath = null ;
		using ( var nvpReader = new NvpReader ( request . Params ) )
		{
			NameValuePair nvp ;
			while ( ( nvp = nvpReader . Read ( ) ) != null )
			{
				if ( nvp . Name == \"DOCUMENT_URI\" )
					requestedPath = nvp . Value ;
			}
		}

		// Let\'s write a classic response
		using ( var writer = new StreamWriter ( request . Stdout ) )
		{
			// The headers first
			writer . NewLine = \" \\r \\n \" ;
			writer . Write ( \"Status: 200 OK\" ) ;
			writer . WriteLine ( \"Content-Type: text/html\" ) ;
			writer . WriteLine ( ) ;

			// Now the body
			writer . Write ( \"<html><head><title>Hello World</title></head><body><h1>Hello FastCgiNet !</h1>The requested path was {0}</body></html>\" , requestedPath ) ;
		}

		// Our application status and end of request. The FastCgi Standard defines that returning 0 indicates there were no errors
		request . SendEndRequest ( 0 , ProtocolStatus . RequestComplete ) ;
	}

	// The connection socket and all other resources (except for the 
	// listen socket) are automatically disposed at this point. This
	// implies that ApplicationSocketRequest still doesn\'t multiplex
	// requests (not for long, hopefully - also, you can inherit from
	// this class and make Dispose() not call CloseSocket() if 
	// you want to multiplex requests).
}

再一次,不要忘记处理各种插座和邪恶的Web服务器错误。

大量要求和内存消耗(应用程序侧)

如果您使用的是请求API,则可以轻松地将大型请求存储在磁盘上而不是在内存中。实际上,如果您只是复制并粘贴应用程序代码示例, FastCgiNet将自动为您存储大于2KB的请求。可以通过RecordFactory类中的构造函数轻松地指定此尺寸限制,该构造器可以提供给您的FastCgiRequest S(请注意,这在v0.1中未实现;它仅在Master上可用,并且可以在V0.11中可用)。

大量要求和内存消耗(WebServer侧)

托多

记录API

这是一个较低级别的API,可让您构建记录并亲自发送记录。强烈建议您不使用此API,原因有几个:

  • 记录最多保存着65535个字节的内容。这意味着您必须将数据分解为多个记录以通过它,或者事情可能会错误地错误。
  • 此API中没有请求的概念。您必须自己处理。
  • 大量要求 – 想象文件上传 – 是记忆的巨大浪费。请求API可以在指定的限制后自动将记录内容的存储存储到磁盘上;直接处理记录时,执行此操作并不容易。
  • 请求API进行了几项理智检查,使其非常有帮助。

该API是公开的,因为与请求API结合使用,电源用户可能会充分利用它(尽管我自己很少看到用例)。因此,我不会在记录此API方面付出太多努力,因为我将记录请求API。该代码的记录和直观非常完美,因此,如果需要,只需探索API,就可以了。

版本控制

该库仍在略有变化。作者非常努力地保持较高的向后兼容性,尽管某些行为发生了变化,甚至可以预期更改API,直到V0.2。达到v0.2后,我们将输入严格的版本控制方案,该方案将在此处进行详细记录。

托多

  • 多路复用请求
  • 类型GetValues,GetValuesResult,Abortrequest,Data和Unknowntype的记录
  • 更加关注角色过滤器和授权者

下载源码

通过命令行克隆项目:

git clone https://github.com/mzabani/FastCgiNet.git

收藏 (0) 打赏

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

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

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

左子网 开发教程 FastCgiNet https://www.zuozi.net/31901.html

angular google chart
上一篇: angular google chart
OpenReservation
下一篇: OpenReservation
常见问题
  • 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小时在线 专业服务