Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent duplicate POST keys in requests #16732

Merged
merged 8 commits into from
Sep 18, 2024
Merged

Conversation

di
Copy link
Member

@di di commented Sep 17, 2024

Fixes https://python-software-foundation.sentry.io/share/issue/40756e6481274d3babdc620efac508a9/

Generally, duplicate POST keys in a request are an error for us. Rather than sanity-checking this everywhere we use request.POST, this PR adds a view deriver that returns an error if duplicate keys are present.

@di di requested a review from a team as a code owner September 17, 2024 21:05
@@ -487,6 +487,7 @@ def _sort_releases(request: Request, project: Project):
require_csrf=False,
require_methods=["POST"],
has_translations=True,
permit_duplicate_post_keys=True,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I'm aware, this is the only view where we actually depend on and permit duplicate keys.

@di di enabled auto-merge (squash) September 18, 2024 15:09
@di di merged commit a908ffd into pypi:main Sep 18, 2024
18 checks passed
@di di deleted the prevent-multiple-post-keys branch September 18, 2024 15:16
@sdb9696
Copy link

sdb9696 commented Sep 19, 2024

Hi there, I think this PR has somehow broken the twine --skip-existing feature.

When I'm publishing to testpypi and I know there's a file there already, I am getting the error message POST body may not contain duplicate keys from this PR instead of the error message twine expects : A file named "{0}" already exists for'.format(filename).

I can't say 100% that it's this PR but it's the message I'm now getting and I can publish successfully when I bump the project version.

N.B. I run a build and test publish after every push to master as per the Python Packaging user guide but only really care if the test publish succeeds just before a proper release. This now causes the CI to fail on the interim commits.

@MOmarMiraj
Copy link

Hi guys,

Also running into this error as I am trying to upload some packages on TestPyPi and no matter what I do (version bump, change name, new project, etc) its giving me this POST body may not contain duplicate keys. Was working yesterday but now its not working no matter what I do.

@di
Copy link
Member Author

di commented Sep 19, 2024

Thanks! Looking into this now.

@marcinn
Copy link

marcinn commented Sep 19, 2024

Same for me:

INFO     Response from https://upload.pypi.org/legacy/:                                                                                                                                                            
         400 Bad Request                                                                                                                                                                                           
INFO     <html>                                                                                                                                                                                                    
          <head>                                                                                                                                                                                                   
           <title>400 Bad Request</title>                                                                                                                                                                          
          </head>                                                                                                                                                                                                  
          <body>                                                                                                                                                                                                   
           <h1>400 Bad Request</h1>                                                                                                                                                                                
           The server could not comply with the request since it is either malformed or otherwise incorrect.<br/><br/>                                                                                             
         POST body may not contain duplicate keys                                                                                                                                                                  
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
          </body>                                                                                                                                                                                                  
         </html>                                                                                                                                                                                                   
ERROR    HTTPError: 400 Bad Request from https://upload.pypi.org/legacy/                                                                                                                                           
         Bad Request      

twine version 5.1.1 (importlib-metadata: 8.5.0, keyring: 25.4.0, pkginfo: 1.10.0, requests: 2.32.3, requests-toolbelt: 1.0.0, urllib3: 2.2.3)

command:
twine upload --verbose --skip-existing dist/*

@MOmarMiraj
Copy link

Hey so actually I figured out my reason which was an issue in my setup.py. This has been resolved for me now and I am confident that it actually didn't have to do with anything here but just had the same error.

Sorry for that!

@di
Copy link
Member Author

di commented Sep 19, 2024

@MOmarMiraj Can you give us some more detail about what the issue in your setup.py was?

@marcinn
Copy link

marcinn commented Sep 19, 2024

I have classifiers defined. This is a part of a dump of data_to_send var (in twine's repository.upload()):

    ('classifiers', 'Development Status :: 4 - Beta'),
    ('classifiers', 'Environment :: Web Environment'),
    ('classifiers', 'Framework :: Django'),
    ('classifiers', 'Framework :: Django :: 3.1'),
    ('classifiers', 'Framework :: Django :: 3.2'),
    ('classifiers', 'Framework :: Django :: 4.0'),
    ('classifiers', 'License :: OSI Approved :: ISC License (ISCL)'),
    ('classifiers', 'Operating System :: OS Independent'),
    ('classifiers', 'Programming Language :: Python'),
    ('classifiers', 'Programming Language :: Python :: 3.9'),
    ('classifiers', 'Programming Language :: Python :: 3.10'),
    ('classifiers', 'Programming Language :: Python :: 3.11'),
    ('classifiers', 'Topic :: Internet :: WWW/HTTP'),
    ('classifiers', 'Topic :: Software Development :: Libraries :: Python Modules'),
    ('classifiers', 'Intended Audience :: Developers'),

After removing classifiers the error disappeared (now pypi complains about not enabled 2FA)

@di
Copy link
Member Author

di commented Sep 19, 2024

I still can't reproduce this myself but I've merged #16755 which might help, can anyone reporting issues here retry and see if this is still happening?

@MOmarMiraj
Copy link

MOmarMiraj commented Sep 19, 2024

@MOmarMiraj Can you give us some more detail about what the issue in your setup.py was?

In my setup.py it was the following:

    classifiers = [
    "Programming Language :: Python :: 3.8",
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "License  :: MIT License"
    ],

The license was missing the OSI Approved section and I was getting that error. The error message should've been more clear but this is what fixed mines

@di
Copy link
Member Author

di commented Sep 19, 2024

We've identified the issue, #16759 will fix this once it's merged & deployed.

@sdb9696
Copy link

sdb9696 commented Sep 19, 2024

I still can't reproduce this myself but I've merged #16755 which might help, can anyone reporting issues here retry and see if this is still happening?

To reproduce just try uploading a file with the same name and different hash twice should do it.

@sdb9696
Copy link

sdb9696 commented Sep 19, 2024

Edited the reproduction steps above to specify using a different hash.

@sdb9696
Copy link

sdb9696 commented Sep 19, 2024

Just tested with the latest deployment, all fixed many thanks!

@marcinn
Copy link

marcinn commented Sep 19, 2024

Seems to be ok now, thanks

@suzukimain
Copy link

It worked. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants