We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
docs should not use underscores in http headers for auth
**Version**
any

**Describe the bug**
https://docs.pulpproject.org/pulpcore/authentication/webserver.html#webserver-auth-with-reverse-proxy says:
> With nginx providing authentication, all it can do is pass REMOTE_USER (or similar name) to the application webserver, i.e. gunicorn. You can pass the header as part of the proxy request in nginx with a config line like:
>     
>    proxy_set_header REMOTE_USER $remote_user;

But since gunicorn 22.0 (more precisely https://github.com/benoitc/gunicorn/commit/72b8970dbf2bf3444eb2e8b12aeff1a3d5922a9a/  https://github.com/benoitc/gunicorn/issues/2799) headers with underscores are forbidden by default.

If the docs would use a dash, so `proxy_set_header REMOTE-USER …` things would work :)

**Additional context**
Grant made me file this, and I did not want to post a screenshot of our colorful conversation ;)

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pulpcore/app/tasks/repository.py`
Content:
```
1 from gettext import gettext as _
2 from logging import getLogger
3 
4 from django.db import transaction
5 
6 from pulpcore.app import models, serializers
7 
8 log = getLogger(__name__)
9 
10 
11 def delete(repo_id):
12     """
13     Delete a :class:`~pulpcore.app.models.Repository`
14 
15     Args:
16         repo_id (int): The name of the repository to be deleted
17     """
18 
19     models.Repository.objects.filter(pk=repo_id).delete()
20 
21 
22 def update(repo_id, partial=True, data=None):
23     """
24     Updates a :class:`~pulpcore.app.models.Repository`
25 
26     Args:
27         repo_id (int): The id of the repository to be updated
28         partial (bool): Boolean to allow partial updates. If set to False, values for all
29                         required fields must be passed or a validation error will be raised.
30                         Defaults to True
31         data (QueryDict): dict of attributes to change and their new values; if None, no attempt to
32                      update the repository object will be made
33     """
34     instance = models.Repository.objects.get(pk=repo_id)
35     serializer = serializers.RepositorySerializer(instance, data=data, partial=partial)
36     serializer.is_valid(raise_exception=True)
37     serializer.save()
38 
39 
40 def delete_version(pk):
41     """
42     Delete a repository version by squashing its changes with the next newer version. This ensures
43     that the content set for each version stays the same.
44 
45     There must be a newer version to squash into. If we deleted the latest version, the next content
46     change would create a new one of the same number, which would violate the immutability
47     guarantee.
48 
49     Args:
50         pk (int): the primary key for a RepositoryVersion to delete
51 
52     Raises:
53         models.RepositoryVersion.DoesNotExist: if there is not a newer version to squash into.
54             TODO: something more friendly
55     """
56     with transaction.atomic():
57         try:
58             version = models.RepositoryVersion.objects.get(pk=pk)
59         except models.RepositoryVersion.DoesNotExist:
60             log.info(_('The repository version was not found. Nothing to do.'))
61             return
62 
63         log.info(_('Deleting and squashing version %(v)d of repository %(r)s'),
64                  {'v': version.number, 'r': version.repository.name})
65 
66         version.delete()
67 
68 
69 def add_and_remove(repository_pk, add_content_units, remove_content_units, base_version_pk=None):
70     """
71     Create a new repository version by adding and then removing content units.
72 
73     Args:
74         repository_pk (int): The primary key for a Repository for which a new Repository Version
75             should be created.
76         add_content_units (list): List of PKs for :class:`~pulpcore.app.models.Content` that
77             should be added to the previous Repository Version for this Repository.
78         remove_content_units (list): List of PKs for:class:`~pulpcore.app.models.Content` that
79             should be removed from the previous Repository Version for this Repository.
80         base_version_pk (int): the primary key for a RepositoryVersion whose content will be used
81             as the initial set of content for our new RepositoryVersion
82     """
83     repository = models.Repository.objects.get(pk=repository_pk)
84 
85     if base_version_pk:
86         base_version = models.RepositoryVersion.objects.get(pk=base_version_pk)
87     else:
88         base_version = None
89 
90     if '*' in remove_content_units:
91         latest = models.RepositoryVersion.latest(repository)
92         remove_content_units = latest.content.values_list('pk', flat=True)
93 
94     with models.RepositoryVersion.create(repository, base_version=base_version) as new_version:
95         new_version.remove_content(models.Content.objects.filter(pk__in=remove_content_units))
96         new_version.add_content(models.Content.objects.filter(pk__in=add_content_units))
97
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pulpcore/app/tasks/repository.py b/pulpcore/app/tasks/repository.py
--- a/pulpcore/app/tasks/repository.py
+++ b/pulpcore/app/tasks/repository.py
@@ -89,7 +89,10 @@
 
     if '*' in remove_content_units:
         latest = models.RepositoryVersion.latest(repository)
