Как отправить собственный код состояния http с помощью mod_perl

Я написал программу CGI и отправляю клиенту ошибку состояния с заголовком HTTP. но когда я попытался использовать mod_perl, он ответил только со статусом 200 ok. Как я могу отправить собственный код состояния?

вот код, когда я хочу ответить ошибкой пользовательского статуса:

my $cgi      = new CGI;
print $cgi->header(-type=>"text/html", -charset=>'utf-8', -status=>599);

EDIT:
вот код:

#!/usr/bin/perl -w
use strict;
use warnings;
use CGI;
use SessionManagement;


my $cgi      = new CGI;
my $method = $cgi->param("method");

my $sessionManagement = new SessionManagement(cgi=>$cgi);
if($sessionManagement){

  if (defined($method)) {
    if($method eq "authentication") {
        loginMethod($cgi,$sessionManagement);
    } elsif ($method eq "someMethod"){
        someMethod($cgi);
    } else{
        print $cgi->header(-type=>"text/xml", -charset=>'utf-8');
        print "<html>method does not exist</html>";
    }

  } else {
      print $cgi->header(-type=>"text/html", -charset=>'utf-8' , -status=>599);
      print "<html>blah blah</html>";
  }

}else{
  print $cgi->header(-type=>"text/html", -charset=>'utf-8' , -status=>599);
  print "<html>blah blah</html>";
}

-------------------------------------------

ИЗМЕНИТЬ 2

предоставление дополнительной информации: когда я использую команду curl -v 192.168.1.212/mymodperl/test.pl в оболочке.
вот ответ:

