unit, PSGI and Mojolicous
Alexander Borisov
alexander.borisov at nginx.com
Thu Jan 24 16:13:47 UTC 2019
Hi Александр,
Please, try this patch for fix the problem:
# HG changeset patch
# User Alexander Borisov <alexander.borisov at nginx.com>
# Date 1548345939 -10800
# Thu Jan 24 19:05:39 2019 +0300
# Node ID a0a93e0673de88519bfd1062bdb6df166aa5ffa9
# Parent dace60fc4926351efe9322761faf974b0ce7964a
Perl: fixed issue with body reading from response object.
diff -r dace60fc4926 -r a0a93e0673de src/perl/nxt_perl_psgi.c
--- a/src/perl/nxt_perl_psgi.c Wed Jan 23 17:47:53 2019 +0300
+++ b/src/perl/nxt_perl_psgi.c Thu Jan 24 19:05:39 2019 +0300
@@ -51,6 +51,9 @@
static SV *nxt_perl_psgi_call_var_application(PerlInterpreter *my_perl,
SV *env, SV *app, nxt_unit_request_info_t *req);
+static SV *
+nxt_perl_psgi_call_method(PerlInterpreter *my_perl, SV *obj, const char *method,
+ nxt_unit_request_info_t *req);
/* For currect load XS modules */
EXTERN_C void boot_DynaLoader(pTHX_ CV *cv);
@@ -84,8 +87,6 @@
SV *result, nxt_unit_request_info_t *req);
static int nxt_perl_psgi_result_body_ref(PerlInterpreter *my_perl,
SV *sv_body, nxt_unit_request_info_t *req);
-static ssize_t nxt_perl_psgi_io_read(nxt_unit_read_info_t *read_info,
- void *dst, size_t size);
static int nxt_perl_psgi_result_array(PerlInterpreter *my_perl,
SV *result, nxt_unit_request_info_t *req);
@@ -251,6 +252,43 @@
}
+static SV *
+nxt_perl_psgi_call_method(PerlInterpreter *my_perl, SV *obj, const char *method,
+ nxt_unit_request_info_t *req)
+{
+ SV *result;
+
+ dSP;
+
+ ENTER;
+ SAVETMPS;
+
+ PUSHMARK(sp);
+ XPUSHs(obj);
+ PUTBACK;
+
+ call_method( method, G_EVAL|G_SCALAR);
+
+ SPAGAIN;
+
+ if (SvTRUE(ERRSV)) {
+ nxt_unit_req_error(req, "PSGI: Failed to call method '%s':\n%s",
+ method, SvPV_nolen(ERRSV));
+
+ result = NULL;
+ }
+ else {
+ result = SvREFCNT_inc(POPs);
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ return result;
+}
+
+
static u_char *
nxt_perl_psgi_module_create(nxt_task_t *task, const char *script)
{
@@ -775,43 +813,40 @@
nxt_perl_psgi_result_body_ref(PerlInterpreter *my_perl, SV *sv_body,
nxt_unit_request_info_t *req)
{
- IO *io;
- nxt_unit_read_info_t read_info;
- nxt_perl_psgi_io_ctx_t io_ctx;
-
- io = GvIO(SvRV(sv_body));
+ SV *data;
+ int rc;
+ size_t len;
+ const char *body;
- if (io == NULL) {
- return NXT_UNIT_OK;
- }
+ do {
+ data = nxt_perl_psgi_call_method(my_perl, sv_body, "getline", req);
+ if (nxt_slow_path(data == NULL)) {
+ return NXT_UNIT_ERROR;
+ }
- io_ctx.my_perl = my_perl;
- io_ctx.fp = IoIFP(io);
+ body = SvPV(data, len);
- read_info.read = nxt_perl_psgi_io_read;
- read_info.eof = PerlIO_eof(io_ctx.fp);
- read_info.buf_size = 8192;
- read_info.data = &io_ctx;
+ if (len == 0) {
+ SvREFCNT_dec(data);
- return nxt_unit_response_write_cb(req, &read_info);
-}
-
+ data = nxt_perl_psgi_call_method(my_perl, sv_body, "close", req);
+ SvREFCNT_dec(data);
-static ssize_t
-nxt_perl_psgi_io_read(nxt_unit_read_info_t *read_info, void *dst, size_t size)
-{
- ssize_t res;
- nxt_perl_psgi_io_ctx_t *ctx;
+ break;
+ }
+
+ rc = nxt_unit_response_write(req, body, len);
- ctx = read_info->data;
-
- dTHXa(ctx->my_perl);
+ SvREFCNT_dec(data);
- res = PerlIO_read(ctx->fp, dst, size);
+ if (nxt_slow_path(rc != NXT_UNIT_OK)) {
+ nxt_unit_req_error(req, "PSGI: Failed to read line from response");
+ return rc;
+ }
- read_info->eof = PerlIO_eof(ctx->fp);
+ } while (1);
- return res;
+ return NXT_UNIT_OK;
}
> 23 янв. 2019 г., в 22:40, Александр Поволоцкий <tarkhil at over.ru> написал(а):
>
>
> On 23.01.2019 19:27, Valentin V. Bartenev wrote:
>> On Wednesday 23 January 2019 18:56:57 Александр Поволоцкий wrote:
>>> Hello
>>>
>>> I'm using Mojolicious::Lite, a Perl framework, which should support PSGI.
>>>
>>> The smallest possible app, however, does not run
>>>
>>> ===
>>> #!/usr/bin/env perl
>>> use Mojolicious::Lite;
>>> get '/' => sub {
>>> my $c = shift;
>>> $c->render(text=>'hello');
>>> };
>>>
>>> app->start;
>>> ===
>>>
>>> 2019/01/23 09:41:23.029 [error] 26579#26579 [unit] #4: PSGI: Failed to
>>> run Perl Application:
>>> Undefined subroutine &main::1 called.
>>>
>>> plackup runs it Ok, so there is some incompatibility, which I do not
>>> know how to trace.
>>>
>>> What kind of error in framework can it be and how to trace it?
>>>
>> [..]
>>
>> https://mojolicious.org/perldoc/Mojolicious/Guides/Cookbook#PSGI-Plack
>>
>> Seems it doesn't behave like PSGI application by default,
>> unless there's a PLACK_ENV environment variable.
>>
>> Unit doesn't set PLACK_ENV by default.
>
> Sorry for doubleposting, but I've found one strange thing.
>
> root at VMNEW:~# telnet localhost 8000
> Trying ::1...
> Trying 127.0.0.1...
> Connected to localhost.
> Escape character is '^]'.
> GET / HTTP/1.0
>
> HTTP/1.1 200 OK
> Content-Length: 6
> Date: Wed, 23 Jan 2019 19:31:37 GMT
> Content-Type: text/html;charset=UTF-8
> Server: Unit/1.7
>
> Connection closed by foreign host.
>
> when I was expecting "hello\n" to be sent as output. You see, Content-Length is correct, but no actual content.
>
> Alex
>
> _______________________________________________
> unit mailing list
> unit at nginx.org <mailto:unit at nginx.org>
> https://mailman.nginx.org/mailman/listinfo/unit <https://mailman.nginx.org/mailman/listinfo/unit>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/unit/attachments/20190124/53438400/attachment.html>
More information about the unit
mailing list