Uploaded image for project: 'Artifactory Binary Repository'
  1. Artifactory Binary Repository
  2. RTFACT-17378

Composer update takes much longer due to not sending correct headers

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: High
    • Resolution: Fixed
    • Affects Version/s: 6.2.0
    • Fix Version/s: 6.8.0
    • Component/s: PHP
    • Labels:
      None

      Description

      When using Artifactory to handle composer repositories (both as a public cached version and a private one), artifactory does not pass the correct headers for the package.json files (i.e. the modified date). This means that when composer comes to do an update, it will never use the version that it cached from Artifactory because it was unable to insert a timestamp into it. This means that doing a "composer up" can take a considerable amount of time for projects with large dependency trees.

       Attached is an example of two different composer.json files. One (p1) uses packagist and the other (p2) uses artifactory. When doing a composer up on the packagist one, it takes approximately 2 seconds from start to finish and, as expected, updates nothing (see p1/bla.txt for the verbose output of that process). You'll notice that most of the package JSON files are simply read from the cache.

       Now, compare this to the Artifactory version. This one took about 20 seconds to complete, again, with no updates performed as expected. It's about x10 slower using Artifactory. If you look at p2/bla.txt the output of this process shows that it had to read from Artifactory for each package.

       20 seconds may not seem like a long time, but this is a composer.json file with one dependency in it. As an example of how painful this is, for one repository that I'm working with, the average amount of time to do a composer update using Artifactory is about 10 minutes!

      The problem lies here: https://github.com/composer/composer/blob/db13cc49603d18b315fdb64f55c5f6fee9e1aa02/src/Composer/Repository/ComposerRepository.php#L711

      After downloading the package information file from Artifactory, it takes (if it exists) the Last-Modified header from that package request and injects it into the cached JSON file. When composer update is run for a second time, it doesn't have this value in the file (because Artifactory isn't passing it) so it will never use the cached version and will always have to request the file again from Artifactory.

       

      Reproduce

      1. Create composer default remote repository
      2. configure config.json and auth.json for remote
      3. perform a composer up on p2 with following composer.json 

      {
        "name": "test/p1",
        "require":

      {     "symfony/framework-bundle": "^4.1"   }

      ,
        "repositories": [
         

      {       "type": "composer",       "url": "http://art.com/artifactory/api/composer/php-remote"     }

      ,
         

      {       "packagist": false     }

        ]
      }

      (notice this request takes around 20 seconds)

       4.  Now remove config.json and auth.json and perform a composer up on p1 with following composer.json

      {
        "name": "test/p1",
        "require":

      {     "symfony/framework-bundle": "^4.1"   }

      }

      (This request finishes much quicker)

        Attachments

          Activity

            People

            • Assignee:
              Dudim Dudi Morad
              Reporter:
              scottm Scott Mosher
            • Votes:
              5 Vote for this issue
              Watchers:
              9 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: