Uploaded image for project: 'mod_python'
  1. mod_python
  2. MODPYTHON-144

Make apache._server/apace._interpreter part of public API.

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 3.3.1
    • Component/s: core
    • Labels:
      None

      Description

      Within the mod_python.apache module there exists two private variables called "_server" and "_interpreter". These are initialised when an interpreter is first created. The variables are set to be an instance of the mod_python "serverobject" and the name of the interpreter. In effect, these would be the same as are available to a request handler as "req.server" and "req.interpreter".

      The problem with those in the "req" object is that they are only available to the request handler. If these variables in the "mod_python.apache" module are made part of the public API, they would then be accessible by any code. Since "server.get_options()" now exists and "server.get_config()" works properly, making these public would allow code running at global scope when a module is being imported to consult the server level config and/or options to customise their runtime behavour.

      Thus, proposed that these variables be renamed to "apache.server" and "apache.interpreter".

        Activity

        Hide
        grahamd Graham Dumpleton added a comment -

        After doing some research, rather than being called "apache.server" should possibly be called "apache.main_server". This would reflect better that it refers to the main Apache server configuration. This is in contrast to "req.server" and "req.connection.base_server".

        Need to do some more research as to what really is the difference between these three ways of getting to the server object. All I understand so far is that "get_options()" and "get_config()" should return different stuff based on configuration in effect to that point.

        At the moment my belief is that "apache.main_server" would reflect config set outside of all configuration containers, "req.connection.base_server" will be the combination of that for the main server and the virtual host, and "req.server" will be the combination of that for the main server, virtual host and any containers traversed based on URL of the request.

        Show
        grahamd Graham Dumpleton added a comment - After doing some research, rather than being called "apache.server" should possibly be called "apache.main_server". This would reflect better that it refers to the main Apache server configuration. This is in contrast to "req.server" and "req.connection.base_server". Need to do some more research as to what really is the difference between these three ways of getting to the server object. All I understand so far is that "get_options()" and "get_config()" should return different stuff based on configuration in effect to that point. At the moment my belief is that "apache.main_server" would reflect config set outside of all configuration containers, "req.connection.base_server" will be the combination of that for the main server and the virtual host, and "req.server" will be the combination of that for the main server, virtual host and any containers traversed based on URL of the request.
        Hide
        grahamd Graham Dumpleton added a comment -

        Third time lucky. Understand this all a bit better now and have found a bug of sorts in mod_python as a result.

        req.connection.base_server.get_config()
        req.connection.base_server.get_options()

        These return config/options outside of all configuration containers.

        req.server.get_config()
        req.server.get_options()

        These return config/options for the virtual host overlayed on top of that in req.connection.base_server. If there is no virtual host container would be same as req.connection.base_server.

        req.get_config()
        req.get_options()

        These return config/options from containers specific to the URL for a request. That is, Location, Directory and Files containers. These overlay those from req.server and req.connection.base_server.

        Now, the server object being exposed in the "apache" module should be the same as available to a request handler through req.connection.base_server.

        Unfortunately, the server object currently stored as "apache._server" is not necessarily the same as req.connection.base_server. This is because it is set to the server object available at the time the interpreter was initialised. Depending on the situation, this might be either req.connection.base_server or req.server.

        The problem arises because in src/mod_python.c, the get_interpreter() function needs to be passed both the interpreter name and a server_rec object.

        interpreterdata *get_interpreter(const char *name, server_rec *srv)

        Originally the server_rec was used only for ensuring error messages were logged in the correct context, thus whether it equated to the base server or virtual host wasn't too important. When MODPYTHON-37 was implemented however, the server object was cached in the "apache" module. Again, for what it was being used, it didn't actually matter that which server object was being cached varied.

        In coming to make the server object available as a public attribute it does now matter. The server object must be that which equates to req.connection.base_server.

        First off therefore, it should be called "apache.base_server" to make the connection obvious.

        Secondly, src/mod_python.c should be modified so that the python_init() function caches a pointer to the base server server_rec structure in a global variable. Whenever get_interpreter() is called, this cached server_rec object should be supplied as the argument. Alternatively, the get_interpreter() function shouldn't even take the server_rec object as a second argument and instead should just get it from the global variable populated by the python_init() function.

        A bit of a review should also possibly be done about how about server_rec objects are used to direct where logging goes in the mod_python internals. It possibly should be consistent and all go through the base server, rather than randomly through either base server or virtual host server contexts.

        Show
        grahamd Graham Dumpleton added a comment - Third time lucky. Understand this all a bit better now and have found a bug of sorts in mod_python as a result. req.connection.base_server.get_config() req.connection.base_server.get_options() These return config/options outside of all configuration containers. req.server.get_config() req.server.get_options() These return config/options for the virtual host overlayed on top of that in req.connection.base_server. If there is no virtual host container would be same as req.connection.base_server. req.get_config() req.get_options() These return config/options from containers specific to the URL for a request. That is, Location, Directory and Files containers. These overlay those from req.server and req.connection.base_server. Now, the server object being exposed in the "apache" module should be the same as available to a request handler through req.connection.base_server. Unfortunately, the server object currently stored as "apache._server" is not necessarily the same as req.connection.base_server. This is because it is set to the server object available at the time the interpreter was initialised. Depending on the situation, this might be either req.connection.base_server or req.server. The problem arises because in src/mod_python.c, the get_interpreter() function needs to be passed both the interpreter name and a server_rec object. interpreterdata *get_interpreter(const char *name, server_rec *srv) Originally the server_rec was used only for ensuring error messages were logged in the correct context, thus whether it equated to the base server or virtual host wasn't too important. When MODPYTHON-37 was implemented however, the server object was cached in the "apache" module. Again, for what it was being used, it didn't actually matter that which server object was being cached varied. In coming to make the server object available as a public attribute it does now matter. The server object must be that which equates to req.connection.base_server. First off therefore, it should be called "apache.base_server" to make the connection obvious. Secondly, src/mod_python.c should be modified so that the python_init() function caches a pointer to the base server server_rec structure in a global variable. Whenever get_interpreter() is called, this cached server_rec object should be supplied as the argument. Alternatively, the get_interpreter() function shouldn't even take the server_rec object as a second argument and instead should just get it from the global variable populated by the python_init() function. A bit of a review should also possibly be done about how about server_rec objects are used to direct where logging goes in the mod_python internals. It possibly should be consistent and all go through the base server, rather than randomly through either base server or virtual host server contexts.
        Hide
        grahamd Graham Dumpleton added a comment -

        It is back to apache.main_server after all. This is because although get_options() returns same for req.connection.base_server and apache.main_server, other attributes are different. For example, server_hostname is an IP address for apache.main_server and the actual virtual host name for req.connection.base_server. Thus distinction is important.

        Show
        grahamd Graham Dumpleton added a comment - It is back to apache.main_server after all. This is because although get_options() returns same for req.connection.base_server and apache.main_server, other attributes are different. For example, server_hostname is an IP address for apache.main_server and the actual virtual host name for req.connection.base_server. Thus distinction is important.
        Hide
        grahamd Graham Dumpleton added a comment -

        Problem with apache.main_server not always being main server object fixed by having python_init() cache it in global variable and at point server object being supplied to apache.init(), that value being supplied instead of that passed down from calling functions. The issue of which server object should be used when logging messages left for another time.

        Show
        grahamd Graham Dumpleton added a comment - Problem with apache.main_server not always being main server object fixed by having python_init() cache it in global variable and at point server object being supplied to apache.init(), that value being supplied instead of that passed down from calling functions. The issue of which server object should be used when logging messages left for another time.

          People

          • Assignee:
            grahamd Graham Dumpleton
            Reporter:
            grahamd Graham Dumpleton
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development