Skip to content

Safari (macOS 12, iOS 15) and compression is broken #1347

Closed

Description

All versions of uWS are totally incompatible with iOS 15 when using compression and will not keep a connection. This is because of an Apple bug where client_no_context_takeover is not properly implemented in newest Safari for iOS 15.

Because of this, if you use compression and expect iOS 15 connections, you will have to enable uWS::DEDICATED_DECOMPRESSOR as well.

See EchoServer.cpp example. uWS::DEDICATED_DECOMPRESSOR is available in v20.3.0 and forward. This adds about 44kb of memory usage per connection.

Activity

  1. ghost pinned this issue on Sep 28, 2021
  2. ghost closed this as completedon Oct 1, 2021
  3. ghost changed the title [-]iOS 15 and compression is broken[/-] [+]Safari (macOS 12, iOS 15) and compression is broken[/+] on Oct 30, 2021
  4. not-implemented commented on Nov 9, 2021

    @not-implemented
    Contributor

    Thanks for documenting this ... we ran into the same issue :-(

    It really sucks ... as using DEDICATED_DECOMPRESSOR is not an option for us because of the massive RAM usage for ten thousands of connections ...

    Would be nice if you can keep us up2date if there are news on the apple issue.

  5. not-implemented commented on Jan 4, 2022

    @not-implemented
    Contributor

    Still no news from Apple here, right? That's really annoying ;-)

  6. ewak commented on Jan 11, 2022

    @ewak

    Here is what I think is the relevant issue in the webKit bugzilla

    REGRESSION (iOS 15): Websocket connection instance in javascript client getting closed
    https://bugs.webkit.org/show_bug.cgi?id=228296#c37

    And a comment that gives ?hope? of an apple response.

    Alex Christensen 2021-12-16 19:59:07 PST
    Alberto, thank you for the excellent go program to reliably reproduce an issue with multiple fragments and the extension combination of extensions "permessage-deflate; server_no_context_takeover; client_no_context_takeover". I found what I believe was a misplaced call to zlib's inflateReset in a non-WebKit framework and am working to fix it internally, tracked by rdar://85078119

    Here is the link to the gist of the "go program" mentioned above - https://gist.github.com/afcapel/4e1012bd658f6818e70115178edd3489

    And also relevant issues logged against the go gorilla/websocket implementation, further confirming that its a client issue.
    gorilla/websocket#731
    gorilla/websocket#696

    The fix if there is one, to the "misplaced call to zlib's inflateReset", has not yet turned up in my installation of a beta release of IOS 15.3(19D5026g)

  7. ewak commented on Jan 13, 2022

    @ewak

    This pull request #1399 contains an example, CompressionIOS15, if I have done it correctly, that shows that the use of the compression option DEDICATED_DECOMPRESSOR | DEDICATED_COMPRESSOR is not enough for a stable connection to an IOS 15.3(19D5026g) Iphone.

    In my investigations I instrumented the calls to forceClose() in WebSocketProtocol.h:consumeMessage() as below.

    CompressionIOS15, serves some simple html and javascript at test1.html that reproducibly results in the server aborting the connection, calling forceClose(), finding "wState->state.opStack == -1". I haven't figured out the meaning of opStack yet. That is hampering my progress bit level decoding of what is going on at the moment.

    It is flaky. Sometimes giving up immediately, other times it may take various combinations of messages.

    I watch the phones Safari console using a connected Desktop Safari Develop Web Inspector.

    Big initial messages seem to trigger a forceClose more readily.

    Sending multiple messages, "quickly", also seems to be a trigger.

    I cannot trigger the issue with Deskop Safari Technology Preview Release 137 (Safari 15.4, WebKit 16613.1.11.8) on Big Sur.

    diff --git a/src/WebSocketProtocol.h b/src/WebSocketProtocol.h
    index 4c5d8e9..ab603fa 100644
    --- a/src/WebSocketProtocol.h
    +++ b/src/WebSocketProtocol.h
    @@ -308,17 +308,20 @@ protected:
         static inline bool consumeMessage(T payLength, char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
             if (getOpCode(src)) {
                 if (wState->state.opStack == 1 || (!wState->state.lastFin && getOpCode(src) < 2)) {
    +                std::cerr << "forceClose: consumeMessage wState->state.opStack == 1 || (!wState->state.lastFin && getOpCode(src) < 2))" << std::endl;
                     Impl::forceClose(wState, user);
                     return true;
                 }
                 wState->state.opCode[++wState->state.opStack] = (OpCode) getOpCode(src);
             } else if (wState->state.opStack == -1) {
    +            std::cerr << "forceClose: consumeMessage wState->state.opStack == -1" << std::endl; //ALWAYS HANGS UP HERE
                 Impl::forceClose(wState, user);
                 return true;
             }
             wState->state.lastFin = isFin(src);
    
             if (Impl::refusePayloadLength(payLength, wState, user)) {
    +            std::cerr << "forceClose: consumeMessage Impl::refusePayloadLength(payLength, wState, user)" << std::endl;
                 Impl::forceClose(wState, user, ERR_TOO_BIG_MESSAGE);
                 return true;
             }
    @@ -417,6 +420,7 @@ public:
                     // invalid reserved bits / invalid opcodes / invalid control frames / set compressed frame
                     if ((rsv1(src) && !Impl::setCompressed(wState, user)) || rsv23(src) || (getOpCode(src) > 2 && getOpCode(src) < 8) ||
                         getOpCode(src) > 10 || (getOpCode(src) > 2 && (!isFin(src) || payloadLength(src) > 125))) {
    +                    std::cerr << "consume forceClose (rsv1(src) && !Impl::setCompressed(wState, user)) || rsv23(src) || (getOpCode(src) > 2 && getOpCode(src) < 8) || getOpCode(src) > 10 || (getOpCode(src) > 2 && (!isFin(src) || payloadLength(src) > 125))" << std::endl;
                         Impl::forceClose(wState, user);
                         return;
                     }
    
  8. 10 remaining items

  9. ghost unpinned this issue on Jan 29, 2022
  10. not-implemented commented on Jan 29, 2022

    @not-implemented
    Contributor

    Great! Thanks :-)

  11. ewak commented on Feb 2, 2022

    @ewak

    Hi All,

    Good news... maybe.

    Looks to me using the IOS15Compression tests #1399 that the current release of IOS 15.4(19E5209h) public beta, installed on my IPhone, now has working compression.

    Note: I have of course NOT incorporated the user agent hasBrokenCompression function above into my tests.

    It works(tm) for me, for both shared and dedicated compression as shown below.

    Shared compression

    compressionFlavour = uWS::CompressOptions(uWS::SHARED_COMPRESSOR | uWS::SHARED_DECOMPRESSOR);

    Request
    Origin: https://-----------------
    Pragma: no-cache
    Sec-WebSocket-Protocol: blah
    Sec-WebSocket-Key: blah==
    Sec-WebSocket-Version: 13
    Upgrade: websocket
    Sec-WebSocket-Extensions: permessage-deflate
    User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 15_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1
    Cache-Control: no-cache
    Connection: Upgrade
    
    Response
    Sec-WebSocket-Protocol: ----
    Upgrade: websocket
    Date: Wed, 02 Feb 2022 00:16:33 GMT
    Sec-WebSocket-Accept: blah=
    Sec-WebSocket-Extensions: permessage-deflate; client_no_context_takeover; server_no_context_takeover
    Connection: upgrade
    Server: nginx/1.20.1
    uWebSockets: 20
    

    Dedicated Compression

    compressionFlavour = uWS::CompressOptions(uWS::DEDICATED_COMPRESSOR | uWS::DEDICATED_DECOMPRESSOR);

    Request
    Origin: https://-----------
    Pragma: no-cache
    Sec-WebSocket-Protocol: --------
    Sec-WebSocket-Key: blah==
    Sec-WebSocket-Version: 13
    Upgrade: websocket
    Sec-WebSocket-Extensions: permessage-deflate
    User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 15_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1
    Cache-Control: no-cache
    Connection: Upgrade
    
    Response
    Sec-WebSocket-Protocol: ----
    Upgrade: websocket
    Date: Wed, 02 Feb 2022 00:24:16 GMT
    Sec-WebSocket-Accept: blah=
    Sec-WebSocket-Extensions: permessage-deflate
    Connection: upgrade
    Server: nginx/1.20.1
    uWebSockets: 20
    
  12. not-implemented commented on Feb 2, 2022

    @not-implemented
    Contributor

    Oh ... sounds good! So we can hopefully change the version-check to target just "Safari 15.0-15.3"

  13. not-implemented commented on Feb 2, 2022

    @not-implemented
    Contributor

    I created a pull request, that can be merged, when we are 100% sure, that Safari 15.4 is fixed:

    #1414

    This is the updated version of hasBrokenCompression():

    // ua-test.cpp
    // g++ -std=c++17 -o ua-test ua-test.cpp && ./ua-test
    
    #include <string_view>
    #include <charconv>
    
    // just for testing:
    #include <string>
    #include <vector>
    #include <iostream>
    #include <chrono>
    
    /* Safari 15.0 - 15.3 has a completely broken compression implementation (client_no_context_takeover not
     * properly implemented) - so we fully disable compression for this browser :-(
     * see https://github.com/uNetworking/uWebSockets/issues/1347 */
    bool hasBrokenCompression(std::string_view userAgent) {
        size_t posStart = userAgent.find(" Version/15.");
        if (posStart == std::string_view::npos) return false;
        posStart += 12;
    
        size_t posEnd = userAgent.find(' ', posStart);
        if (posEnd == std::string_view::npos) return false;
    
        unsigned int minorVersion = 0;
        auto result = std::from_chars(userAgent.data() + posStart, userAgent.data() + posEnd, minorVersion);
        if (result.ec != std::errc()) return false;
        if (result.ptr != userAgent.data() + posEnd) return false; // do not accept trailing chars
        if (minorVersion > 3) return false; // we target just Safari 15.0 - 15.3
    
        if (userAgent.find(" Safari/", posEnd) == std::string_view::npos) return false;
    
        return true;
    }
    
    int main() {
        std::vector<std::string> testUserAgents = {
            // Firefox 96.0:
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:96.0) Gecko/20100101 Firefox/96.0",
    
            // Firefox Mobile 96.0:
            "Mozilla/5.0 (Android 12; Mobile; rv:96.0) Gecko/96.0 Firefox/96.0",
    
            // Chrome 96.0.4664:
            "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36",
    
            // Chrome Mobile 97.0.4692:
            "Mozilla/5.0 (Linux; Android 11; SM-A405FN) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.87 Mobile Safari/537.36",
    
            // Edge 97.0.1072:
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36 Edg/97.0.1072.69",
    
            // Safari 14.1.2 (not affected):
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15",
    
            // Safari 15.0 (BROKEN!):
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15",
    
            // Safari 15.2 (BROKEN!):
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15",
    
            // Safari 15.3 (BROKEN!):
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.3 Safari/605.1.15",
    
            // "Safari 15.4" (hopefully fixed):
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Safari/605.1.15",
    
            // "Safari 16.0" (hopefully fixed):
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15",
    
            // Mobile Safari 13.4 (not affected):
            "Mozilla/5.0 (iPhone; CPU iPhone OS 13_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.4 Mobile/15E148 Safari/605.1.15",
    
            // Mobile Safari 13.4 with DuckDuckGo (not affected):
            "Mozilla/5.0 (iPhone; CPU iPhone OS 13_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.4 Mobile/15E148 DuckDuckGo/7 Safari/605.1.15",
    
            // Mobile Safari 15.0 (BROKEN!):
            "Mozilla/5.0 (iPhone; CPU iPhone OS 15_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1",
    
            // Mobile Safari 15.1 (BROKEN!):
            "Mozilla/5.0 (iPhone; CPU iPhone OS 15_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Mobile/15E148 Safari/604.1",
    
            // Mobile Safari 15.1 with DuckDuckGo (BROKEN!):
            "Mozilla/5.0 (iPhone; CPU iPhone OS 15_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Mobile/15E148 DuckDuckGo/7 Safari/604.1",
    
            // Mobile Safari 15.3 (BROKEN!):
            "Mozilla/5.0 (iPhone; CPU iPhone OS 15_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.3 Mobile/15E148 Safari/604.1",
    
            // "Mobile Safari 15.4" (hopefully fixed):
            "Mozilla/5.0 (iPhone; CPU iPhone OS 15_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1",
    
            // "Mobile Safari 16.0" (hopefully fixed):
            "Mozilla/5.0 (iPhone; CPU iPhone OS 15_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1",
    
            // Samsung Internet 16.0 (Chromium based):
            "Mozilla/5.0 (Linux; Android 8.0.0; SAMSUNG SM-A320FL) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/16.0 Chrome/92.0.4515.166 Mobile Safari/537.36",
    
            // Yandex Browser 22.1.0 (Blink based):
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 YaBrowser/22.1.0.2500 Yowser/2.5 Safari/537.36",
    
            // parser crash tests:
            "",
            " Version/15.",
            " Version/15. ",
            " Version/15.XX",
            " Version/15.XX ",
            " Version/15.0 ",
            " Version/15. Safari/",
            " Version/15.XX Safari/",
            " Version/15.0 Safari/",
            " Version/15.3 Safari/",
            " Version/15.4 Safari/",
            " Version/15.3X Safari/",
            " Version/15.0x3 Safari/",
            " Version/15.-1 Safari/",
            " Version/15.99999999999999999999 Safari/",
        };
    
        for (auto testUserAgent : testUserAgents) {
            std::cout << testUserAgent << " --- " << (hasBrokenCompression(testUserAgent) ? "BROKEN!" : "Fine") << std::endl;
        }
    
        // Benchmark:
        std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
        const int count = 100000;
    
        for (int i = 0; i < count; i++) {
            for (auto testUserAgent : testUserAgents) {
                hasBrokenCompression(testUserAgent);
            }
        }
    
        std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
        std::cout << "Time for " << count * testUserAgents.size() << " iterations: " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms" << std::endl;
    }

    Output:

    Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:96.0) Gecko/20100101 Firefox/96.0 --- Fine
    Mozilla/5.0 (Android 12; Mobile; rv:96.0) Gecko/96.0 Firefox/96.0 --- Fine
    Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 --- Fine
    Mozilla/5.0 (Linux; Android 11; SM-A405FN) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.87 Mobile Safari/537.36 --- Fine
    Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36 Edg/97.0.1072.69 --- Fine
    Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15 --- Fine
    Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15 --- BROKEN!
    Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15 --- BROKEN!
    Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.3 Safari/605.1.15 --- BROKEN!
    Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Safari/605.1.15 --- Fine
    Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15 --- Fine
    Mozilla/5.0 (iPhone; CPU iPhone OS 13_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.4 Mobile/15E148 Safari/605.1.15 --- Fine
    Mozilla/5.0 (iPhone; CPU iPhone OS 13_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.4 Mobile/15E148 DuckDuckGo/7 Safari/605.1.15 --- Fine
    Mozilla/5.0 (iPhone; CPU iPhone OS 15_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1 --- BROKEN!
    Mozilla/5.0 (iPhone; CPU iPhone OS 15_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Mobile/15E148 Safari/604.1 --- BROKEN!
    Mozilla/5.0 (iPhone; CPU iPhone OS 15_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Mobile/15E148 DuckDuckGo/7 Safari/604.1 --- BROKEN!
    Mozilla/5.0 (iPhone; CPU iPhone OS 15_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.3 Mobile/15E148 Safari/604.1 --- BROKEN!
    Mozilla/5.0 (iPhone; CPU iPhone OS 15_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1 --- Fine
    Mozilla/5.0 (iPhone; CPU iPhone OS 15_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1 --- Fine
    Mozilla/5.0 (Linux; Android 8.0.0; SAMSUNG SM-A320FL) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/16.0 Chrome/92.0.4515.166 Mobile Safari/537.36 --- Fine
    Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 YaBrowser/22.1.0.2500 Yowser/2.5 Safari/537.36 --- Fine
     --- Fine
     Version/15. --- Fine
     Version/15.  --- Fine
     Version/15.XX --- Fine
     Version/15.XX  --- Fine
     Version/15.0  --- Fine
     Version/15. Safari/ --- Fine
     Version/15.XX Safari/ --- Fine
     Version/15.0 Safari/ --- BROKEN!
     Version/15.3 Safari/ --- BROKEN!
     Version/15.4 Safari/ --- Fine
     Version/15.3X Safari/ --- Fine
     Version/15.0x3 Safari/ --- Fine
     Version/15.-1 Safari/ --- Fine
     Version/15.99999999999999999999 Safari/ --- Fine
    Time for 3600000 iterations: 2057ms
    
  14. ghost added a commit that references this issue on Feb 14, 2022
  15. ewak commented on Mar 17, 2022

    @ewak

    Hi Alex,

    I saw your message re macos 12.3.

    Its on my list to risk "destroying" one of my machines with yet another fresh os upgrade to macOS 12.3
    I have not done so yet.

    I can confirm that the official IOS 15.4 is working for my tests.

  16. gaby23s commented on Mar 17, 2022

    @gaby23s

    Hi,

    I still have the issue with an iPhone 8 and iOS 15.4 !

    When I return after safari has been in the background for a while, the websocket is closed.

  17. not-implemented commented on Mar 17, 2022

    @not-implemented
    Contributor

    @gaby23s are you sure, you are testing this very specific issue with Safari compression? This issue has nothing to do with putting Safari into the background ... in this scenario, Safari disconnects immediately after connect.

  18. gaby23s commented on Mar 18, 2022

    @gaby23s
  19. ewak commented on Mar 18, 2022

    @ewak

    @gaby23s We have also experienced MANY problems dealing with network re-connection after application sleep.

    We fight it with a patched version of https://github.com/pladaria/reconnecting-websocket v4.2.0. (Here is our patched version - https://github.com/ewak/reconnecting-websocket/tree/feature/ewak/improvements) which I need to PR.

    We use react, setup the websocket to start closed and attach an onerror() function. In the App componentDidMount() we reattach the onmessage(), onopen(), onclose() first and THEN call reconnect(). With IOS 15.4 this has again been working fine for us.

    We also use React Native WebView(effectively safari) and have had many attempts to try to use native network information to know when it is worth attempting to reconnect, none of that got us anywhere reliably, and I suspect that privacy/anit-tracking improvements in IOS further limit the effectiveness of that.

    Full disclosure - Be sure that you are really reconnecting to the correct place!!!
    We had a long time nasty race condition due the accidental use of default connection parameters. We were failing to "await" the download and use runtime of configuration of the websocket connection details. Depending on the users phone, state of their browser cache, network latency the reconnection would race between the default configuration connecting to development servers(firewalled) rather than the runtime downloaded configuration environment(test, qa, prod).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions