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

update upgrade for Qt6 #1410

Merged
merged 1 commit into from
Feb 17, 2025
Merged

update upgrade for Qt6 #1410

merged 1 commit into from
Feb 17, 2025

Conversation

tsteven4
Copy link
Collaborator

  1. change upgrade url method to https. In the past this caused problems on windows (Download failed: TLS initialization failed. #580, use http for upgrade #587). However, with Qt6 we are shipping plugins for native TLS libraries (windows SChannel, macos Secure Transport) as well as OpenSSL. Qt will fall back on the native plugin if required.
  2. skip all the use count statistics if the user has disabled them, i.e. babelData_.reportStatistics_ is false.
  3. implement clazy QString allocation optimizations.
  4. delete redundant QDateTime constructor.
  5. use default initializers.
  6. delete obsolete manual redirection code.
  7. delete unused variable.

1. change upgrade url method to https.  In the past this caused
problems on windows (GPSBabel#580, GPSBabel#587).  However, with Qt6 we are shipping
plugins for native TLS libraries (windows SChannel, macos Secure Transport)
as well as OpenSSL.  Qt will fall back on the native plugin if
required.
2. skip all the use count statistics if the user has disabled
them, i.e. babelData_.reportStatistics_ is false.
3. implement clazy QString allocation optimizations.
4. delete redundant QDateTime constructor.
5. use default initializers.
6. delete obsolete manual redirection code.
7. delete unused variable.
@tsteven4 tsteven4 requested a review from robertlipe February 15, 2025 00:58
@tsteven4
Copy link
Collaborator Author

I did notice automatic redirection fails for
http://gpsbabel.org/upgrade_check.html
although
http://www.gpsbabel.org/upgrade_check.html
and
https://gpsbabel.org/upgrade_check.html
both work.
The manual redirection code didn't help.

@tsteven4
Copy link
Collaborator Author

Also in the response

  • the detailsURL attribute points to 1.7.0. I couldn't find any evidence that this attribute was ever used.
  • the overview element points to 1.8.0. This is used in the QMessageBox detailed text.

At least the version attribute is correct!

@tsteven4
Copy link
Collaborator Author

I have exercised this with "static const bool testing = true;" on Windows 11 and was offered the upgrade.

@tsteven4
Copy link
Collaborator Author

I have exercised this with "static const bool testing = true;" on macos 15.3.1 and was offered the upgrade. This also worked when I had deleted either the openssl plugin or the secure transport plugin. libopenssl was present in /usr/local/lib from homebrew.

if (babelData_.reportStatistics_) {
int j = 0;

for (int i = 0; i < formatList_.size(); i++) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

If you have any other reason to touch this, please consider:

for (const auto& entry : formatList_)
and them making the formatList[i] below into entry...and/or just moving rc and wc into the one place they seem to be used.

If you're tired of looking at this, that's OK, too.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks for your comments. I have lost count of the number of times I have started to modernize the loops in the GUI. I think I will defer this for a more global solution for the GUI.

@robertlipe
Copy link
Collaborator

I did notice automatic redirection fails for

That was/is special cased because had some versions in play that couldnt handle the redirect so it actually overrides the global (if not https, redirect) rewrite.

There's probably a generation of some combination of OS and version that's an island
of not getting updates. Maybe it goes back to that 1.4.x-era handling of redirects. At some point, we just decide that anything older than X quits getting handled and probably just let them all fall into the https path. There was a petty fragile dance of server and client-side handling for a while that I'm pretty sure is no longer in play.

@robertlipe
Copy link
Collaborator

Re: the prose being wrong now points to a new page that says we don't have release notes. At some point, I should just give up on the pretense of even offering those. The GitHub history is there for anyone that cares - and it seems that only you and I do. There is probably some overdesign in the XML that's returned vs. what's actually shown to the user. Back in 1.2 I thought about offering translated pages for example, but online and in-browser translation make that seem pretty silly.

That 'testing' path you found was exactly to provide an easy one-byte change to allow testing it. It was easier during development than editing registry keys in different ways on different OSes. I'm glad you found it useful ... and more glad that you've confirmed it's all working in modern times. I usually just spot-check my own desktop after an upgrade but don't run around the whole matrix.

@tsteven4
Copy link
Collaborator Author

I did notice automatic redirection fails for

That was/is special cased because had some versions in play that couldnt handle the redirect so it actually overrides the global (if not https, redirect) rewrite.

There's probably a generation of some combination of OS and version that's an island of not getting updates. Maybe it goes back to that 1.4.x-era handling of redirects. At some point, we just decide that anything older than X quits getting handled and probably just let them all fall into the https path. There was a petty fragile dance of server and client-side handling for a while that I'm pretty sure is no longer in play.

If the GUI (on linux) uses http://gpsbabel.org/upgrade_check.html it still fails. Note the scheme and the subdomain are both changed.

Download failed: Error transferring https://www.gpsbabel.org/upgrade_check.html - server replied: Request Timeout.

I note curl handles the 301 followed by a 307 without an issue. Qt bug? I'm not sure we care.

$ curl -d 'current_version=1.10.0&current_gui_version=1.10.0&installation={ffead5f2-cfc4-483c-aae0-b2200f593c89}&os=ubuntu&cpu=x86_64&os_ver=24.04&beta_ok=0&lang=C&last_checkin=2025-02-16T08:47:37&ugcb=63&ugdec=42&ugacc=0&ugoff=42&ugerr=21&rc=67' -L -v  http://gpsbabel.org/upgrade_check.html
* Host gpsbabel.org:80 was resolved.
* IPv6: (none)
* IPv4: 75.119.205.41
*   Trying 75.119.205.41:80...
* Connected to gpsbabel.org (75.119.205.41) port 80
> POST /upgrade_check.html HTTP/1.1
> Host: gpsbabel.org
> User-Agent: curl/8.5.0
> Accept: */*
> Content-Length: 234
> Content-Type: application/x-www-form-urlencoded
>
< HTTP/1.1 301 Moved Permanently
< Date: Sun, 16 Feb 2025 16:08:44 GMT
< Server: Apache
* Please rewind output before next send
< Location: http://www.gpsbabel.org/upgrade_check.html
< Content-Length: 250
< Content-Type: text/html; charset=iso-8859-1
<
* Ignoring the response-body
* Connection #0 to host gpsbabel.org left intact
* Issue another request to this URL: 'http://www.gpsbabel.org/upgrade_check.html'
* Switch from POST to GET
* Host www.gpsbabel.org:80 was resolved.
* IPv6: (none)
* IPv4: 75.119.205.41
*   Trying 75.119.205.41:80...
* Connected to www.gpsbabel.org (75.119.205.41) port 80
> GET /upgrade_check.html HTTP/1.1
> Host: www.gpsbabel.org
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 307 Temporary Redirect
< Date: Sun, 16 Feb 2025 16:08:44 GMT
< Server: Apache
< Location: https://www.gpsbabel.org/upgrade_check.html
< Cache-Control: max-age=600
< Expires: Sun, 16 Feb 2025 16:18:44 GMT
< Content-Length: 253
< Content-Type: text/html; charset=iso-8859-1
<
* Ignoring the response-body
* Connection #1 to host www.gpsbabel.org left intact
* Clear auth, redirects to port from 80 to 443
* Issue another request to this URL: 'https://www.gpsbabel.org/upgrade_check.html'
* Host www.gpsbabel.org:443 was resolved.
* IPv6: (none)
* IPv4: 75.119.205.41
*   Trying 75.119.205.41:443...
* Connected to www.gpsbabel.org (75.119.205.41) port 443
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519 / RSASSA-PSS
* ALPN: server accepted http/1.1
* Server certificate:
*  subject: CN=gpsbabel.org
*  start date: Jan 28 18:32:08 2025 GMT
*  expire date: Apr 28 18:32:07 2025 GMT
*  subjectAltName: host "www.gpsbabel.org" matched cert's "www.gpsbabel.org"
*  issuer: C=US; O=Let's Encrypt; CN=R11
*  SSL certificate verify ok.
*   Certificate level 0: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
*   Certificate level 1: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
*   Certificate level 2: Public key type RSA (4096/152 Bits/secBits), signed using sha256WithRSAEncryption
* using HTTP/1.x
> GET /upgrade_check.html HTTP/1.1
> Host: www.gpsbabel.org
> User-Agent: curl/8.5.0
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< HTTP/1.1 200 OK
< Date: Sun, 16 Feb 2025 16:08:45 GMT
< Server: Apache
< Vary: Accept-Encoding,User-Agent
< Transfer-Encoding: chunked
< Content-Type: text/xml;charset=UTF-8
<
<?xml version="1.0"?>
<updates>
<update version="1.10.0" type="major" detailsURL="http%3A%2F%2Fwww.gpsbabel.org%2Fnews%2Fgpsbabel-1.10.0.html" downloadURL="http://www.gpsbabel.org/download.html">
<overview>See http://www.gpsbabel.org/news/gpsbabel-1.10.0.html</overview>
</update>
* Connection #2 to host www.gpsbabel.org left intact
*

@tsteven4
Copy link
Collaborator Author

Re: the prose being wrong now points to a new page that says we don't have release notes.

Thanks. Even if there isn't much there it's nice to not refer to 1.7 and 1.8 anymore.

@tsteven4 tsteven4 merged commit 2e19e87 into GPSBabel:master Feb 17, 2025
21 checks passed
@tsteven4 tsteven4 deleted the upgrade6 branch February 17, 2025 21:35
@tsteven4
Copy link
Collaborator Author

regarding the 301,307 redirect failure after the 307 the GUI sends the following. Note that the content-type and content-length headers are present, yet the content is empty. This is with Qt 6.8.2 but I don't think that matters. wireshark has some trouble decoding this frame, it shows the protocol as TLSv1.3 instead of HTTP.
This is the decrypted TLS:

0000   47 45 54 20 2f 75 70 67 72 61 64 65 5f 63 68 65   GET /upgrade_che
0010   63 6b 2e 68 74 6d 6c 20 48 54 54 50 2f 31 2e 31   ck.html HTTP/1.1
0020   0d 0a 68 6f 73 74 3a 20 77 77 77 2e 67 70 73 62   ..host: www.gpsb
0030   61 62 65 6c 2e 6f 72 67 0d 0a 63 6f 6e 74 65 6e   abel.org..conten
0040   74 2d 74 79 70 65 3a 20 61 70 70 6c 69 63 61 74   t-type: applicat
0050   69 6f 6e 2f 78 2d 77 77 77 2d 66 6f 72 6d 2d 75   ion/x-www-form-u
0060   72 6c 65 6e 63 6f 64 65 64 0d 0a 61 63 63 65 70   rlencoded..accep
0070   74 2d 65 6e 63 6f 64 69 6e 67 3a 20 69 64 65 6e   t-encoding: iden
0080   74 69 74 79 0d 0a 63 6f 6e 74 65 6e 74 2d 6c 65   tity..content-le
0090   6e 67 74 68 3a 20 32 33 34 0d 0a 63 6f 6e 6e 65   ngth: 234..conne
00a0   63 74 69 6f 6e 3a 20 4b 65 65 70 2d 41 6c 69 76   ction: Keep-Aliv
00b0   65 0d 0a 61 63 63 65 70 74 2d 6c 61 6e 67 75 61   e..accept-langua
00c0   67 65 3a 20 65 6e 2c 2a 0d 0a 75 73 65 72 2d 61   ge: en,*..user-a
00d0   67 65 6e 74 3a 20 4d 6f 7a 69 6c 6c 61 2f 35 2e   gent: Mozilla/5.
00e0   30 0d 0a 0d 0a 

After the 301 the GUI sends a GET without the content* headers and an empty body. But after the 307 the content headers come back.

0000   bc 99 11 49 22 5a d0 37 45 c5 71 ae 08 00 45 00   ...I"Z.7E.q...E.
0010   00 c7 f7 bd 40 00 40 06 69 26 c0 a8 00 04 4b 77   ....@[email protected]&....Kw
0020   cd 29 b7 67 00 50 fd fb 8c 1a 19 21 a2 98 50 18   .).g.P.....!..P.
0030   01 f6 da 06 00 00 47 45 54 20 2f 75 70 67 72 61   ......GET /upgra
0040   64 65 5f 63 68 65 63 6b 2e 68 74 6d 6c 20 48 54   de_check.html HT
0050   54 50 2f 31 2e 31 0d 0a 68 6f 73 74 3a 20 77 77   TP/1.1..host: ww
0060   77 2e 67 70 73 62 61 62 65 6c 2e 6f 72 67 0d 0a   w.gpsbabel.org..
0070   61 63 63 65 70 74 2d 65 6e 63 6f 64 69 6e 67 3a   accept-encoding:
0080   20 69 64 65 6e 74 69 74 79 0d 0a 63 6f 6e 6e 65    identity..conne
0090   63 74 69 6f 6e 3a 20 4b 65 65 70 2d 41 6c 69 76   ction: Keep-Aliv
00a0   65 0d 0a 61 63 63 65 70 74 2d 6c 61 6e 67 75 61   e..accept-langua
00b0   67 65 3a 20 65 6e 2c 2a 0d 0a 75 73 65 72 2d 61   ge: en,*..user-a
00c0   67 65 6e 74 3a 20 4d 6f 7a 69 6c 6c 61 2f 35 2e   gent: Mozilla/5.
00d0   30 0d 0a 0d 0a 

I don't know that the content* headers cause the timeout, but curl works and it strips them from both redirect generated requests. I can imagine gpsbabel.org is waiting for the 234 bytes of content length.

@tsteven4
Copy link
Collaborator Author

The problem with the POST generating a 301, 307 redirect sequence is a regression between Qt 6.6.3 and 6.7.0. It seems to be due to qt/qtbase@0345f07#diff-1747ac73c8af554792736e60577b4c366e9b0408d5b82b8100f995b5aa6d329a

Specifically getOperationKeepsBody was introduced. In our case a POST with a body is followed by a 301 redirect, which is followed by a 307 redirect. The 301 redirect executes the code clearing the outgoingData and Content headers. It also changes operation to a GET. When the 307 redirect comes getOperationKeepsBody is true so we don't clear the Content Headers. Note that the redirectRequest is created each time from the originalRequest which is not overwritten by the redirects. Thus, the original headers from the POST are copied for the 307 redirect, but the body has been cleared. I assert that the 307 GET request should not have Content headers. With them a timeout eventually results.

    // If the original operation was a GET with a body and the status code is either
    // 307 or 308 then keep the message body
    const bool getOperationKeepsBody = (operation == QNetworkAccessManager::GetOperation)
                          && (httpStatus == 307 || httpStatus == 308);


    redirectRequest = createRedirectRequest(originalRequest, url, maxRedirectsRemaining);
    operation = getRedirectOperation(operation, httpStatus);


    // Clear stale headers, the relevant ones get set again later
    httpRequest.clearHeaders();
    if ((operation == QNetworkAccessManager::GetOperation
        || operation == QNetworkAccessManager::HeadOperation) && !getOperationKeepsBody) {
        // possibly changed from not-GET/HEAD to GET/HEAD, make sure to get rid of upload device
        uploadByteDevice.reset();
        uploadByteDevicePosition = 0;
        if (outgoingData) {
            QObject::disconnect(outgoingData, SIGNAL(readyRead()), q,
                                SLOT(_q_bufferOutgoingData()));
            QObject::disconnect(outgoingData, SIGNAL(readChannelFinished()), q,
                                SLOT(_q_bufferOutgoingDataFinished()));
        }
        outgoingData = nullptr;
        outgoingDataBuffer.reset();
        // We need to explicitly unset these headers so they're not reapplied to the httpRequest
        redirectRequest.setHeader(QNetworkRequest::ContentLengthHeader, QVariant());
        redirectRequest.setHeader(QNetworkRequest::ContentTypeHeader, QVariant());
    }

https://github.com/qt/qtbase/blob/0345f07dd11cb931e4c3625284bb1b408455fb32/src/network/access/qnetworkreplyhttpimpl.cpp#L1247-L1273

@tsteven4
Copy link
Collaborator Author

As I don't have an Qt account I emailed the author of the commit at qt.io. Hopefully they can address the issue.

@tsteven4
Copy link
Collaborator Author

Thanks @wpbrown for https://github.com/wpbrown/openssl-keylog. That was very helpful debugging this issue and played nicely with the Qt Network API (when it is backed by OpenSSL).

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.

2 participants