Thanks to visit codestin.com
Credit goes to github.com

Skip to content

bpo-46436: Fix command-line option -d/--directory in module http.server #30701

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

Merged
merged 1 commit into from
Feb 3, 2022

Conversation

geryogam
Copy link
Contributor

@geryogam geryogam commented Jan 19, 2022

Fix command-line option -d/--directory in http.server main
function that was ignored when combined with --cgi.

https://bugs.python.org/issue46436

Automerge-Triggered-By: GH:merwok

Automerge-Triggered-By: GH:merwok

@geryogam geryogam changed the title Add alternative directory support (-d/--directory option) to http.server CLI for CGIHTTPRequestHandler Pass -d/--directory command-line option to http.server.CGIHTTPRequestHandler Jan 19, 2022
@geryogam geryogam changed the title Pass -d/--directory command-line option to http.server.CGIHTTPRequestHandler Pass the -d/--directory command-line option to http.server.CGIHTTPRequestHandler Jan 19, 2022
@geryogam geryogam changed the title Pass the -d/--directory command-line option to http.server.CGIHTTPRequestHandler bpo-46436: Pass the -d/--directory command-line option to http.server.CGIHTTPRequestHandler Jan 19, 2022
Copy link
Member

@JelleZijlstra JelleZijlstra left a comment

Choose a reason for hiding this comment

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

The substantive change looks good and I confirmed that it worked, but I agree that you should back out the unnecessary changes such as those in import order. They're not necessary to the fix.

Copy link
Member

@merwok merwok left a comment

Choose a reason for hiding this comment

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

Thanks! Do revert the import change then this can be merged

@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@geryogam
Copy link
Contributor Author

@merwok Done.

I have made the requested changes; please review again.

@bedevere-bot
Copy link

Thanks for making the requested changes!

@merwok: please review the changes made to this pull request.

@bedevere-bot bedevere-bot requested a review from merwok January 22, 2022 21:15
@merwok
Copy link
Member

merwok commented Jan 23, 2022

Please see https://bugs.python.org/issue46285

@geryogam
Copy link
Contributor Author

geryogam commented Jan 23, 2022

Thanks for mentioning this issue @merwok.

As you pointed out, function test in module http.server expects a real request handler class argument (SimpleHTTPRequestHandler or CGIHTTPRequestHandler), not a partial object partial(SimpleHTTPRequestHandler, directory=args.directory) or partial(CGIHTTPRequestHandler, directory=args.directory), so that the assignment of class attribute protocol_version in test is not ignored.

The partial object in the if __name__ == '__main__': branch of module http.server was introduced in the first place to pass the directory argument at request handler class instantiation in method BaseServer.finish_request of module socketserver:

def finish_request(self, request, client_address):
    """Finish one request by instantiating RequestHandlerClass."""
    self.RequestHandlerClass(request, client_address, self)

But method BaseServer.finish_request is a factory method of class BaseServer (the abstract creator) so it is designed to be overridden in subclasses to customize the instantiation of request handler subclasses of class BaseRequestHandler (the abstract product). So the proper way to instantiate subclasses SimpleHTTPRequestHandler and CGIHTTPRequestHandler with the directory argument is to override BaseServer.finish_request, not using a partial object.

I have just updated my PR to implement this. It fixes both #46285 and #46436. It also adds a command-line option -p/--protocol to module http.server and passes it to function test in the if __name__ == '__main__' branch (the protocol argument of test is now no longer ignored since we also pass a real request handler class instead of a partial object).

@geryogam geryogam changed the title bpo-46436: Pass the -d/--directory command-line option to http.server.CGIHTTPRequestHandler bpo-46436: Pass command-line option -d/--directory to CGIHTTPRequestHandler and add command-line option -p/--protocol in module http.server Jan 23, 2022
@geryogam geryogam changed the title bpo-46436: Pass command-line option -d/--directory to CGIHTTPRequestHandler and add command-line option -p/--protocol in module http.server bpo-46436: No longer ignore command-line option -d/--directory in module http.server when --cgi is used, and add -p/--protocol Jan 23, 2022
@merwok
Copy link
Member

merwok commented Jan 23, 2022

Thanks for fixing both issues! I’ll review the code to see if it also addresses my bad feeling about setting attributes directly on class objects.

Can we reference two tickets in one pull request title? Also have two blurb notes?

@merwok
Copy link
Member

merwok commented Jan 23, 2022

Nice trick with using a closure to keep finish_request’s signature compliant with the definition in socketserver.
On the other hand, I wonder if it wouldn’t be more straightforward to add a directory parameter to test.

test still sets attributes on the passed classes directly, which I find fishy, but it’s not the job of this PR to change that, and maybe it doesn’t need to be fixed at all (it’s a main function, not one that would be imported and called from regular code).

@geryogam
Copy link
Contributor Author

geryogam commented Jan 24, 2022

Nice trick with using a closure to keep finish_request’s signature compliant with the definition in socketserver. On the other hand, I wonder if it wouldn’t be more straightforward to add a directory parameter to test.

Yes that is another solution: moving the creation of partial objects with argument directory after the assignment of class attribute protocol_version in function test. The drawback of this approach is that, as you mentioned, it requires changing the signature of test (though it would be backward compatible and test is not part of the API of module http.server), and it requires such a change each time the signature of the __init__ method of a handler subclass changes (i.e. it couples test with __init__).

Factory methods (like finish_request) are a design pattern that avoids such information distribution.

@merwok
Copy link
Member