* About to connect() to 192.168.1.212 port 80 (#0)
*   Trying 192.168.1.212... connected
* Connected to 192.168.1.212 (192.168.1.212) port 80 (#0)
> GET /mymodperl/test.pl HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.15.3 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: 192.168.1.212
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Sat, 25 Nov 2017 11:04:18 GMT
< Server: Apache/2.2.15 (Red Hat)
< Connection: close
< Transfer-Encoding: chunked
< Content-Type: text/html; charset=ISO-8859-1
< 
<html>hi</html><!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>500 Internal Server Error</title>
</head><body>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error or
misconfiguration and was unable to complete
your request.</p>
<p>Please contact the server administrator,
 root@localhost and inform them of the time the error occurred,
and anything you might have done that may have
caused the error.</p>
<p>More information about this error may be available
in the server error log.</p>
<hr>
<address>Apache/2.2.15 (Red Hat) Server at 192.168.1.212 Port 80</address>
</body></html>
* Closing connection #0

person Sarah Aziziyan    schedule 23.11.2017    source источник
comment
Вы понимаете, что сейчас 2017 год?   -  person Gerhard    schedule 23.11.2017
comment
@GerhardBarnard Да :))   -  person Sarah Aziziyan    schedule 23.11.2017
comment
Хорошо, а где часть mod_perl, с которой у вас возникли проблемы?   -  person Gerhard    schedule 23.11.2017
comment
Кроме того, я откладываю свой ответ до тех пор, пока я не получу ясность от вас и не опубликую.   -  person Gerhard    schedule 23.11.2017
comment
@GerhardBarnard, что вы имеете в виду под частью mod_perl? Я поместил свой код в каталог mod_perl и вызвал его в браузере, он запускается через mod_perl. но статусы, которые я поставил, не работают.   -  person Sarah Aziziyan    schedule 23.11.2017
comment
это то, что я имею в виду, покажите мне, как вы это называете, и вашу структуру каталогов   -  person Gerhard    schedule 23.11.2017
comment
Можете ли вы запустить curl -v <url> для того, где вы ожидаете код 599, и опубликовать вывод, который вы получили в своем вопросе? Статус - это первое, что должно вернуться, и я предполагаю, что это может быть случай ошибки порядка заголовка.   -  person Tarun Lalwani    schedule 25.11.2017
comment
Вы должны попробовать использовать $cgi->$header->status('599 Some Issue'); перед печатью или настройкой любого заголовка   -  person Tarun Lalwani    schedule 25.11.2017
comment
@TarunLalwani Я сделал «curl -v ‹myUrl›» и снова получил 200 ок. Я очистил все остальные настройки заголовка, кроме статуса, и все еще имею ту же проблему.   -  person Sarah Aziziyan    schedule 25.11.2017
comment
Я думаю, что это проблема mod_perl, должен быть какой-то другой способ установить статус заголовка в mod_perl, потому что у меня нет проблем с запуском кода в режиме CGI.   -  person Sarah Aziziyan    schedule 25.11.2017
comment
@TarunLalwani Я отредактировал вопрос и добавил ответ curl.   -  person Sarah Aziziyan    schedule 25.11.2017
comment
Использование mod_perl для написания веб-приложений не рекомендуется. Вы не рассматривали что-то основанное на PSGI?   -  person melpomene    schedule 25.11.2017
comment
У меня отлично работает на Apache/2.4.18, может быть это из-за более старой версии apache? Можешь попробовать с последней?   -  person Tarun Lalwani    schedule 25.11.2017
comment
вы пробовали это с mod_perl ??? @TarunLalwani   -  person Sarah Aziziyan    schedule 26.11.2017
comment
Я думаю, что я смешал CGI и мод Perl. Позвольте мне попробовать это   -  person Tarun Lalwani    schedule 26.11.2017
comment
Вы можете просто напечатать заголовок, который хотите. В том, что делает CGI-›header, нет никакой настоящей магии. Я бы также рекомендовал использовать действительный код возврата HTTP.   -  person Jim Black    schedule 28.11.2017
comment
Не используйте больше Perl-модуль CGI и не изобретайте новые HTTP-коды.   -  person Patrick Mevzek    schedule 30.11.2017
comment
@melpomene Спасибо за ваше предложение, но сейчас мне нужно заставить его работать с mod_perl (не мой выбор). но я рассмотрю ваш совет для более поздних приложений. Спасибо.   -  person Sarah Aziziyan    schedule 02.12.2017
comment
@JimBlack на самом деле я отправил другие действительные коды, и они все еще не работают. поэтому я знаю, что проблема не в отправке действительного кода HTTP.   -  person Sarah Aziziyan    schedule 02.12.2017
comment
@PatrickMevzek Я предлагаю вам внимательно прочитать вопрос. Я использую mod_perl, и мне нужно использовать пользовательский код. если у вас есть какие-либо решения, я был бы рад услышать это.   -  person Sarah Aziziyan    schedule 02.12.2017
comment
Не изобретайте новые HTTP-коды, какое бы программное обеспечение вы ни использовали. Есть стандарт, и его нельзя расширять лично какими-либо новыми кодами... конечно, если вы хотите взаимодействия и соблюдения стандартов. Вы нигде не указали вескую причину для создания нового значения ответа. Представьте, если бы вы всем нравились, как, по-вашему, могла бы работать сеть?   -  person Patrick Mevzek    schedule 02.12.2017
comment
Нет закона против использования пользовательского HTTP-кода. и в программировании нет границ. Как это сделать, вы найдете в ответах ниже. если я хочу сделать что-то, я заставлю это работать. Это способ раздвинуть границы. Мне нравится иметь растущее мышление.   -  person Sarah Aziziyan    schedule 02.12.2017
comment
Вы ошибаетесь, есть закон. HTTP — это протокол, определенный RFC IETF. Они не говорят, что вы можете в одностороннем порядке принимать новые коды статуса. Это не имеет ничего общего с растущим мышлением.   -  person Patrick Mevzek    schedule 04.12.2017
comment
@PatrickMevzek RFC не являются законами. они определяют некоторые правила, протоколы и стандарты. нарушение этих правил или стандартов не сажает вас в тюрьму!!! плюс это выполнимо. Также допустимо даже создать собственный протокол, если ваши приложения понимают его и нормально с ним работают. У меня нет информации о законах вашей страны/штата, возможно, это закон вашего региона. но насколько я помню, в RFC 2616 ничего подобного не написано.   -  person Sarah Aziziyan    schedule 04.12.2017
comment
Игра словами ни к чему плодотворному не приводит. Стандарты существуют по какой-то причине, начиная с функциональной совместимости. Если вы предпочитаете ломать все и делать свое дело в одиночестве в своем углу, вы правы, технически вы свободны в этом. Но это вовсе не означает, что это хорошая идея. EOT.   -  person Patrick Mevzek    schedule 04.12.2017


Ответы (1)


С http://www.perlmonks.org/?node_id=826769 путь к установить код состояния

