Bug 451790

Summary: System Monitor Sensor breaks WeatherWidget-2 from the KDE store on KDE Framework 5.92
Product: [Applications] plasma-systemmonitor Reporter: blackadderkate
Component: generalAssignee: KSysGuard Developers <ksysguard-bugs>
Status: RESOLVED FIXED    
Severity: normal CC: ahiemstra, fkrueger, martin.schnitkemper, matthieu.malassis, mkyral, nate, plasma-bugs, tnifc
Priority: HI Keywords: regression
Version: 5.24.3   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed In: 5.95

Description blackadderkate 2022-03-22 11:27:36 UTC
I've had multiple bug reports stating that my weather widget no longer works on distributions that have been upgraded to KDE Frameworks 5.92, when they add the "System Monitor Widget".

Apparently these are the steps to reproduce the issue:

STEPS TO REPRODUCE
1. Get the "Weather Widget 2" from the official KDE Store (https://store.kde.org/p/998917).
2. Right click the taskbar and add the widget. There are by default already three locations configured, and you will see the weather data for "Leicester, UK" - downloaded using the "Met.No" website API. Weather data is downloaded and displayed.
3. Now place the "System monitor Sensor"-widget on the desktop; there is no need for further configuration, the simple presence is sufficient.
4. Logoff and back in again, and the Weather Widget no longer downloads data using the same Met.No API (indicated by a "-- N/A") although OWM locations still work.
5. Remove the "System monitor Sensor"-widget from desktop and Logoff and back in again. Connections to the Metno should work now again

OBSERVED RESULT
The widget displays "-- N/A" indicating no data has been downloaded.

EXPECTED RESULT
The widget displays the relevant weather icon and the current temperature for Leicester.

SOFTWARE/OS VERSIONS
Operating System: Arch Linux
KDE Plasma Version: 5.24.3
KDE Frameworks Version: 5.92.0
Qt Version: 5.15.3
Kernel Version: 5.16.15-arch1-1 (64-bit)
Graphics Platform: X11

ADDITIONAL INFORMATION

The bug report for my widget is here: https://github.com/blackadderkate/weather-widget-2/issues/89

I'm running Kubuntu 20.04 LTS so I'm unable to diagnose or fix the problem...
Comment 1 blackadderkate 2022-03-22 22:25:13 UTC
Apparently the System Monitor Widget is changing the default XMLRequest User Agent, and the Met.No API is rejecting it.

From my Github issues page: https://github.com/blackadderkate/weather-widget-2/issues/89#issuecomment-1075689558

Without System Monitor widget:

  'HTTP_USER_AGENT': 'Mozilla/5.0 (X11; Linux x86_64) KIO/5.92 '
                     'plasmashell/5.24.3',

With System Monitor widget:

  'HTTP_USER_AGENT': 'Mozilla/5.0',

I don't think I can code a workaround in my widget for this - Qt5 does not allow setting the User-Agent header in XmlHttpRequest.
See https://github.com/qt/qtdeclarative/blob/v5.13.2/src/qml/qml/qqmlxmlhttprequest.cpp#L1836
Comment 2 tnifc 2022-03-31 18:21:37 UTC
I tried to trace where the user agent is determined. In kio source code in kprotocolmanager.cpp, I see the user-agent can be configured by ~/.config/kio_httprc
I configured as so:
  $ cat ~/.config/kio_httprc
  SendUserAgent=true
  UserAgentKeys=:ovml

It does have effect on the kio user-agent. By running without a System Monitor widget, the user-agent is according to the modifiers defined in the config file.
    'HTTP_USER_AGENT': 'Mozilla/5.0 (X11; Linux '
                     '5.16.15-1-localmod-01004-gaedeba2797ad x86_64; English) '
                     'KIO/5.92 plasmawindowed/1.0',

The default UserAgentKeys is :om. A value of :ovml adds kernel version and language of my system as seen above.

When there is a System Monitor widget in the taskbar, the user-agent becomes:
  'HTTP_USER_AGENT': 'Mozilla/5.0',

I put some print lines in the defaultUserAgent() function in kprotocolmanager. When there's a System Monitor widget present the function is never called. There must be some other code path the determines the user-agent. I haven't been able find where that could be.
Comment 3 Martin Schnitkemper 2022-04-17 18:01:10 UTC
Problem still persist in the latest update of KDE Framework 5.93.0
Comment 4 Arjen Hiemstra 2022-04-28 14:20:22 UTC
Unfortunately, I have no idea how the applet ends up changing the user agent. The only thing I can think of is that we somehow end up pulling KNewStuff into the process and that ends up changing the user agent, but in that case I'd expect any "get new stuff" button to trigger it.
Comment 5 Arjen Hiemstra 2022-05-11 13:36:41 UTC
I did some digging around and I think https://invent.kde.org/frameworks/kdeclarative/-/commit/0943bbf5f625ef218605dc8aba69bf3274698d49 caused this.
Comment 6 Arjen Hiemstra 2022-05-13 12:50:31 UTC
Turns out it's not really a system monitor issue, but as mentioned the deletion of the NetworkAccessManagerFactory in KDeclarative. https://invent.kde.org/frameworks/kdeclarative/-/merge_requests/122 should fix it, it cleans up the shared engines and makes sure to only delete the QNAM factory when there's only one user of the engine left.
Comment 7 Martin Schnitkemper 2022-05-13 14:32:54 UTC
I rebuilt the package while applying the provided patches, and it seems that it works.

After I placed a widget (disk usage) on the desktop and signed off-/on, the connection of the weather widget to Met.No was still operational. 

To verify the behavior I reverted back to the package of the provider, and the connection was again broken.
Comment 8 Arjen Hiemstra 2022-05-17 09:26:25 UTC
Git commit fac27b49172fa3bbdfe3dbee0ceabe95b7c84b45 by Arjen Hiemstra.
Committed on 17/05/2022 at 09:20.
Pushed by ahiemstra into branch 'master'.

QmlObject: Use std::shared_ptr to properly track the lifetime of QQmlEngine

The engine passed to QmlObject is potentially shared, either because it
comes from QmlObjectSharedEngine or because the caller is already using
it. Since raw pointers do not provide any information about that,
deprecate the raw pointer constructors and replace them with a
constructor taking a std::shared_ptr.

This allows QmlObject to properly track if its the first user of the
QQmlEngine and if so, call KDeclarative::setupEngine on it. It also
allows it to know if it is the *last* user of the engine, and in that
case properly cleanup the QNAM factory, without affecting the shared
engine case.

M  +1    -1    src/kdeclarative/CMakeLists.txt
M  +33   -29   src/kdeclarative/qmlobject.cpp
M  +33   -0    src/kdeclarative/qmlobject.h
M  +8    -7    src/kdeclarative/qmlobjectsharedengine.cpp

https://invent.kde.org/frameworks/kdeclarative/commit/fac27b49172fa3bbdfe3dbee0ceabe95b7c84b45