{"@attributes":{"version":"2.0"},"channel":{"title":"Klausi's Weblog","link":"https:\/\/klau.si","description":{},"generator":"Zola","language":"en","lastBuildDate":"Thu, 23 Apr 2026 00:00:00 +0000","item":[{"title":"Mago presentation at Drupal Dev Days Athens","pubDate":"Thu, 23 Apr 2026 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/mago-format-your-drupal-code\/","guid":"https:\/\/klau.si\/blog\/mago-format-your-drupal-code\/","description":"<div class=\"youtube-lazy\" data-video-id=\"bNI_PC1bBuE\">\n  <a href=\"https:\/\/www.youtube.com\/watch?v=bNI_PC1bBuE\"\n     class=\"youtube-lazy-placeholder\"\n     target=\"_blank\"\n     rel=\"noopener\">\n    <img src=\"https:\/\/klau.si\/youtube-thumbs\/bNI_PC1bBuE.webp\"\n         alt=\"YouTube video thumbnail - click to play\"\n         loading=\"lazy\"\n         width=\"480\"\n         height=\"270\">\n  <\/a>\n<\/div>\n<p>Here are <a href=\"https:\/\/klau.si\/blog\/mago-format-your-drupal-code\/drupal-dev-days-2026-mago-format-code.pdf\">the slides<\/a> and <a rel=\"external\" href=\"https:\/\/www.youtube.com\/watch?v=bNI_PC1bBuE\">video<\/a> of my <a rel=\"external\" href=\"https:\/\/devdays2026.drupal.org.gr\/drupal-developer-days-athens-2026\/session\/mago-format-lint-and-analyze-your-php-code\">Drupal Dev Days presentation<\/a> about <a rel=\"external\" href=\"https:\/\/mago.carthage.software\/\">Mago<\/a> in Athens.<\/p>"},{"title":"almost kms many times","pubDate":"Sun, 22 Mar 2026 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/almost-kms-many-times\/","guid":"https:\/\/klau.si\/blog\/almost-kms-many-times\/","description":"<p><strong>Triggerwarnung: Tod, Suizid<\/strong><\/p>\n<p>Mein Sohn <a href=\"https:\/\/klau.si\/blog\/moony\/\">Moony<\/a> hat sich das Leben genommen. In meiner Trauer ist dieser Text entstanden (weitere Texte in der Kategorie: <a href=\"\/tags\/suicide\">suicide<\/a>).<\/p>\n<p><img src=\"https:\/\/klau.si\/blog\/almost-kms-many-times\/moony-2025-review.webp\" alt=\"Foto von Moony, der in einem Aufzug steht und ein Selfie macht. Kurze blaue Haare, helle Haut, schwarzer Hoodie, olivgr\u00fcne Hose. In der rechten Hand h\u00e4lt er eine kleine wei\u00dfe Medikamentenschachtel. Dar\u00fcber sind einige Textzeilen eingeblendet: \u2022 got a wheelchair \u2022 changed legal name &amp; gender \u2022 started testosterone \u2022 turning 18 \u2022 mom found out i smoke \u2022 almost kms many times \u2022 got a fibromyalgia diagnosis \u2022 got caught smoking underage by the police \u2022 lost almost 10kg \u2022 quit my antidepressants \u2022 mh is still shit \u2022 barely worked on my and my friend&#39;s book \u2022 was on two different waiting lists for the hospital \u2022 parents spent thousands of euros on doctors\/treatments and nothing helped at all \u2022 collected like 6 7 reports from psychologists and such to transition\" \/><\/p>"},{"title":"18 Monate","pubDate":"Fri, 20 Feb 2026 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/18-monate\/","guid":"https:\/\/klau.si\/blog\/18-monate\/","description":"<p><strong>Triggerwarnung: Tod, Suizid<\/strong><\/p>\n<p>Ich trauere um meinen Sohn <a href=\"https:\/\/klau.si\/blog\/moony\/\">Moony<\/a>, der sich das Leben genommen hat. Dies ist ein weiterer Text in meiner Suche nach Umgang mit Selbstmord (Kategorie: <a href=\"\/tags\/suicide\">suicide<\/a>).<\/p>\n<p><img src=\"https:\/\/klau.si\/blog\/18-monate\/moony-hair.webp\" alt=\"Portr\u00e4tfoto des 17-j\u00e4hrigen Moony. Kurze, schwarz gef\u00e4rbte Haare mit einem einrasierten Muster auf der Seite des Kopfes. 2 Piercings im Ohr, eines in der Nase. Grau-gr\u00fcne Augen. Wei\u00dfe Hautfarbe. Dunkelgr\u00fcner Sweater.\" \/><\/p>"},{"title":"Moony","pubDate":"Sun, 01 Feb 2026 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/moony\/","guid":"https:\/\/klau.si\/blog\/moony\/","description":"<p><strong>Triggerwarnung: Tod, Suizid<\/strong><\/p>\n<p>Mein Sohn Moony hat sich das Leben genommen. In meiner Trauer ist dieser Text entstanden (weitere Texte in der Kategorie: <a href=\"\/tags\/suicide\">suicide<\/a>).<\/p>\n<p><img src=\"https:\/\/klau.si\/blog\/moony\/moony-datum.webp\" alt=\"Portr\u00e4tfoto des 18-j\u00e4hrigen Moony. Kurzes blondes und blaues Haar. Helle Hautfarbe. Piercings im Ohr und in der Nase. Beinahe ein L\u00e4cheln. Geboren 22.12.2007, gestorben 26.01.2026.\" \/><\/p>"},{"title":"Testing Claude AI for Drupal code","pubDate":"Fri, 04 Apr 2025 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/testing-claude-ai-for-drupal-code\/","guid":"https:\/\/klau.si\/blog\/testing-claude-ai-for-drupal-code\/","description":"<p>I tested ClaudeAI for Drupal code, got inspired by <a rel=\"external\" href=\"https:\/\/dri.es\/claude-code-meets-drupal\">Dries Buytaert video<\/a>.<\/p>\n<ul>\n<li>\ud83e\udd2f the interaction and suggestions were quite good<\/li>\n<li>\ud83d\udcb5 execution is expensive, I paid $1.16 for 20 minutes<\/li>\n<li>\ud83d\ude44 I got annoyed a couple of times, because Claude did contradictory things<\/li>\n<\/ul>\n<div class=\"youtube-lazy\" data-video-id=\"7U4XwkjfckE\">\n  <a href=\"https:\/\/www.youtube.com\/watch?v=7U4XwkjfckE\"\n     class=\"youtube-lazy-placeholder\"\n     target=\"_blank\"\n     rel=\"noopener\">\n    <img src=\"https:\/\/klau.si\/youtube-thumbs\/7U4XwkjfckE.webp\"\n         alt=\"YouTube video thumbnail - click to play\"\n         loading=\"lazy\"\n         width=\"480\"\n         height=\"270\">\n  <\/a>\n<\/div>"},{"title":"Dangerous Next.js redirects - how misconfiguration can bring your website down","pubDate":"Thu, 30 Jan 2025 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/security-advisory-nextjs-redirects\/","guid":"https:\/\/klau.si\/blog\/security-advisory-nextjs-redirects\/","description":"<p><img src=\"https:\/\/klau.si\/blog\/security-advisory-nextjs-redirects\/nextjs_exhale.webp\" alt=\"Black Next.js logos arranged in a circle. In the middle is an emoji with closed eyes exhausting.\" \/><\/p>\n<p>Security Advisory: Next.js Denial of Service vulnerability in redirect misconfiguration<\/p>\n<ul>\n<li><strong>Project<\/strong>: <a rel=\"external\" href=\"https:\/\/nextjs.org\/\">Next.js<\/a><\/li>\n<li><strong>Security Risk<\/strong>: Less Critical<\/li>\n<li><strong>Vulnerability<\/strong>: Denial of Service (DoS)<\/li>\n<li><strong>Category<\/strong>: <a rel=\"external\" href=\"https:\/\/owasp.org\/Top10\/A05_2021-Security_Misconfiguration\/\">OWASP A05:2021 \u2013 Security Misconfiguration<\/a><\/li>\n<li><strong>Affected versions<\/strong>: all Next.js versions, for example 15.0.3<\/li>\n<\/ul>\n<p>Note: This vulnerability has been disclosed privately to the Vercel Security Team. They decided that this is a misconfiguration issue and not an inherent security issue.<\/p>"},{"title":"D7Security presentation at Drupal Dev Days Bourgas","pubDate":"Wed, 26 Jun 2024 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/d7security-devdays\/","guid":"https:\/\/klau.si\/blog\/d7security-devdays\/","description":"<p>Here are <a href=\"https:\/\/klau.si\/blog\/d7security-devdays\/d7security-dev-days-bourgas-2024.pdf\">the slides<\/a> of my <a rel=\"external\" href=\"https:\/\/ddd2024.drupalcamp.bg\/drupal-dev-days-2024\/session\/d7security-drupal-7-long-term-support\">Drupal Dev Days presentation<\/a> about <a rel=\"external\" href=\"https:\/\/www.d7security.org\">D7Security<\/a> in Bourgas. Unfortunately there is no video recording.<\/p>"},{"title":"D7Security presentation at Drupal Austria Meetup","pubDate":"Wed, 13 Mar 2024 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/d7security-drupal-austria-meetup\/","guid":"https:\/\/klau.si\/blog\/d7security-drupal-austria-meetup\/","description":"<p>Here are <a href=\"https:\/\/klau.si\/blog\/d7security-drupal-austria-meetup\/d7security-drupal-austria-2024.pdf\">the slides<\/a> and a recording of my Drupal Austria Meetup presentation about <a rel=\"external\" href=\"https:\/\/www.d7security.org\">D7Security<\/a>.<\/p>\n<div class=\"youtube-lazy\" data-video-id=\"1vLU1Eo0Tkk\">\n  <a href=\"https:\/\/www.youtube.com\/watch?v=1vLU1Eo0Tkk\"\n     class=\"youtube-lazy-placeholder\"\n     target=\"_blank\"\n     rel=\"noopener\">\n    <img src=\"https:\/\/klau.si\/youtube-thumbs\/1vLU1Eo0Tkk.webp\"\n         alt=\"YouTube video thumbnail - click to play\"\n         loading=\"lazy\"\n         width=\"480\"\n         height=\"270\">\n  <\/a>\n<\/div>"},{"title":"Drupal 7 end of life podcast: Unofficial Drupal 7 Security Team","pubDate":"Sun, 31 Dec 2023 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/d7-eol-podcast\/","guid":"https:\/\/klau.si\/blog\/d7-eol-podcast\/","description":"<p>Here is the video of my appearance on the Drupal 7 end of life podcast, talking about plans for the <a rel=\"external\" href=\"https:\/\/www.d7security.org\/\">D7Security<\/a> group. Thank you Mark Dorison and Chris Free from Chromatic for the recording!<\/p>\n<div class=\"youtube-lazy\" data-video-id=\"hNI73M0ftOM\">\n  <a href=\"https:\/\/www.youtube.com\/watch?v=hNI73M0ftOM\"\n     class=\"youtube-lazy-placeholder\"\n     target=\"_blank\"\n     rel=\"noopener\">\n    <img src=\"https:\/\/klau.si\/youtube-thumbs\/hNI73M0ftOM.webp\"\n         alt=\"YouTube video thumbnail - click to play\"\n         loading=\"lazy\"\n         width=\"480\"\n         height=\"270\">\n  <\/a>\n<\/div>"},{"title":"Proposing a Drupal 7 security team","pubDate":"Tue, 12 Dec 2023 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/proposing-drupal-7-security-team\/","guid":"https:\/\/klau.si\/blog\/proposing-drupal-7-security-team\/","description":"<p><strong>Update:<\/strong> The D7Security group is now established at <a rel=\"external\" href=\"https:\/\/gitlab.com\/d7security\">gitlab.com\/d7security<\/a> and <a rel=\"external\" href=\"https:\/\/www.d7security.org\/\">d7security.org<\/a>!<\/p>\n<p><img src=\"https:\/\/klau.si\/blog\/proposing-drupal-7-security-team\/unsupported-hm.webp\" alt=\"Screenshot of a drupal.org release settings page. Contains a warning box with the text &quot;Branches compatible with Drupal 7.x that are set as unsupported cannot be set as supported again.&quot;. A big thinking emoji is inserted on the screenshot.\" \/><\/p>\n<p>The Drupal Security Team has announced in <a rel=\"external\" href=\"https:\/\/www.drupal.org\/psa-2023-06-07\">PSA-2023-06-07<\/a> that unsupported Drupal 7 modules\/themes cannot be supported again. I'm proposing to create a D7Security team on Gitlab.com that can provide security fixes for those unsupported modules. A small update module can then notify Drupal 7 site owners when new security releases are available on Gitlab.com.<\/p>"},{"title":"Fully hidden automatic system updates on Ubuntu 20.04","pubDate":"Tue, 05 Jan 2021 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/fully-hidden-automatic-system-updates-ubuntu\/","guid":"https:\/\/klau.si\/blog\/fully-hidden-automatic-system-updates-ubuntu\/","description":"<p><img src=\"https:\/\/klau.si\/blog\/fully-hidden-automatic-system-updates-ubuntu\/tank-girl-update-smaller.webp\" alt=\"Screenshot of Ubuntu&#39;s update manager popping up during the movie &quot;Tank Girl.&quot;\" \/><\/p>\n<p>Ubuntu's graphical update manager pops up every time you need to install updates. That can be annoying when you are watching a movie or doing other things and don't want to be bothered all the time. Yes, I want to always apply all updates from all sources, but please do it silently. Here is a small script I use to do that with Anacron.<\/p>"},{"title":"Russmedia CTO meetup talk: Pull Request Review best practices","pubDate":"Fri, 27 Nov 2020 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/russmedia-cto-meetup-talk-pull-request-review\/","guid":"https:\/\/klau.si\/blog\/russmedia-cto-meetup-talk-pull-request-review\/","description":"<p>Here is the video of my Russmedia CTO &amp; product meetup talk \"Pull Request Review best practices\".<\/p>\n<div class=\"youtube-lazy\" data-video-id=\"6CbdQaWI5Hk\">\n  <a href=\"https:\/\/www.youtube.com\/watch?v=6CbdQaWI5Hk\"\n     class=\"youtube-lazy-placeholder\"\n     target=\"_blank\"\n     rel=\"noopener\">\n    <img src=\"https:\/\/klau.si\/youtube-thumbs\/6CbdQaWI5Hk.webp\"\n         alt=\"YouTube video thumbnail - click to play\"\n         loading=\"lazy\"\n         width=\"480\"\n         height=\"270\">\n  <\/a>\n<\/div>"},{"title":"Drupalcon 2019 talk: Find security vulnerabilities through code review","pubDate":"Sun, 03 Nov 2019 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/drupalcon-security-code-review\/","guid":"https:\/\/klau.si\/blog\/drupalcon-security-code-review\/","description":"<p>Here are <a rel=\"external\" href=\"https:\/\/klausi.github.io\/sec-code-review2019\/#\/\">the slides<\/a> and the video of my DrupalCon Amsterdam 2019 talk \"Find security vulnerabilities through code review\".<\/p>\n<div class=\"youtube-lazy\" data-video-id=\"Oyoja2rfqSk\">\n  <a href=\"https:\/\/www.youtube.com\/watch?v=Oyoja2rfqSk\"\n     class=\"youtube-lazy-placeholder\"\n     target=\"_blank\"\n     rel=\"noopener\">\n    <img src=\"https:\/\/klau.si\/youtube-thumbs\/Oyoja2rfqSk.webp\"\n         alt=\"YouTube video thumbnail - click to play\"\n         loading=\"lazy\"\n         width=\"480\"\n         height=\"270\">\n  <\/a>\n<\/div>"},{"title":"A new blog on Zola","pubDate":"Sat, 26 Oct 2019 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/a-new-blog-on-zola\/","guid":"https:\/\/klau.si\/blog\/a-new-blog-on-zola\/","description":"<p><img src=\"https:\/\/klau.si\/blog\/a-new-blog-on-zola\/zola.ico\" alt=\"Zola logo\" \/><\/p>\n<p>I converted my old blog posts from Drupal to static files and now I'm trying out <a rel=\"external\" href=\"https:\/\/www.getzola.org\">Zola<\/a>. The static files are hosted on <a rel=\"external\" href=\"https:\/\/www.getzola.org\/documentation\/deployment\/github-pages\/\">Github Pages<\/a>.<\/p>"},{"title":"Mocking in Rust with conditional compilation","pubDate":"Sun, 31 Mar 2019 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/mocking-in-rust-with-conditional-compilation\/","guid":"https:\/\/klau.si\/blog\/mocking-in-rust-with-conditional-compilation\/","description":"<p>When writing automated unit tests for your application you will probably need to use <a rel=\"external\" href=\"https:\/\/en.wikipedia.org\/wiki\/Mock_object\">mocks<\/a> at some point. Classical object-oriented programming languages such as PHP solve this with reflection where mock object types are created during test runtime. The code under test expects a certain interface or class and the test code passes mock objects that implement the interface or are a subclass.<\/p>\n<p>Similar approaches exist in Rust where mock objects are used to test code that expects a trait type. There is a wonderful <a rel=\"external\" href=\"https:\/\/asomers.github.io\/mock_shootout\/\">Rust mock framework comparison<\/a> by Alan Somers that lists their features. The biggest problem with most of them as far as I can see is that they cannot mock a foreign <code>struct<\/code> you are using in your code. Rust does not have a concept of object inheritance for structs so there is no way to mimic a struct type from the standard library or an external crate.<\/p>"},{"title":"Drupal Austria Meetup: Drupal security learnings","pubDate":"Wed, 13 Mar 2019 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/drupal-security-vulnerability-learnings\/","guid":"https:\/\/klau.si\/blog\/drupal-security-vulnerability-learnings\/","description":"<p><img src=\"https:\/\/klau.si\/blog\/drupal-security-vulnerability-learnings\/meetup_security.jpeg\" alt=\"Drupal Austria security meetup\" \/><\/p>\n<p>Here are <a href=\"\/presentations\/sec-learnings2019\/index.html\">the slides<\/a> of my Drupal Austria Meetup talk \"Drupal security learnings\".<\/p>"},{"title":"Benchmarking a Rust web application","pubDate":"Fri, 31 Aug 2018 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/benchmarking-a-rust-web-application\/","guid":"https:\/\/klau.si\/blog\/benchmarking-a-rust-web-application\/","description":"<p>Performance testing is an important part when developing a network application - you want to know when you have a regression in request throughput in your service.<\/p>\n<p>I set out out my goal 9 for Rustnish:<\/p>\n<blockquote>\n<p>Write benchmark code that compares runtime performance of Rustnish against\n<a rel=\"external\" href=\"https:\/\/varnish-cache.org\/\">Varnish<\/a>. Use <code>cargo bench<\/code> to execute the benchmarks.<\/p>\n<\/blockquote>\n<p>The basic idea of a performance test here is to send many HTTP requests to the web service (the reverse proxy in this case) and measure how fast the responses arrive back. Comparing the results from Rustnish and Varnish should give us an idea if our performance expectations are holding up.<\/p>"},{"title":"Crashing a Rust Hyper server with a Denial of Service attack","pubDate":"Sun, 11 Mar 2018 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/crashing-a-rust-hyper-server-with-a-denial-of-service-attack\/","guid":"https:\/\/klau.si\/blog\/crashing-a-rust-hyper-server-with-a-denial-of-service-attack\/","description":"<p>I'm writing a reverse proxy in Rust using <a rel=\"external\" href=\"https:\/\/hyper.rs\/\">Hyper<\/a> and I want\nto measure performance a bit to know if I'm doing something terribly wrong. By\ndoing that I discovered a Denial of Service vulnerability in Hyper when IO\nerrors are not properly handled. Note that <a rel=\"external\" href=\"https:\/\/github.com\/hyperium\/hyper\/releases\/tag\/v0.11.20\">a workaround has been released in\nthe meantime in Hyper\n0.11.20<\/a>, more\nbackground info can be found in <a rel=\"external\" href=\"https:\/\/github.com\/hyperium\/hyper\/issues\/1358\">this Hyper\nissue<\/a>.<\/p>"},{"title":"Testing memory leaks in Rust","pubDate":"Fri, 06 Oct 2017 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/testing-memory-leaks-in-rust\/","guid":"https:\/\/klau.si\/blog\/testing-memory-leaks-in-rust\/","description":"<p>Rust has many built-in concepts for memory safety, but it cannot prevent\napplication level logic errors that take up system memory. An example would be\na server application that stores something for each incoming request in a\ngrowing collection or list. If the program does not clean up the growing list\nthen it will take up more and more server memory - thereby exposing a memory\nleak.<\/p>\n<p>While working on my reverse proxy project I discovered such a <a rel=\"external\" href=\"https:\/\/github.com\/hyperium\/hyper\/issues\/1315\">leak in the HTTP\nlibrary Hyper<\/a>. In order to\nprevent and detect memory leaks in the future I set out my goal 7:<\/p>\n<blockquote>\n<p>Add an integration test that ensures that the proxy server is not leaking\nmemory (growing RAM usage without shrinking again). Use \/proc information to\ncompare memory usage of the current process before and after the test.<\/p>\n<\/blockquote>"},{"title":"Static variables made thread-safe in Rust","pubDate":"Sat, 09 Sep 2017 00:00:00 +0000","author":"Klaus Purer","link":"https:\/\/klau.si\/blog\/static-variables-made-thread-safe-in-rust\/","guid":"https:\/\/klau.si\/blog\/static-variables-made-thread-safe-in-rust\/","description":"<p>When writing <a href=\"https:\/\/klau.si\/blog\/writing-integration-tests-in-rust\/\">integration tests for my Rustnish reverse proxy project<\/a> I\nhave hard-coded port numbers in tests. This is not ideal because it is hard to\nkeep track of which port numbers have already been used and which ones are\navailable when writing a new test. Because Rust's test runner <a rel=\"external\" href=\"https:\/\/doc.rust-lang.org\/book\/ch11-02-running-tests.html#running-tests-in-parallel-or-consecutively\">executes test cases in parallel<\/a> it is important to coordinate\nwhich test uses which ports so that there are no clashes that break the tests.<\/p>\n<p>One obvious solution to this problem would be to disable parallel test\nexecution with <code>cargo test -- --test-threads=1<\/code>. But we want to cover program\nand test isolation with our test so this is not really an option.<\/p>"}]}}