erlang 连接php-fpm

前端时间在网上看见erlang 连接php-fpm的例子,自己跟到弄了一下,下面给我调试后的代码贴出来

我修正了原来代码的2处bug:

1、参数超过128字符出错

2、当php返回超过1024字节时候出错

文件名fastcgi.erl

 
  
- module(fastcgi).
- compile(export_all).


do_request(Argv)
->
Env
= [
{
" SCRIPT_FILENAME " , " E:/phpGame/game/gateway.php " },
{
" websocket " ,Argv}
],
io:format(
" Argv msg: ~ts~n " , [Argv]),
{ok, Socket}
= gen_tcp:connect( " 127.0.0.1 " , 9000 ,[binary, {packet, 0}, {active,true}], 10000 ),
fcgi_send_record(Socket,
1 , 1 , << 1 : 16 ,0: 8 ,0: 40 >> ),
fcgi_send_record(Socket,
4 , 1 , Env),
fcgi_send_record(Socket,
4 , 1 , []),
Bin
= phpRespone(Socket,[]),
gen_tcp:close(Socket),
%% 原报文 << Version: 8 , Type: 8 , RequestId: 16 , ContentLength: 16 ,PaddingLength: 8 , Reserved: 8 ,Str / binary >> = Bin,
<< _: 32 ,ContentLength: 16 ,_: 16 ,Str / binary >> = Bin,
%% 计算输出内容长度
Dlen
= ContentLength - 52 ,
%% 获取内容
<< _H: 52 / binary,Data:Dlen / binary,_Other / binary >> = Str,
io:fwrite(
" rs:~p~n " ,[Data]),
{ok,Data}.


recv_msg(Sock)
->
receive
{tcp, Sock, Bin}
->
io:format(
" Bin msg: ~p~n " , [Bin]),
%% 原报文 << Version: 8 , Type: 8 , RequestId: 16 , ContentLength: 16 ,PaddingLength: 8 , Reserved: 8 ,Str / binary >> = Bin,
<< _: 32 ,ContentLength: 16 ,_: 16 ,Str / binary >> = Bin,
%% 计算输出内容长度
Dlen
= ContentLength - 52 ,
%% 获取内容
<< _H: 52 / binary,Data:Dlen / binary,_Other / binary >> = Str,
io:fwrite(
" rs:~p~n " ,[Data]),
{ok,Data};
{tcp_closed,Sock}
->
io:format(
" socket close: ~p~n " , [Sock]);
_Other
->
io:format(
" Other msg: ~p~n " , [_Other]),
recv_msg(Sock)
after
3000 -> io:format( " Time out.~n " )
end.

phpRespone(Sock,SoFar)
->
receive
{tcp, Sock, Bin}
->
phpRespone(Sock,[Bin
| SoFar]);
{tcp_closed,Sock}
->
list_to_binary(lists:reverse(SoFar));
_Other
->
io:format(
" Other msg: ~p~n " , [_Other]),
phpRespone(Sock,SoFar)
after
3000 -> io:format( " Time out.~n " )
end.


%% 发送选项
fcgi_send_record(Socket, Type, RequestId, NameValueList)
->
EncodedRecord
= fcgi_encode_record(Type, RequestId,NameValueList),
gen_tcp:send(Socket, EncodedRecord).



%% 组包
fcgi_encode_record(Type, RequestId, NameValueList) when is_list(NameValueList)
->
fcgi_encode_record(Type, RequestId,fcgi_encode_name_value_list(NameValueList));

%% 判断ContentData是否满8字节,否则填充
fcgi_encode_record(Type, RequestId, ContentData) when is_binary(ContentData)
->
ContentLength
= size(ContentData),
PaddingLength
= if
ContentLength rem
8 == 0 ->
0;
true
->
8 - (ContentLength rem 8 )
end,
%% 填充数据,每8字节组包 不足用0填充
PaddingData
= << 0:(PaddingLength * 8 ) >> ,
Version
= 1 ,
Reserved
= 0,
<< Version: 8 ,
Type:
8 ,
RequestId:
16 ,
ContentLength:
16 ,
PaddingLength:
8 ,
Reserved:
8 ,
ContentData
/ binary,
PaddingData
/ binary >> .

%% 将环境变量组成binary
fcgi_encode_name_value_list(_NameValueList
= []) ->
<< >> ;

fcgi_encode_name_value_list(_NameValueList
= [{Name, Value} | Tail]) ->
<< (fcgi_encode_name_value(Name,Value)) / binary,(fcgi_encode_name_value_list(Tail)) / binary >> .

fcgi_encode_name_value(Name, _Value
= undefined) ->
fcgi_encode_name_value(Name,
"" );

fcgi_encode_name_value(Name, Value) when is_list(Name)
and is_list(Value) ->
NameSize
= length(Name),
NameSizeData
= << NameSize: 8 >> ,
ValueSize
= length(Value),

if ValueSize < 128 ->
ValueSizeData
= << ValueSize: 8 >> ;
ValueSize
> 127 ->
ValueSizeData
= << (ValueSize bor 16 # 80000000):32>>
end,

<< NameSizeData / binary,ValueSizeData / binary,(list_to_binary(Name)) / binary,(list_to_binary(Value)) / binary >> .

在windows 下启动php cgi可以这样做

php-cgi.exe -b 127.0.0.1:9000

在erlang shell中调用:

2> c(fastcgi).
{ok,fastcgi}
3> fastcgi:do_request("{'uid':1}").

文笔不好,请大家多多包含

转载于:https://www.cnblogs.com/wufoxfm95/archive/2011/04/18/2020007.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值