package My::Handler;

use strict;
use warnings 'all';
use Apache2::RequestRec;

sub handler : method {
  my ($class, $r) = @_;

  $r->status( 401 );
  return 401;
}

1;# return true:

РЕДАКТИРОВАТЬ: уточнение

Из https://perl.apache.org/docs/2.0/user/handlers/intro.html

Что такое хэндлеры?

Apache различает несколько фаз, для которых он предоставляет ловушки (поскольку функции C называются ap_hook_), где модули могут подключать различные обратные вызовы для расширения и изменения поведения веб-сервера по умолчанию. mod_perl предоставляет интерфейс Perl для большинства доступных хуков, поэтому авторы модулей mod_perl могут изменить поведение Apache в Perl. Эти обратные вызовы обычно называются обработчиками, поэтому директивы конфигурации для обработчиков mod_perl выглядят так: PerlFooHandler, где Foo — одно из имен обработчиков. Например, PerlResponseHandler настраивает обратный вызов ответа.

Типичный обработчик — это просто Perl-пакет с подпрограммой-обработчиком. Например:

file:MyApache2/CurrentTime.pm
----------------------------
package MyApache2::CurrentTime;

use strict;
use warnings;

use Apache2::RequestRec ();
use Apache2::RequestIO ();

use Apache2::Const -compile => qw(OK);

sub handler {
  my $r = shift;

  $r->content_type('text/plain');
  $r->print("Now is: " . scalar(localtime) . "\n");

  return Apache2::Const::OK;
}
1;

Этот обработчик просто возвращает текущую дату и время в качестве ответа.

Так как это обработчик ответа, мы настраиваем его в httpd.conf:

PerlResponseHandler MyApache2::CurrentTime

Поскольку обработчик ответа должен быть настроен для определенного местоположения, давайте напишем полный раздел конфигурации:

PerlModule MyApache2::CurrentTime
<Location /time>
  SetHandler modperl
  PerlResponseHandler MyApache2::CurrentTime
</Location>

Теперь, когда отправляется запрос на http://localhost/time, выполняется этот обработчик ответа, и ответ, который включает текущий время возвращается клиенту.

person mikep    schedule 26.11.2017
comment
Я читал это раньше, но я не знаю, как использовать это в своем собственном коде. @mikep - person Sarah Aziziyan; 26.11.2017
comment
ОП не пишет обработчик mod_perl; они пишут сценарий реестра. - person ikegami; 27.11.2017
comment
@SarahAziziyan, кажется, это невозможно сделать с помощью сценария реестра. Таким образом, то, как вы это делаете, не позволит вам изменить статус. Вам нужно будет использовать обработчик, чтобы заставить его работать - person Tarun Lalwani; 27.11.2017
comment
@mikep Я попытаюсь использовать обработчик, как вы упомянули, и сообщу вам, сработало ли это. Благодарю. - person Sarah Aziziyan; 27.11.2017
comment
@TarunLalwani Я попробую использовать обработчик. - person Sarah Aziziyan; 27.11.2017
comment
@mikep Я пытался использовать обработчик, но, насколько я читал, обработчики могут обрабатывать запросы с определенных URL-адресов. В моем случае (код, который я написал в вопросе), мне нужно отправить сообщение об ошибке пользователю с некоторым статусом (например, 599) в случае, если они не отправляют параметр с именем «метод». но я не хочу отправлять один и тот же статус ошибки для всех запросов, поступающих в test.pl. - person Sarah Aziziyan; 28.11.2017
comment
Если хотите, мы можем обсудить это в чате. - person mikep; 28.11.2017
comment
Спасибо за ваше время и энергию @mikep. вы были огромной помощью. - person Sarah Aziziyan; 02.12.2017
comment
@Sarah Aziziyan, рада помочь :) - person mikep; 02.12.2017
comment
@TarunLalwani Конечно, вы можете установить статус с помощью сценария реестра. Вы можете получить объект запроса с помощью my $r = Apache2::RequestUtil->request; или с помощью начального $r = shift() в скрипте. Конечно, лучше заключить весь сценарий в подпрограмму, а затем вызвать эту подпрограмму, передав объект запроса в качестве аргумента, аналогично использованию метода handler в модуле обработчика Perl. - person Francisco Zarabozo; 08.11.2018