RotherOSS / otobo

OTOBO is one of the most flexible web-based ticketing systems used for Customer Service, Help Desk, IT Service Management. https://otobo.io/
GNU General Public License v3.0
254 stars 75 forks source link

Use Plack::Request instead of CGI::PSGI #1683

Closed bschmalhofer closed 1 year ago

bschmalhofer commented 2 years ago

Just a small step toward a more standard usage of Plack and PSGI. Kernel::System::Web::Request currently wraps CGI::PSGI. Switch that over to Plack::Request. There are a couple of instances were a CGI object is passed via the parameter WebRequest into the constructor of Kernel::System::Web::Request. These instances would have to be adapted as well. In future, test scripts should pass in HTTP::Request objects via the parameter HTTPRequest.

bschmalhofer commented 2 years ago

Putting this into the wishlist as moving to Plack::Request requires more effort than expected. By design Plack::Request is immutable. But Kernel::System::Web::Request::LoadFormDraft() wants to modify the underlying query object.

bschmalhofer commented 1 year ago

Did some some experimenting for this issue. Plack::Request is not fully compatible with CGI, so there is a bit of work to do.

bschmalhofer commented 1 year ago

Reopening, as I still like the idea.

bschmalhofer commented 1 year ago

Here is the current strategy for eliminating CGI.pm:

bschmalhofer commented 1 year ago

The fallout from the test suite is now down to three failures:

Test Summary Report
-------------------
/opt/otobo/scripts/test/Compile.t                                                                         (Wstat: 0 Tests: 1775 Failed: 0)
  TODO passed:   1137, 1234
/opt/otobo/scripts/test/Selenium/Agent/Admin/ProcessManagement/AdminProcessManagementTransitionAction.t   (Wstat: 768 (exited 3) Tests: 87 Failed: 3)
  Failed tests:  81, 84, 87
  Non-zero exit status: 3
/opt/otobo/scripts/test/Selenium/Agent/AgentTicketService.t                                               (Wstat: 256 (exited 1) Tests: 42 Failed: 1)
  Failed test:  42
  Non-zero exit status: 1
/opt/otobo/scripts/test/Selenium/Output/Ticket/OverviewMedium.t                                           (Wstat: 256 (exited 1) Tests: 29 Failed: 1)
  Failed test:  29
  Non-zero exit status: 1
/opt/otobo/scripts/test/Selenium/Output/Ticket/OverviewPreview.t                                          (Wstat: 256 (exited 1) Tests: 35 Failed: 1)
  Failed test:  35
  Non-zero exit status: 1
/opt/otobo/scripts/test/Selenium/TestingMethods.t                                                         (Wstat: 0 Tests: 36 Failed: 0)
  TODO passed:   21, 24, 28
Files=959, Tests=80558, 5543 wallclock secs (26.94 usr  3.11 sys + 1521.04 cusr 214.30 csys = 1765.39 CPU)
Result: FAIL
ran tests for product OTOBO 11.0.x on host d05d0f2bdf0d .

I investigated what the failure of AgentTicketService.t is about. The cause is a hidden parameter with a redirect URL: <input type="hidden" name="RedirectURL" value="Action=AgentTicketService;Filter=Unlocked;View=Medium;ServiceID=2;SortBy=Age;OrderBy=Up;View=Small;"/> That the parameter View is given twice, seems to be an accident. But the point is that the code apparently relies on that the first declaration View=Medium takes precedence over the second declaration View=Small. So let's take the extra step and let GetParam() return the first value when there are multiple values.

bschmalhofer commented 1 year ago

I discussed this with @svenoe and we decided to go ahead with these changes. The first PR is merged. Some TODOs are still open.

bschmalhofer commented 1 year ago

It is not obvious how the SysConfig Setting WebMaxFileUpload should be enforced on the server side. Plack::Request used HTTP::Entity::Parser which seem to honor the Content-Length header but does not support a hard limit. Maybe a PSGI Middleware can help here. See #2103 for details.

bschmalhofer commented 1 year ago

The failures in scripts/test/GenericInterface/Transport/HTTP/SOAP/ContentCharset.t seem to be an artefact of the test script. In #320, from me @bschmalhofer, a nasty trick was introduced for making the test script pass.

In the script there used to be:

    # Fake STDIN and fill it with the request.
    local *STDIN;
    open STDIN, '<:encoding(UTF-8)', \$Request;    ## no critic qw(OTOBO::ProhibitOpen)

This forced CGI.pm to decode the content as it was read STDIN. Thus the test script always got a decoded string for comparison and the comparison with the Perl strings from the script worked. But in the real world UTF-8 encoded strings are sent over the wire and the processing has no charset information that the content is UTF-8 encoded. Thus the processing has no reason to decode the content. Thus the comparison must be done with the encoded strings. The conversion to HTTP::Request removed the nasty workaround and there were failures again. The new version is hopefully more correct.

bschmalhofer commented 1 year ago

PR is merged. Tests look fine now. The open issues have been adressed. Closing this issue.


Test Summary Report
-------------------
/opt/otobo/scripts/test/Compile.t                                                                         (Wstat: 0 Tests: 1775 Failed: 0)
  TODO passed:   1137, 1234
/opt/otobo/scripts/test/Selenium/Agent/Admin/ProcessManagement/AdminProcessManagementTransitionAction.t   (Wstat: 768 (exited 3) Tests: 87 Failed: 3)
  Failed tests:  81, 84, 87
  Non-zero exit status: 3
/opt/otobo/scripts/test/Selenium/TestingMethods.t                                                         (Wstat: 0 Tests: 36 Failed: 0)
  TODO passed:   21, 24, 28
Files=959, Tests=80732, 5878 wallclock secs (28.15 usr  2.99 sys + 1603.95 cusr 225.94 csys = 1861.03 CPU)
Result: FAIL
ran tests for product OTOBO 11.0.x on host c86ad2058931 .