-        remove_content_units = latest.content.values_list('pk', flat=True)
+        if latest:
+            remove_content_units = latest.content.values_list('pk', flat=True)
+        else:
+            remove_content_units = []
 
     with models.RepositoryVersion.create(repository, base_version=base_version) as new_version:
         new_version.remove_content(models.Content.objects.filter(pk__in=remove_content_units))

{"golden_diff": "diff --git a/pulpcore/app/tasks/repository.py b/pulpcore/app/tasks/repository.py\n--- a/pulpcore/app/tasks/repository.py\n+++ b/pulpcore/app/tasks/repository.py\n@@ -89,7 +89,10 @@\n \n     if '*' in remove_content_units:\n         latest = models.RepositoryVersion.latest(repository)\n-        remove_content_units = latest.content.values_list('pk', flat=True)\n+        if latest:\n+            remove_content_units = latest.content.values_list('pk', flat=True)\n+        else:\n+            remove_content_units = []\n \n     with models.RepositoryVersion.create(repository, base_version=base_version) as new_version:\n         new_version.remove_content(models.Content.objects.filter(pk__in=remove_content_units))\n", "issue": "docs should not use underscores in http headers for auth\n**Version**\r\nany\r\n\r\n**Describe the bug**\r\nhttps://docs.pulpproject.org/pulpcore/authentication/webserver.html#webserver-auth-with-reverse-proxy says:\r\n> With nginx providing authentication, all it can do is pass REMOTE_USER (or similar name) to the application webserver, i.e. gunicorn. You can pass the header as part of the proxy request in nginx with a config line like:\r\n>     \r\n>    proxy_set_header REMOTE_USER $remote_user;\r\n\r\nBut since gunicorn 22.0 (more precisely https://github.com/benoitc/gunicorn/commit/72b8970dbf2bf3444eb2e8b12aeff1a3d5922a9a/  https://github.com/benoitc/gunicorn/issues/2799) headers with underscores are forbidden by default.\r\n\r\nIf the docs would use a dash, so `proxy_set_header REMOTE-USER \u2026` things would work :)\r\n\r\n**Additional context**\r\nGrant made me file this, and I did not want to post a screenshot of our colorful conversation ;)\n", "before_files": [{"content": "from gettext import gettext as _\nfrom logging import getLogger\n\nfrom django.db import transaction\n\nfrom pulpcore.app import models, serializers\n\nlog = getLogger(__name__)\n\n\ndef delete(repo_id):\n    \"\"\"\n    Delete a :class:`~pulpcore.app.models.Repository`\n\n    Args:\n        repo_id (int): The name of the repository to be deleted\n    \"\"\"\n\n    models.Repository.objects.filter(pk=repo_id).delete()\n\n\ndef update(repo_id, partial=True, data=None):\n    \"\"\"\n    Updates a :class:`~pulpcore.app.models.Repository`\n\n    Args:\n        repo_id (int): The id of the repository to be updated\n        partial (bool): Boolean to allow partial updates. If set to False, values for all\n                        required fields must be passed or a validation error will be raised.\n                        Defaults to True\n        data (QueryDict): dict of attributes to change and their new values; if None, no attempt to\n                     update the repository object will be made\n    \"\"\"\n    instance = models.Repository.objects.get(pk=repo_id)\n    serializer = serializers.RepositorySerializer(instance, data=data, partial=partial)\n    serializer.is_valid(raise_exception=True)\n    serializer.save()\n\n\ndef delete_version(pk):\n    \"\"\"\n    Delete a repository version by squashing its changes with the next newer version. This ensures\n    that the content set for each version stays the same.\n\n    There must be a newer version to squash into. If we deleted the latest version, the next content\n    change would create a new one of the same number, which would violate the immutability\n    guarantee.\n\n    Args:\n        pk (int): the primary key for a RepositoryVersion to delete\n\n    Raises:\n        models.RepositoryVersion.DoesNotExist: if there is not a newer version to squash into.\n            TODO: something more friendly\n    \"\"\"\n    with transaction.atomic():\n        try:\n            version = models.RepositoryVersion.objects.get(pk=pk)\n        except models.RepositoryVersion.DoesNotExist:\n            log.info(_('The repository version was not found. Nothing to do.'))\n            return\n\n        log.info(_('Deleting and squashing version %(v)d of repository %(r)s'),\n                 {'v': version.number, 'r': version.repository.name})\n\n        version.delete()\n\n\ndef add_and_remove(repository_pk, add_content_units, remove_content_units, base_version_pk=None):\n    \"\"\"\n    Create a new repository version by adding and then removing content units.\n\n    Args:\n        repository_pk (int): The primary key for a Repository for which a new Repository Version\n            should be created.\n        add_content_units (list): List of PKs for :class:`~pulpcore.app.models.Content` that\n            should be added to the previous Repository Version for this Repository.\n        remove_content_units (list): List of PKs for:class:`~pulpcore.app.models.Content` that\n            should be removed from the previous Repository Version for this Repository.\n        base_version_pk (int): the primary key for a RepositoryVersion whose content will be used\n            as the initial set of content for our new RepositoryVersion\n    \"\"\"\n    repository = models.Repository.objects.get(pk=repository_pk)\n\n    if base_version_pk:\n        base_version = models.RepositoryVersion.objects.get(pk=base_version_pk)\n    else:\n        base_version = None\n\n    if '*' in remove_content_units:\n        latest = models.RepositoryVersion.latest(repository)\n        remove_content_units = latest.content.values_list('pk', flat=True)\n\n    with models.RepositoryVersion.create(repository, base_version=base_version) as new_version:\n        new_version.remove_content(models.Content.objects.filter(pk__in=remove_content_units))\n        new_version.add_content(models.Content.objects.filter(pk__in=add_content_units))\n", "path": "pulpcore/app/tasks/repository.py"}], "after_files": [{"content": "from gettext import gettext as _\nfrom logging import getLogger\n\nfrom django.db import transaction\n\nfrom pulpcore.app import models, serializers\n\nlog = getLogger(__name__)\n\n\ndef delete(repo_id):\n    \"\"\"\n    Delete a :class:`~pulpcore.app.models.Repository`\n\n    Args:\n        repo_id (int): The name of the repository to be deleted\n    \"\"\"\n\n    models.Repository.objects.filter(pk=repo_id).delete()\n\n\ndef update(repo_id, partial=True, data=None):\n    \"\"\"\n    Updates a :class:`~pulpcore.app.models.Repository`\n\n    Args:\n        repo_id (int): The id of the repository to be updated\n        partial (bool): Boolean to allow partial updates. If set to False, values for all\n                        required fields must be passed or a validation error will be raised.\n                        Defaults to True\n        data (QueryDict): dict of attributes to change and their new values; if None, no attempt to\n                     update the repository object will be made\n    \"\"\"\n    instance = models.Repository.objects.get(pk=repo_id)\n    serializer = serializers.RepositorySerializer(instance, data=data, partial=partial)\n    serializer.is_valid(raise_exception=True)\n    serializer.save()\n\n\ndef delete_version(pk):\n    \"\"\"\n    Delete a repository version by squashing its changes with the next newer version. This ensures\n    that the content set for each version stays the same.\n\n    There must be a newer version to squash into. If we deleted the latest version, the next content\n    change would create a new one of the same number, which would violate the immutability\n    guarantee.\n\n    Args:\n        pk (int): the primary key for a RepositoryVersion to delete\n\n    Raises:\n        models.RepositoryVersion.DoesNotExist: if there is not a newer version to squash into.\n            TODO: something more friendly\n    \"\"\"\n    with transaction.atomic():\n        try:\n            version = models.RepositoryVersion.objects.get(pk=pk)\n        except models.RepositoryVersion.DoesNotExist:\n            log.info(_('The repository version was not found. Nothing to do.'))\n            return\n\n        log.info(_('Deleting and squashing version %(v)d of repository %(r)s'),\n                 {'v': version.number, 'r': version.repository.name})\n\n        version.delete()\n\n\ndef add_and_remove(repository_pk, add_content_units, remove_content_units, base_version_pk=None):\n    \"\"\"\n    Create a new repository version by adding and then removing content units.\n\n    Args:\n        repository_pk (int): The primary key for a Repository for which a new Repository Version\n            should be created.\n        add_content_units (list): List of PKs for :class:`~pulpcore.app.models.Content` that\n            should be added to the previous Repository Version for this Repository.\n        remove_content_units (list): List of PKs for:class:`~pulpcore.app.models.Content` that\n            should be removed from the previous Repository Version for this Repository.\n        base_version_pk (int): the primary key for a RepositoryVersion whose content will be used\n            as the initial set of content for our new RepositoryVersion\n    \"\"\"\n    repository = models.Repository.objects.get(pk=repository_pk)\n\n    if base_version_pk:\n        base_version = models.RepositoryVersion.objects.get(pk=base_version_pk)\n    else:\n        base_version = None\n\n    if '*' in remove_content_units:\n        latest = models.RepositoryVersion.latest(repository)\n        if latest:\n            remove_content_units = latest.content.values_list('pk', flat=True)\n        else:\n            remove_content_units = []\n\n    with models.RepositoryVersion.create(repository, base_version=base_version) as new_version:\n        new_version.remove_content(models.Content.objects.filter(pk__in=remove_content_units))\n        new_version.add_content(models.Content.objects.filter(pk__in=add_content_units))\n", "path": "pulpcore/app/tasks/repository.py"}]}