merwok commented Jan 24, 2022

I wasn’t suggesting to use partial objects, if that’s necessary then keeping your technique is better.
(Otherwise I don’t mind changing the signature of test, just like it was changed for protocol)

@geryogam
Copy link
Contributor Author

I wasn’t suggesting to use partial objects, if that’s necessary then keeping your technique is better.
(Otherwise I don’t mind changing the signature of test, just like it was changed for protocol)

Yes I think that is necessary. To instantiate a request handler with the directory argument from the method finish_request of a server, we have only two solutions:

  1. The partial object solution: pass a callable partial(RequestHandlerClass, directory=directory) to the server as the RequestHandlerClass argument (which becomes the self.RequestHandlerClass instance attribute) and let the server inherit the method finish_request of the class socketserver.BaseServer:
    def finish_request(self, request, client_address):
        """Finish one request by instantiating RequestHandlerClass."""
        self.RequestHandlerClass(request, client_address, self)
  1. The factory method solution: override the method finish_request of the class socketserver.BaseServer with the instantiation of the class RequestHandlerClass:
    def finish_request(self, request, client_address):
        RequestHandlerClass(request, client_address, self, directory=directory)

The designer of the class socketserver.BaseServer gave us the two possibilities. In the first solution, finish_request is a useless factory method. In the second solution, self.RequestHandlerClass is a useless instance attribute.

@orsenthil, do you a preference?

@geryogam geryogam changed the title bpo-46436: Fix ignored command-line option -d/--directory in module http.server when --cgi is used bpo-46436: Fix command-line option -d/--directory in module http.server Jan 30, 2022
@geryogam
Copy link
Contributor Author

geryogam commented Jan 31, 2022

Thanks for getting the PR ready to merge!
Can you confirm that you tested it locally?

Thanks for reviewing it @merwok! I cleaned up my history and tested the HTTP server locally with Curl for both PRs and I confirm that they both work. You can merge them.

@merwok
Copy link
Member

merwok commented Jan 31, 2022

Can you add your name to Misc/ACKS?

@geryogam
Copy link
Contributor Author

Can you add your name to Misc/ACKS?

@merwok It is already there actually.

@miss-islington
Copy link
Contributor

Sorry, I can't merge this PR. Reason: You're not authorized to push to this branch. Visit https://docs.github.com/articles/about-protected-branches/ for more information..

@merwok merwok self-assigned this Jan 31, 2022
@geryogam
Copy link
Contributor Author

geryogam commented Feb 3, 2022

@merwok Is there anything that I can do to let miss-islington merge?

@miss-islington miss-islington merged commit 2d08034 into python:main Feb 3, 2022
@miss-islington
Copy link
Contributor

Thanks @maggyero for the PR 🌮🎉.. I'm working now to backport this PR to: 3.9, 3.10.
🐍🍒⛏🤖

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Feb 3, 2022
…er (pythonGH-30701)

Fix command-line option -d/--directory in http.server main
function that was ignored when combined with --cgi.

Automerge-Triggered-By: GH:merwok
(cherry picked from commit 2d08034)

Co-authored-by: Géry Ogam <[email protected]>
@bedevere-bot
Copy link

GH-31102 is a backport of this pull request to the 3.10 branch.

@bedevere-bot bedevere-bot removed the needs backport to 3.10 only security fixes label Feb 3, 2022
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Feb 3, 2022
…er (pythonGH-30701)

Fix command-line option -d/--directory in http.server main
function that was ignored when combined with --cgi.

Automerge-Triggered-By: GH:merwok
(cherry picked from commit 2d08034)

Co-authored-by: Géry Ogam <[email protected]>
@bedevere-bot
Copy link

GH-31103 is a backport of this pull request to the 3.9 branch.

@bedevere-bot bedevere-bot removed the needs backport to 3.9 only security fixes label Feb 3, 2022
@merwok
Copy link
Member

merwok commented Feb 3, 2022

The main branch was locked temporarily, tests were always failing because of a missing indent in a new test.

@geryogam
Copy link
Contributor Author

geryogam commented Feb 3, 2022

@merwok Thanks a lot for your careful review! It really improved the quality of this PR.

I think we can now merge the other PR.

@geryogam geryogam deleted the patch-20 branch February 8, 2022 16:37
Mariatta pushed a commit that referenced this pull request Feb 14, 2022
…er (GH-30701)

Fix command-line option -d/--directory in http.server main
function that was ignored when combined with --cgi.

Automerge-Triggered-By: GH:merwok
(cherry picked from commit 2d08034)

Co-authored-by: Géry Ogam <[email protected]>

Co-authored-by: Géry Ogam <[email protected]>
Mariatta pushed a commit that referenced this pull request Feb 14, 2022
…er (GH-30701)

Fix command-line option -d/--directory in http.server main
function that was ignored when combined with --cgi.

Automerge-Triggered-By: GH:merwok
(cherry picked from commit 2d08034)

Co-authored-by: Géry Ogam <[email protected]>

Co-authored-by: Géry Ogam <[email protected]>
hello-adam pushed a commit to hello-adam/cpython that referenced this pull request Jun 2, 2022
…er (pythonGH-30701)

Fix command-line option -d/--directory in http.server main
function that was ignored when combined with --cgi.

Automerge-Triggered-By: GH:merwok
(cherry picked from commit 2d08034)

Co-authored-by: Géry Ogam <[email protected]>

Co-authored-by: Géry Ogam <[email protected]>
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.

7 participants