我有一些看起来像这样的代码:
use SomeApp;
use Test::WWW::Mechanize::PSGI;
my $mech = Test::WWW::Mechanize::PSGI->new(
app => sub { SomeApp->run(@_) },
);
$mech->get_ok('/');
Run Code Online (Sandbox Code Playgroud)
但是,一旦get_ok()调用,我收到以下警告:
PSGI error: failed to listen to port 8080: Address already in use at .../5.18.1/HTTP/Server/PSGI.pm line 94.
HTTP::Server::PSGI::setup_listener('HTTP::Server::PSGI=HASH(0x7fe6622fad60)') called at .../5.18.1/HTTP/Server/PSGI.pm line 54
Run Code Online (Sandbox Code Playgroud)
是的,我正在使用那个端口做其他事情.来自Test :: WWW :: Mechanize :: PSGI的文档:
此模块允许您测试PSGI Web应用程序,但不需要服务器或发出HTTP请求.相反,它将HTTP请求对象直接传递给PSGI.
所以从理论上讲,我不需要指定一个端口,但是我得到了上面的警告,并且获取的页面返回了500(它们在浏览器中工作正常).我错过了什么?
更改MyApp->run为MyApp->psgi_app结果:
Can't call method "request" on an undefined value at .../5.18.1/Test/WWW/Mechanize/PSGI.pm line 47.
Run Code Online (Sandbox Code Playgroud)
可以使用以下命令复制此错误: …
我正在使用Perl模块的一部分创建一个大型CSV响应.服务器运行在Plack上,我远非专家.
目前我正在使用这样的东西发送回复:
$res->content_type('text/csv');
my $body = '';
query_data (
parameters => \%query_parameters,
callback => sub {
my $row_object = shift;
$body .= $row_object->to_csv;
},
);
$res->body($body);
return $res->finalize;
Run Code Online (Sandbox Code Playgroud)
但是,该query_data函数不是一个快速的函数,并检索大量的记录.在那里,我只是将每一行连接进去,$body并且在处理完所有行之后,发送整个响应.
我不喜欢这两个原因:首先,它需要大量的RAM才能$body被破坏.其次,在该方法完成工作并实际发送响应之前,用户看不到任何响应活动$res->body($body).
我试图在文档中找到答案,但没有找到我需要的东西.
我也试过调用$res->body($row_object->to_csv)我的回调部分,但似乎最终只发送了我做的最后一次调用$res->body,覆盖了所有以前的调用.
有没有办法发送Plack响应来刷新每行的内容,因此用户在收集数据时实时开始接收内容,而不必将所有数据累积到可靠的第一个?
提前感谢您的任何意见!
尝试使用Plack处理多个文件上传.
我的表格:
<form id="file_upload" action="savefile" method="POST" enctype="multipart/form-data">
<input type="file" name="file[]" multiple>
<button>upload</button>
</form>
Run Code Online (Sandbox Code Playgroud)
选择了两个文件,名为:x1和x2.该Data::Dumper结果:
my $u = $req->uploads;
Run Code Online (Sandbox Code Playgroud)
是
$VAR1 = bless( {
'file[]' => bless( {
'headers' => bless( {
'content-disposition' => 'form-data; name="file[]"; filename="x2"',
'content-type' => 'application/octet-stream',
'::std_case' => {
'content-disposition' => 'Content-Disposition'
}
}, 'HTTP::Headers' ),
'filename' => 'x2',
'tempname' => '/var/folders/7l/nhyscwy14bjb_sxr_t2gynpm0000gn/T/7vt04wIrne',
'size' => 146
}, 'Plack::Request::Upload' )
}, 'Hash::MultiValue' );
Run Code Online (Sandbox Code Playgroud)
因此,它只包含第二个文件x2,但在选中时,/var/folders/7l/nhyscwy14bjb_sxr_t2gynpm0000gn/T/它包含上传的两个文件.
问题是如何将两个文件都放到脚本中,而不是最后一个?
我刚刚将一个PageKit(mod_perl)应用程序转换为Plack.这意味着我现在需要一些方法来强制执行Apache2 :: Reques 先前已经处理过的POST_MAX/MAX_BODY .最简单的方法可能只是将nginx放在应用程序前面,但是应用程序已经位于HAProxy后面,我不知道如何使用HAProxy执行此操作.
那么,我的问题是我如何在不首先阅读整个请求的情况下在Plack :: Middleware中强制执行最大体型?
具体来说,我关注文件上传.通过检查大小普拉克::支持::上传是为时已晚,因为整个身体会一直在这一点上阅读.该应用程序将通过Starman部署,所以psgix.streaming应该是true.
我计划用PSGI/Plack开发一个Web应用程序.(与舞者有关,但尚未决定).
应用程序应该是utf8,多语言(使用Locale :: Maketext)和(ofc)将包含给定语言的一些静态页面.我的想法是将它部署在不同的语言域中en.example.com,de.example.com等等.应用程序本身很简单,大多数只会填充带有本地化文本和其他(轻量级)功能的模板.
在一台物理计算机中为多个基于语言的子域部署一个应用程序的最佳解决方案是什么?
我目前的研究以此解决方案结束:需要为每个语言子域使用Apache及其基于名称的虚拟服务器.
<VirtualHost en.example.com>
ServerName en.example.com
DocumentRoot /path/to/site/en/files
<Location />
SetHandler perl-script
PerlResponseHandler Plack::Handler::Apache2
PerlSetVar psgi_app /path/to/site/en/en.psgi
</Location>
</VirtualHost>
Run Code Online (Sandbox Code Playgroud)
问题:
什么其他的想法/事物会对开发本身产生什么影响?
现在我的app.psgi包含(简化):
builder {
enable 'Session', store => 'File'; #default uses Plack::Session::State::Cookie
$app;
};
Run Code Online (Sandbox Code Playgroud)
后来,$app我正在使用:
my $req = Plack::Request->new($env);
my $session = $req->session(); #returns env->{'psgix.session'}
$session->{user} = "name";
Run Code Online (Sandbox Code Playgroud)
它工作正常,例如:
现在,我希望在登录面板中实现"记住我"功能.在这种情况下,不应从浏览器中自动删除sesion-state-cookie.这可以通过使用Plack :: Session :: State :: Cookie中的expires方法来完成.
问题:
如何从我的更改cookie过期(由Session中间件管理)$app.换句话说,如何在这里调用expire方法:
my $req = Plack::Request->new($env);
my $session = $req->session(); #returns env->{'psgix.session'}
$session->{user} = "name"; …Run Code Online (Sandbox Code Playgroud) 两个起点:
use语句的样板代码.关于Unicode的使用的类似问题是如何使用现代perl和utf8默认值来"使用My :: defaults"?该PSGI规范是面向设计字节.编码/解码所有内容是我的责任,因此对于Plack应用程序,正确的方法是对输出和解码输入进行编码,例如:
use Encode;
my $app = sub {
my $output = encode_utf8( myapp() );
return [ 200, [ 'Content-Type' =>'text/plain' ], [ $str ] ];
};
Run Code Online (Sandbox Code Playgroud)使用是否正确
use uni::perl; # or any similar
Run Code Online (Sandbox Code Playgroud)
在PSGI应用程序和/或我的模块中?
uni::perl 将Perl的默认IO更改为UTF-8,因此:
use open qw(:std :utf8);
binmode(STDIN, ":utf8");
binmode(STDOUT, ":utf8");
binmode(STDERR, ":utf8");
Run Code Online (Sandbox Code Playgroud)
这样做会破坏Plack或其中间件吗?或者是在开放时明确编写/解码Plack的应用程序的唯一正确方法,所以没有open编译指示?
我正在尝试将我当前的Apache/Modperl站点转移到Starman,并且需要使用不同的处理程序构建app.psgi以用于不同的文件扩展名.像Apache一样的东西:
<LocationMatch "(\.m|\.mh|\/)$">
SetHandler perl-script
PerlHandler MyApp::Mhandler
</LocationMatch>
<LocationMatch "(\.p|\.ph)$">
SetHandler perl-script
PerlHandler MyApp::Phandler
</LocationMatch>
Run Code Online (Sandbox Code Playgroud)
我现在有:
#app for handle .m and .mh
my $Mapp = Some::PSGI->handler( sub {
...
});
#app for handling .p and .ph
my $Papp = SomeOther::PSGI->handler( sub {
...
});
Run Code Online (Sandbox Code Playgroud)
但如何使用建设者?
builder {
#any extension what is not .m .mh .p .ph - handle as static
#but, only when the request have any extension
enable "Plack::Middleware::Static",
path => __what here__, ???
root => "/my/doc/root";
#and what …Run Code Online (Sandbox Code Playgroud) 这是我的情景:

所以,
https://server1/MyPerlApphttps://server1/MyPerlApp到http://server2:5000问题1:这可能吗?(问,因为我不太了解Apache,这不是一个简单的:
ProxyPass /MyPerlApp http://server2:5000/
Run Code Online (Sandbox Code Playgroud)
因为我需要在server1上验证用户身份,并ProxyPass在验证时设置Only.由于Apache非常灵活,我认为上面的答案是肯定的(但确认和细节非常受欢迎) - 所以这是我的主要具体问题:
perl服务器2上的应用程序的简单方法?例如,使用Apache 为每个查询mod_rewrite附加一个user=username参数,perl应用应该读取的一些HTTP标头吗?我正在寻找如何避免我的starman/perl应用程序中的身份验证例程,因为:
已经有类似的问题,但是:
我有一个简单的Plack应用程序(类似于Plack :: App :: GitHub :: WebHook),我运行它plackup.我在请求处理程序中执行了一个冗长的操作,该操作程序当前使应用程序对后续请求没有响应,直到操作完成.如何在不阻止其他请求的情况下在后台执行操作?还有一个后续问题,我怎样才能最多保留一个在后台队列中运行的作业?
我习惯了libdispatch,所以我喜欢这样的东西:
my $queue = Hypothetical::Concurrency::Queue->new(max_jobs => 1);
$queue->dispatch(sub {
# code
});
Run Code Online (Sandbox Code Playgroud)