The latest posts in full-text for feed readers.
Recently I had the need to hide elements on some web page, but only if they contain a certain other element: Hide all list items that have a div with class="premium".
I use Firefox with uBlock origin for advertisement blocking. Beside ad blocking, it also helps to keep sanity on the web by hiding unnecessary elements like the "hot network questions" list on Stack Overflow.
The normal filter rules used by uBlock are CSS selectors, which do not allow selecting elements based on child tags.
Fortunately, uBlock supports XPath filters which specifically have this feature. The resulting filter rule was easy to write:
##:xpath(//li[.//div[contains(@class,"premium")]])
I use this to filter "heise plus" articles on the main heise.de page, since I do not have a login there and do not need teasers:
##:xpath(//article[.//span[contains(@class,"a-article-meta__item--heiseplus")]])
The usage of Tailwind CSS makes it harder to block elements since we do not have meaningful class names anymore. Instead I have to rely on hard-coded element attributes.
##svg:xpath(.[@width=78 and @height=24]):upward(article)
The owner of e-reader-forum.de put ads into their forum that look like normal posts. The first response to a new thread is
Hello $originalPosterName,
have a look here:
$originalThreadTitle
for example at thread Eigene Apps installieren (Firmware 14.2.0) it says (in German):
Hallo AaronDewes,
schau mal hier:
Eigene Apps installieren (Firmware 14.2.0).
The only way to know it's an ad is that the user name is "Anzeige", which is german for "Advertisement".
This is one of the most annoying ads I've seen in a long time, so I had to add a ublock rule that removes the posts that have "Anzeige" as username:
##:xpath(//article[contains(@class,"message--post") and .//span[contains(@class,"username") and text() = "Anzeige"]])
Published on 2019-02-10 in extensions, web
I don't use Twitter very often and only check the website every couple of days. When I open a new tab, type twitter.com and press "enter", the website loads.
When I have a notification, the red circle badge on top of the "Notifications" menu entry appears for a fraction of a second and then disappears. It takes 28 seconds after the page has been loaded for it to re-appear.
When I click the notifications menu entry they are immediately visible and do not disappear.
I suspect this is done deliberately by Twitter to prevent people from closing the twitter tab in their browser. (nudging, dark pattern)
Published on 2022-03-30 in kundeistkönig, web
My laptop's name is boo, and all the web projects I'm developing on my laptop have a domain name $project.boo. Today I wanted to open http://archive.boo/ in Firefox and got an error message:
Kein Verbindungsversuch unternommen: Mögliches Sicherheitsproblem
Firefox hat ein mögliches Sicherheitsrisiko erkannt und daher archive.boo
nicht aufgerufen, denn die Website benötigt eine verschlüsselte Verbindung.
archive.boo verwendet eine Sicherheitstechnologie namens
"HTTP Strict Transport Security (HSTS)",
durch welche Firefox nur über gesicherte Verbindungen mit der Website
verbinden darf.
Daher kann keine Ausnahme für die Website hinzugefügt werden.
My local Apache web server does not server any HSTS headers, and tracing the HTTP request in Wireshark shows me that no HTTP request is made at all. Only a HTTPS request.
It turns out that the .boo top level domain (TLD) is owned by Google and that it is on the HSTS preload list for both Firefox and Chromium.
Game over. I could try to disable HSTS in the browser (which I won't do), or I move to a new development TLD (that is specific to my machine, so I can share links in my network).
Published on 2022-02-17 in http, web
Recently in a docker container I got the following error message:
cURL error (77) error setting certificate verify locations: CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs for https://example.org
The solution was to install the ca-certificates via apt.
Published on 2020-11-21 in linux, web
Recently at work I had to analyze a problem in a Laravel application that I was not familiar with. The problem: When calling a specific URL, it wrongly redirected to another URL.
The route that I expected to be called was not, and routes/web.php was huge; too large to find the matching route quickly.
The solution was to adjust public/index.php and add the following line before the response was sent back to the browser:
$response->header('X-Route', Route::currentRouteName());
$response->send();
Now I could look at the redirect's HTTP headers to find the route that had been used:
$ curl -I http://app.example.org/en/explanatory-videos/test-510/
HTTP/1.1 302 Found
Date: Wed, 16 Sep 2020 11:45:26 GMT
Server: nginx/1.10.3 (Ubuntu)
Content-Type: text/html; charset=UTF-8
Cache-Control: no-cache, private
Location: http://app.example.org/en/products
X-Route: en_product_detail
Published on 2020-09-20 in php, web
The
James Bond
movies are based on novels written by
Ian Fleming,
and I discovered that all of his works entered the public domain in 2015.
While book retailers want 9€ per book (which themselves are not that long), the Internet Archive provides The Complete Ian Fleming as .epub file for download onto your e-book reader, for free.
I'm already the enjoying the first novel on my e-reader.
Published on 2019-09-10 in books, web
Letztens musste ich mich beim Onlineshopping zwischen Amazon Pay und PayPal entscheiden. Die Wahl fiel auf Amazon.
Leider bekam ich dann im Bezahl-Popup eine Fehlermeldung angezeigt:
Ihre Browser-Einstellungen blockieren Amazon Pay. Um Amazon Pay weiterhin zu nutzen, deaktivieren Sie diese Blockierung in den Browser-Einstellungen. Probieren Sie alternativ einen anderen Browser aus.
Der Werbeblocker (uBlock origin) war es nicht, ich musste tiefer gehen, bis in die Browsereinstellungen von Firefox:
Firefox > Einstellungen > Datenschutz und Datensicherheit > Seitenelemente blockieren > Standard
Vorher hatte ich "Benutzerdefiniert", und das ging nicht.
Published on 2019-08-06 in web
Because some Wikipedian did revert my commit, here it is again:
A reverse DNS entry is controlled by the company that owns a particular IP address. A server administrator would need to contact the hosting company that provides the server and IP address to get the reverse DNS entry changed.
IANA, the owner of the .arpa top level domain, delegates parts of the in-addr.arpa and ip6.arpa to the Regional Internet registries, which in turn delegate to hosting companies and ISPs.
Published on 2019-05-15 in web
I tried to setup a new site with Grav CMS 1.5.10 and ran into permission problems after unpacking one of the skeleton .zip files. The reason is that on my Linux machine I am running as user+group "cweiske", while Apache is running under "www-data" - and Grav wants to write some files even when it tries to reach the setup check screen.
Grav has a manual page about permissions which is complete nonsense if you want a secure system, and only give the web server process as few writable files and directories as possible. The manual page instructs you to change the permissions and group of every file and directory, which is unneeded.
Error messages I encountered before the setup check page worked:
Fatal error: Uncaught RuntimeException: Creating directory '/.../cache/compiled/files' failed on error
This is simple:
$ chgrp -R www-data cache
$ chmod -R g+w cache/
But now:
Fatal error: Uncaught RuntimeException: Opening file for writing failed on error
No more information. And what's worse: No stack trace, because Grav catches the Exception and throws it again.
The solution is to edit vendor/rockettheme/toolbox/File/src/File.php and let it output the file it tried to write:
- throw new \RuntimeException("Opening file for writing failed on error {$error['message']}");
+ throw new \RuntimeException("Opening file for writing failed on error {$error['message']}" . $this->filename);
We now see that it wants to write into user/config/security.yaml.
$ chgrp -R www-data user/config/
$ chmod -R g+w user/config/
And now I saw the setup check page.
In the end I had to give this permissions:
$ chgrp -R www-data assets/ backup/ cache/ images/ logs/ system/config/ tmp/ user/accounts/ user/config/ user/data/ user/pages/
$ chmod -R g+w assets/ backup/ cache/ images/ logs/ system/config/ tmp/ user/accounts/ user/config/ user/data/ user/pages/
I'm also disappointed that Grav puts all files publicly available into the server's document root directory, because it does not have a public/ or www/ directory. The issue was closed without a proper solution; Grav's authors chose to patch their .htaccess file instead :/
Published on 2019-04-04 in php, web
Two years after its last release, I finally found the time - and a reason - to rewrite the playVideoOnDreambox browser extension, making it compatible with newer Firefox versions.
The extension adds a button to Firefox that sends the currently playing video to the Dreambox satellite receiver - useful for showing a Youtube video to the family on the large TV screen.
Dreambox' media player does not support playing websites, so the extension needs to extract the URL of the video embedded on the current page. I did not implement this myself, but rely on youtube-dl for this.
Mozilla dropped support for "classic" extensions in Firefox 57; you have to use the "web extension" format now that severely restricts the things you can do. The main problem for me is that extensions cannot execute other programs on the computer anymore (unless the are registered manually with the browser and speak a certain protocol). This broke the my old extension that called youtube-dl directly.
I could have written a youtube-dl proxy script that users would need to register in their browser and that speaks said protocol. But instead I made the Firefox extension rely on the playVideoOnDreambox proxy application, just as the Android app does.
So when your browser shows some video and you click "Play on Dreambox", the extension sends the page URL to the proxy server web app running on some machine in your network. This proxy calls youtube-dl to find the video URL, and then instructs the Dreambox to play the video.
You can download the playVideoOnDreambox firefox extension version 0.6.0 from its homepage or the Mozilla Add-Ons page.
You migh be interested in the playVideoOnDreambox Android app that lets you "share" the video with your satellite receiver.
Published on 2019-03-14 in dreambox, php, video, web