Moodle
  1. Moodle
  2. MDL-40005

Service.php cannot read the Authorization header when PHP is run as FCGI

    Details

    • Testing Instructions:
      Hide

      1. You'll need to find a tool provider that supports sending grades (I think http://www.imsglobal.org/developers/LTI/test/v1p1/tool.php can)
      2. Add an external tool link pointing to that tool provider (make sure it's configured to accept grades)
      3. Ensure the user you're testing as is enrolled in the course
      4. View the external tool link and have it send a grade back
      5. Check the grade book. A grade should be present for the user and that LTI item.

      Note: your moodle site might need to be publicly available so the Tool can send info back.

      Show
      1. You'll need to find a tool provider that supports sending grades (I think http://www.imsglobal.org/developers/LTI/test/v1p1/tool.php can) 2. Add an external tool link pointing to that tool provider (make sure it's configured to accept grades) 3. Ensure the user you're testing as is enrolled in the course 4. View the external tool link and have it send a grade back 5. Check the grade book. A grade should be present for the user and that LTI item. Note: your moodle site might need to be publicly available so the Tool can send info back.
    • Affected Branches:
      MOODLE_23_STABLE, MOODLE_24_STABLE, MOODLE_25_STABLE
    • Fixed Branches:
      MOODLE_24_STABLE, MOODLE_25_STABLE
    • Pull Master Branch:
      MDL-40005_lti_headers

      Description

      Steps to reproduce:
      Run PHP as FCGI
      Try to POST a grade from an external tool to Moodle
      Nothing is reported

      This is due to the fact that getheaders() used in service.php only works when mod_php is used via Apache.

      My solution was to use a .htaccess with this in it:
      RewriteEngine on
      RewriteRule .* - [E=HTTP_AUTHORIZATION:%

      {HTTP:Authorization}

      ,L]

      And insert the following code at the very top of the page

      if (!function_exists('getallheaders'))
      {
      function getallheaders()
      {
      $headers = '';
      foreach ($_SERVER as $name => $value)
      {
      if (substr($name, 0, 5) == 'HTTP_')

      { $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; }

      }

      $headers['Authorization'] = $_SERVER['HTTP_AUTHORIZATION'];

      return $headers;
      }
      }

        Gliffy Diagrams

        1. htaccess
          0.1 kB
          Eric Warner

          Issue Links

            Activity

            Hide
            Eric Warner added a comment -

            The .htaccess file

            Show
            Eric Warner added a comment - The .htaccess file
            Hide
            Juan Leyva added a comment -

            Just for the record, in PHP 5.4 getallheaders is available only for FCGI

            Show
            Juan Leyva added a comment - Just for the record, in PHP 5.4 getallheaders is available only for FCGI
            Hide
            Juan Leyva added a comment -

            I think that this bug must be marked as important, people using the LTI Provider plugin for connecting two Moodle installations are having problems with this, errors like:

            <b>Fatal error</b>: Call to undefined function getallheaders() in ... mod/lti/service.php on line <b>36</b>

            Seems that being only a function that works for Apache and doesn't work in supported PHP versions by Moodle is critical

            Show
            Juan Leyva added a comment - I think that this bug must be marked as important, people using the LTI Provider plugin for connecting two Moodle installations are having problems with this, errors like: <b>Fatal error</b>: Call to undefined function getallheaders() in ... mod/lti/service.php on line <b>36</b> Seems that being only a function that works for Apache and doesn't work in supported PHP versions by Moodle is critical
            Hide
            Martin Dougiamas added a comment -

            Bumping this one in priority so that Chris (or someone else at MR) can look at it.

            Show
            Martin Dougiamas added a comment - Bumping this one in priority so that Chris (or someone else at MR) can look at it.
            Hide
            Kris Stokking added a comment -

            We'll give this priority attention. Eric/Juan - would you be able to assist with testing? We don't readily have access to non-Apache environments.

            Show
            Kris Stokking added a comment - We'll give this priority attention. Eric/Juan - would you be able to assist with testing? We don't readily have access to non-Apache environments.
            Hide
            Juan Leyva added a comment -

            Hi,

            I'm contacting one of the persons who reported directly to me that issue (thinking that was a problem in the provider) for request him help

            Regards

            Show
            Juan Leyva added a comment - Hi, I'm contacting one of the persons who reported directly to me that issue (thinking that was a problem in the provider) for request him help Regards
            Hide
            Brendan added a comment - - edited

            I've talked with Juan about errors I am experiencing using the lti_provider plugin that seem related. I can do some testing on my set-up if that would help.

            I've posted some "getallheaders()" errors in cron output in this thread.

            My versions info.:

            • The Moodle I'm running as LTI Consumer is Moodle 2.5+ (build: 20130627)
            • The Moodle I'm running as LTI Provider is Moodle 2.4.4+ (build: 20130627)
            • I'm using lti_provider 2.2 (version = 2011121706)
            • I switched FROM running PHP5.3 in FastCGI mode TO 5.4.x CGI, and THEN TO 5.4.x FastCGI (on DreamHost, if that matters)

            The errors in the cron output under the three PHP set-ups are the same.
            ~Brendan

            P.S.: A quick clarification in case anyone needs it: implementing the above workaround requires inserting "the following code at the very top of the page." "The page" is /mod/lti/service.php – NOT /admin/webservice/service.php.

            Show
            Brendan added a comment - - edited I've talked with Juan about errors I am experiencing using the lti_provider plugin that seem related. I can do some testing on my set-up if that would help. I've posted some "getallheaders()" errors in cron output in this thread . My versions info.: The Moodle I'm running as LTI Consumer is Moodle 2.5+ (build: 20130627) The Moodle I'm running as LTI Provider is Moodle 2.4.4+ (build: 20130627) I'm using lti_provider 2.2 (version = 2011121706) I switched FROM running PHP5.3 in FastCGI mode TO 5.4.x CGI, and THEN TO 5.4.x FastCGI (on DreamHost, if that matters) The errors in the cron output under the three PHP set-ups are the same. ~Brendan P.S.: A quick clarification in case anyone needs it: implementing the above workaround requires inserting "the following code at the very top of the page." "The page" is /mod/lti/service.php – NOT /admin/webservice/service.php.
            Hide
            Mark Nielsen added a comment -

            This should be safe to backport and it should also resolve MDL-32352.

            Show
            Mark Nielsen added a comment - This should be safe to backport and it should also resolve MDL-32352 .
            Hide
            Brendan added a comment - - edited

            I followed the suggested "workaround" instructions and, behold, a grade did transfer. I've got more experimenting to do, as only the quiz average was transferred, neither the individual quiz scores nor the quiz titles (but perhaps this is "how it is" when sharing a COURSE rather than an ASSIGNMENT).

            Here is the cron output, which still contains an fopen error:

            Processing customized cron scripts ...Processing cron function for local_ltiprovider...
            Running cron for ltiprovider
             Starting sync tool id 1 course id 2
             Completed sync tool id 1 course id 2 users=0 sent=0 errors=0
             Starting sync tool id 2 course id 3
             Problem with http://moodle.thereitis.org/mod/lti/service.php, fopen(http://moodle.thereitis.org/mod/lti/service.php): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
             
             User grade sent to remote system. userid: 6 grade: 1
             Completed sync tool id 2 course id 3 users=9 sent=1 errors=1
             Starting sync tool id 3 course id 3
             Completed sync tool id 3 course id 3 users=1 sent=0 errors=0
            done. (45 dbqueries, 1.63 seconds) 

            ... and after a couple quizzes - to change the average - the output was the same except for:

            User grade sent to remote system. userid: 6 grade: 0.6666667

            Show
            Brendan added a comment - - edited I followed the suggested "workaround" instructions and, behold, a grade did transfer. I've got more experimenting to do, as only the quiz average was transferred, neither the individual quiz scores nor the quiz titles (but perhaps this is "how it is" when sharing a COURSE rather than an ASSIGNMENT). Here is the cron output, which still contains an fopen error: Processing customized cron scripts ...Processing cron function for local_ltiprovider... Running cron for ltiprovider Starting sync tool id 1 course id 2 Completed sync tool id 1 course id 2 users=0 sent=0 errors=0 Starting sync tool id 2 course id 3 Problem with http://moodle.thereitis.org/mod/lti/service.php, fopen(http://moodle.thereitis.org/mod/lti/service.php): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found   User grade sent to remote system. userid: 6 grade: 1 Completed sync tool id 2 course id 3 users=9 sent=1 errors=1 Starting sync tool id 3 course id 3 Completed sync tool id 3 course id 3 users=1 sent=0 errors=0 done. (45 dbqueries, 1.63 seconds) ... and after a couple quizzes - to change the average - the output was the same except for: User grade sent to remote system. userid: 6 grade: 0.6666667
            Hide
            Tim Hunt added a comment -

            This and MDL-32352 seem to be duplicates of each other. Would you like to confirm and close one?

            Show
            Tim Hunt added a comment - This and MDL-32352 seem to be duplicates of each other. Would you like to confirm and close one?
            Hide
            Mark Nielsen added a comment -

            Closed MDL-32352

            Show
            Mark Nielsen added a comment - Closed MDL-32352
            Hide
            Dan Poltawski added a comment -

            Hi Mark,

            Seems simple enough and looks OK. Please could you add testing instructions and create branches for 24/25 and then this can be sent to integration.

            thanks,

            Dan

            Show
            Dan Poltawski added a comment - Hi Mark, Seems simple enough and looks OK. Please could you add testing instructions and create branches for 24/25 and then this can be sent to integration. thanks, Dan
            Hide
            Mark Nielsen added a comment -

            Adding instructions from the duplicate issue.

            Show
            Mark Nielsen added a comment - Adding instructions from the duplicate issue.
            Hide
            Sam Hemelryk added a comment -

            Thanks guys - change looked good and has been cherry-picked back to 24 + 25.

            Many thanks
            Sam

            Show
            Sam Hemelryk added a comment - Thanks guys - change looked good and has been cherry-picked back to 24 + 25. Many thanks Sam
            Hide
            Rajesh Taneja added a comment -

            Thanks for fixing this Mark,

            Works as expected.

            Show
            Rajesh Taneja added a comment - Thanks for fixing this Mark, Works as expected.
            Hide
            Sam Hemelryk added a comment -

            Against all probability we've achieved normality. You changes didn't break the tests I pretended to run and are now immortalised upstream. Good for you!

            "It was a programming technique that had been reverse-engineered from the sort of psychotic mental blocks that otherwise perfectly normal people had been observed invariably to develop when elected to high political office."
            Adams, D (1992) Mostly Harmless. London: William Heinemann.

            Show
            Sam Hemelryk added a comment - Against all probability we've achieved normality. You changes didn't break the tests I pretended to run and are now immortalised upstream. Good for you! "It was a programming technique that had been reverse-engineered from the sort of psychotic mental blocks that otherwise perfectly normal people had been observed invariably to develop when elected to high political office." Adams, D (1992) Mostly Harmless. London: William Heinemann.
            Hide
            Brendan added a comment -

            Nice job, folks. Thank you!

            Show
            Brendan added a comment - Nice job, folks. Thank you!
            Hide
            Juan Leyva added a comment -

            that was super fast, thanks all for the good work!

            Show
            Juan Leyva added a comment - that was super fast, thanks all for the good work!

              People

              • Votes:
                1 Vote for this issue
                Watchers:
                10 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: