Panopto / Moodle-2.0-plugin-for-Panopto

Panopto's integration with the Moodle LMS.
http://www.panopto.com
GNU General Public License v3.0
18 stars 38 forks source link

PanoptoTimeoutSoapClient::__doRequest strips splits response headers and body unreliably #201

Closed cameron1729 closed 7 months ago

cameron1729 commented 1 year ago

Bug description

The code that splits the header and body from a response uses $curl->info["header_size"] which corresponds to the value of: https://curl.se/libcurl/c/CURLINFO_HEADER_SIZE.html

Note that the description of CURLINFO_HEADER_SIZE specifies:

The total includes the size of any received headers suppressed by CURLOPT_SUPPRESS_CONNECT_HEADERS.

Since Moodle 4.0.7 (specifically, MDL-76370), when using a proxy, CURLOPT_SUPPRESS_CONNECT_HEADERS is set: https://github.com/moodle/moodle/blob/v4.0.7/lib/filelib.php#L3188

So if you are using a proxy which adds an additional connect header, then the value of $curl->info["header_size"] the length of that connect string is included, even though it's suppressed. Meaning that if you use it to try split the response headers from the body, you will have the wrong position.

Replication steps

On Moodle 4.0.7+:

  1. Place the following test script (adapted from PanoptoTimeoutSoapClient) in your Moodle root and name it panoptotest.php:
<?php

require_once('config.php');
require_once('lib/filelib.php');

$curl = new curl();
$options = [
    'CURLOPT_VERBOSE' => false,
    'CURLOPT_RETURNTRANSFER' => true,
    'CURLOPT_HEADER' => true,
];

$response = $curl->post("https://postman-echo.com/post", ['foo' => 'bar'], $options);
$actualresponse = (isset($curl->info["header_size"])) ? substr($response, $curl->info["header_size"]) : "";
echo $actualresponse;
  1. Browse to [YOUR_MOODLE]/panoptotest.php
  2. Note that the response appears complete
  3. Set up a proxy: docker run -d --name squid-container -e TZ=UTC -p 1729:3128 ubuntu/squid:5.2-22.04_beta
  4. Configure Moodle to use the proxy:
    1. Browse to "Site administration" > "Server" > "HTTP"
    2. Set "Proxy host" to "localhost"
    3. Set "Proxy port" to 1729
  5. Browse to [YOUR_MOODLE]/panoptotest.php (ideally do it in a new tab so you can compare to the response from step 2.)
  6. Note that the response is not complete (the beginning is cut off).
jmalmsten-panopto commented 1 year ago

Hi,

Thank you for bringing this issue to our attention. I have filed an internal work item to investigate this further.

Thanks, Joe

cameron1729 commented 1 year ago

I have also filed https://tracker.moodle.org/browse/MDL-78510 with Moodle HQ as this is "kind of sort of" a regression. Even though $curl->info["header_size"] is behaving correctly.

zeroAps commented 7 months ago

This is fixed by adding CURLOPT_SUPPRESS_CONNECT_HEADERS if defined. Closing this for now.

cameron1729 commented 7 months ago

@zeroAps I'm not sure what you mean. This is a bug in the panopto plugin that happens when CURLOPT_SUPPRESS_CONNECT_HEADERS is defined. The problem is the way the plugin tries to split the response headers from the response body.

The plugin is using $curl->info["header_size"] to split the response headers from the response body when it shouldn't. Has there been a code change in the plugin to rectify this?