Roundup Tracker - Issues

Message8488

Author rouilj
Recipients rouilj
Date 2026-08-03.05:32:44
Message-id <1785735164.45.0.0143445486162.issue2551304@roundup-tracker.org>
In-reply-to
I wonder if there are enough users to make fixing this worthwhile.

Maybe it's time to deprecate xml-rpc endpoint since we have rest.

We need to send etag on display() and require if-match on set().

It looks like you have to subclass the transport. Some google AI gave me this to record
the headers and make them available. Note this will overwrite the headers on each call.
So threads will each need a unique instance of the class.

import xmlrpc.client

class HeaderCapturingTransport(xmlrpc.client.Transport):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # This will hold the response headers from the most recent request
        self.last_headers = None

    def single_request(self, host, handler, request_body, verbose=False):
        # 1. Establish the HTTP connection using standard internals
        connection = self.make_connection(host)
        try:
            if verbose:
                connection.set_debuglevel(1)

            # 2. Send request headers and content
            self.send_request(connection, handler, request_body, debug=verbose)
            self.send_content(connection, request_body)

            # 3. Intercept the HTTP response
            response = connection.getresponse()
            
            # 4. CAPTURE HEADERS: Parse and save them to the transport instance
            # response.headers is an http.client.HTTPMessage object
            self.last_headers = response.headers

            # 5. Handle the response payload normally using standard validation
            if response.status == 200:
                return self.parse_response(response)
            
            # Handle non-200 responses appropriately
            raise xmlrpc.client.ProtocolError(
                host + handler,
                response.status,
                response.reason,
                response.headers
            )
        finally:
            self.close()

# Initialize the custom transport
transport = HeaderCapturingTransport()

# Bind the transport to your ServerProxy
proxy = xmlrpc.client.ServerProxy('http://localhost:8000', transport=transport)

try:
    # Make your normal RPC call
    result = proxy.some_remote_function()
    print("RPC Result:", result)
    
    # Read the response headers captured during the call
    headers = transport.last_headers
    if headers:
        print("\n--- Response Headers ---")
        # Access a specific header safely (case-insensitive)
        print("Server Type:", headers.get("Server"))
        print("Content Type:", headers.get("Content-Type"))
        
        # Iterate over all headers
        for key, value in headers.items():
            print(f"{key}: {value}")

except xmlrpc.client.Error as err:
    print(f"XML-RPC Error: {err}")


Also update the xmlrpc docs. It still has some python2 constructs.
History
Date User Action Args
2026-08-03 05:32:44rouiljsetmessageid: <1785735164.45.0.0143445486162.issue2551304@roundup-tracker.org>
2026-08-03 05:32:44rouiljsetrecipients: + rouilj
2026-08-03 05:32:44rouiljlinkissue2551304 messages
2026-08-03 05:32:44rouiljcreate