<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yaroslav Polyakov</title>
    <description>The latest articles on DEV Community by Yaroslav Polyakov (@yaroslaff).</description>
    <link>https://dev.to/yaroslaff</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F957071%2F396bc340-4607-4f50-a3cb-6eef4cc4a6c2.png</url>
      <title>DEV Community: Yaroslav Polyakov</title>
      <link>https://dev.to/yaroslaff</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yaroslaff"/>
    <language>en</language>
    <item>
      <title>SmugglerJPG: Free unlimited photo hosting on... Youtube!</title>
      <dc:creator>Yaroslav Polyakov</dc:creator>
      <pubDate>Thu, 25 Jun 2026 17:25:34 +0000</pubDate>
      <link>https://dev.to/yaroslaff/smugglerjpg-free-unlimited-photo-hosting-on-youtube-296j</link>
      <guid>https://dev.to/yaroslaff/smugglerjpg-free-unlimited-photo-hosting-on-youtube-296j</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; &lt;a href="https://github.com/yaroslaff/smugglerjpg" rel="noopener noreferrer"&gt;https://github.com/yaroslaff/smugglerjpg&lt;/a&gt;. We turn photos into a slideshow video and upload it (you can make it unlisted or private so no one sees it). Then, if needed, download the video and extract the photos back.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyuyhnpcgop9gp24ajigk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyuyhnpcgop9gp24ajigk.jpg" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In the image: the original (left) and after packing → uploading → downloading → extracting (right). The second image has lower resolution, so both were scaled to the same height for comparison.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Video hosting platforms let you store huge videos, but not photos. Messengers allow sending and storing photos, but they’re inconvenient for managing collections (folders, groups, etc.).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Turn your photos into a slideshow in a way that makes it easy to extract them back later — either lossless or with minimal quality loss.&lt;/p&gt;

&lt;h3&gt;
  
  
  SmugglerJPG — Packing a Gallery into a Single Video
&lt;/h3&gt;

&lt;p&gt;We’ll use my small tool: &lt;a href="https://github.com/yaroslaff/smugglerjpg" rel="noopener noreferrer"&gt;smugglerjpg&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pipx &lt;span class="nb"&gt;install &lt;/span&gt;smugglerjpg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don’t have pipx: &lt;code&gt;apt install pipx&lt;/code&gt;. On Windows it should also be possible (I haven’t tried). You’ll also need &lt;code&gt;ffmpeg&lt;/code&gt; on Linux.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating the video&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;smugglerjpg create /tmp/testgallery/ &lt;span class="nt"&gt;-a&lt;/span&gt; ~/tmp/bgmusic/ &lt;span class="nt"&gt;-o&lt;/span&gt; out.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-a&lt;/code&gt; — add background music (so you can even watch it yourself without getting too bored)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-d&lt;/code&gt; — duration of each slide (default: 5 seconds)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want the photos in a specific order, use &lt;code&gt;--sort name&lt;/code&gt;, &lt;code&gt;--sort mtime&lt;/code&gt;, or &lt;code&gt;-f filelist.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then just upload the video wherever you want.&lt;/p&gt;

&lt;h3&gt;
  
  
  Extracting Your Contraband Back
&lt;/h3&gt;

&lt;p&gt;Download the video (from the studio or via &lt;a href="https://github.com/yt-dlp/yt-dlp" rel="noopener noreferrer"&gt;yt-dlp&lt;/a&gt;) and extract it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;smugglerjpg extract out-ytdlp.webm &lt;span class="nt"&gt;-o&lt;/span&gt; /tmp/extracted/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll get your original pictures back (with only a small quality loss — barely noticeable to my eye).&lt;/p&gt;

&lt;h3&gt;
  
  
  Quality Control
&lt;/h3&gt;

&lt;p&gt;Original photo example:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mediainfo testgallery/IMG20260513193409.jpg
General
Complete name : testgallery/IMG20260513193409.jpg
Format : JPEG
File size : 10.8 MiB
Image
Format : JPEG
Width : 3 072 pixels
Height : 4 096 pixels
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Compression mode : Lossy
Stream size : 10.8 MiB (100%)
ColorSpace_ICC : RGB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Our local video file:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mediainfo out.mp4
General
Complete name : out.mp4
Format : MPEG-4
Format profile : Base Media
Codec ID : isom (isom/iso2/avc1/mp41)
File size : 18.8 MiB
Duration : 35 s 0 ms
Overall bit rate : 4 517 kb/s
Frame rate : 30.000 FPS
Writing application : Lavf61.7.103
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : Constrained Baseline@L5.1
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;File after yt-dlp from YouTube:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mediainfo out-ytdlp.webm
General
Complete name : out-ytdlp.webm
Format : WebM
...
Video
Format : AV1
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Extracted image parameters:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mediainfo /tmp/extracted/extracted_slide_003.jpg
General
Complete name : /tmp/extracted/extracted_slide_003.jpg
Format : JPEG
File size : 967 KiB
Image
Format : JPEG
Width : 1 620 pixels
Height : 2 160 pixels
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h3&gt;
  
  
  Notes &amp;amp; Tips
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;On YouTube, you can keep videos as &lt;strong&gt;unlisted&lt;/strong&gt;, &lt;strong&gt;private&lt;/strong&gt;, or even as &lt;strong&gt;Draft&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Video resolution is the same for the entire duration. Mixing portrait and landscape photos in one video will result in higher quality loss. That said, modern phones have so many megapixels that I don’t notice the difference after the process.&lt;/li&gt;
&lt;li&gt;This was made with an LLM, so… you know how it is.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Enjoy and keep your precious memories safe!&lt;/p&gt;

</description>
      <category>free</category>
      <category>image</category>
      <category>hosting</category>
      <category>storage</category>
    </item>
    <item>
      <title>Your own Certificate Authority (CA) in ONE simple command</title>
      <dc:creator>Yaroslav Polyakov</dc:creator>
      <pubDate>Mon, 29 Jan 2024 19:56:18 +0000</pubDate>
      <link>https://dev.to/yaroslaff/your-own-certificate-authority-ca-in-one-simple-command-23ob</link>
      <guid>https://dev.to/yaroslaff/your-own-certificate-authority-ca-in-one-simple-command-23ob</guid>
      <description>&lt;p&gt;You can find many instructions how to make certificates with OpenSSL. OpenSSL is very good except... it's too complex. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yaroslaff/showcert" rel="noopener noreferrer"&gt;Showcert&lt;/a&gt; is OpenSSL for humans, much simpler to use and it has &lt;code&gt;gencert&lt;/code&gt; utility to generate certificates. Very easy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate self-signed cert with simple command
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gencert example.com www.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will make self-signed cert. Easy, isn't it?&lt;/p&gt;

&lt;h2&gt;
  
  
  Your own CA
&lt;/h2&gt;

&lt;p&gt;Generate CA certificate (1 command):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gencert --ca MyCA
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thats all! Now, you can import generated &lt;code&gt;MyCA.pem&lt;/code&gt; file to browsers and generate signed certificates for sites:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gencert --cacert MyCA.pem --cakey MyCA.key example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What could be simpler?&lt;/p&gt;

&lt;p&gt;Install &lt;a href="https://github.com/yaroslaff/showcert" rel="noopener noreferrer"&gt;showcert&lt;/a&gt; and play for yourself.&lt;/p&gt;

</description>
      <category>ssl</category>
      <category>tls</category>
      <category>https</category>
      <category>openssl</category>
    </item>
    <item>
      <title>Great design trick I learned in X.509 (critical extension)</title>
      <dc:creator>Yaroslav Polyakov</dc:creator>
      <pubDate>Thu, 25 Jan 2024 16:24:17 +0000</pubDate>
      <link>https://dev.to/yaroslaff/great-design-trick-i-learned-in-x509-critical-extension-1gjd</link>
      <guid>https://dev.to/yaroslaff/great-design-trick-i-learned-in-x509-critical-extension-1gjd</guid>
      <description>&lt;p&gt;Good software, file formats and network protocols are extendable. You may develop new version later, but it should interoperate with older version. Old client software must work with new server and vice versa. Old software must open files created by new version of software and vice versa.&lt;/p&gt;

&lt;p&gt;Extensions are good for this, but usually it comes with problem: How should software work, if it finds unknown extension? Often answer is simple - "just ignore it". Skip unknown extension and process file/request. (Same as your web app does if HTTP request has unknown header - it just does not looks at it)&lt;/p&gt;

&lt;p&gt;But sometimes this approach will fail. Sometimes simple ignoring extension will not work (especially in security area). And here comes "critical extension". Extension has some identified and simple boolean flag "critical". &lt;/p&gt;

&lt;p&gt;If software founds unknown extension it looks for flag. if not critical - ignore extension and go on. If critical - sorry, this software can not process this file/request (and it's very good if old software knows when it can process new data and when it should not try).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://datatracker.ietf.org/doc/html/rfc5280" rel="noopener noreferrer"&gt;https://datatracker.ietf.org/doc/html/rfc5280&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ssl</category>
      <category>softwareengineering</category>
      <category>x509</category>
      <category>rfc5280</category>
    </item>
    <item>
      <title>Simple decorator to retry after exception</title>
      <dc:creator>Yaroslav Polyakov</dc:creator>
      <pubDate>Mon, 18 Dec 2023 19:30:29 +0000</pubDate>
      <link>https://dev.to/yaroslaff/simple-decorator-to-retry-after-exception-5a6</link>
      <guid>https://dev.to/yaroslaff/simple-decorator-to-retry-after-exception-5a6</guid>
      <description>&lt;p&gt;Typical situation: you have unreliable function, for example, doing HTTP requests and getting exception from time to time. Maybe connection went down temporary or 429 Too Many requests problem, or remote service itself is temporary broken. &lt;/p&gt;

&lt;p&gt;One simple decorator solves problem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;functools&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;retry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_times&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;decorator_repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nd"&gt;@functools.wraps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wrapper_repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;last_exception&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_times&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;last_exception&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
                    &lt;span class="c1"&gt;# handle exception. log it or just pass
&lt;/span&gt;                    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Try #&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; got exception &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, but we will retry&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;last_exception&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;wrapper_repeat&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;decorator_repeat&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lets use it with requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="nd"&gt;@retry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;myhttp&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://httpbin.org/status/200,500,429&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;myhttp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Try #0 got exception 429 Client Error: TOO MANY REQUESTS for url: https://httpbin.org/status/200,500,429, but we will retry
Try #1 got exception 500 Server Error: INTERNAL SERVER ERROR for url: https://httpbin.org/status/200,500,429, but we will retry
Try #2 got exception 500 Server Error: INTERNAL SERVER ERROR for url: https://httpbin.org/status/200,500,429, but we will retry
200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way you are immune against temporary problems which could be solved by retry (maybe with &lt;code&gt;time.sleep(10)&lt;/code&gt;) but you will still get exception from long-time problems. Change URL in &lt;code&gt;myhttp()&lt;/code&gt; to &lt;a href="https://httpbin.org/status/500" rel="noopener noreferrer"&gt;https://httpbin.org/status/500&lt;/a&gt; to see this.&lt;/p&gt;

</description>
      <category>python</category>
      <category>decorator</category>
      <category>exception</category>
      <category>requests</category>
    </item>
    <item>
      <title>apache2 allows CORS with credentials for any address</title>
      <dc:creator>Yaroslav Polyakov</dc:creator>
      <pubDate>Thu, 12 Oct 2023 08:51:00 +0000</pubDate>
      <link>https://dev.to/yaroslaff/apache2-allows-cors-with-credentials-for-any-address-nha</link>
      <guid>https://dev.to/yaroslaff/apache2-allows-cors-with-credentials-for-any-address-nha</guid>
      <description>&lt;p&gt;You cannot use '*' in &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt; and use &lt;code&gt;Access-Control-Allow-Credentials&lt;/code&gt; at same time. And this is actually makes sense, but during development this dirty hack is useful (for apache2):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;&lt;span class="nc"&gt;SetEnvIf&lt;/span&gt; Origin "^http(s)?://.*$" REQUEST_ORIGIN=$0
&lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="ss"&gt;always&lt;/span&gt; &lt;span class="ss"&gt;set&lt;/span&gt; Access-Control-Allow-Origin %{REQUEST_ORIGIN}e env=REQUEST_ORIGIN
&lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="ss"&gt;always&lt;/span&gt; &lt;span class="ss"&gt;set&lt;/span&gt; Access-Control-Allow-Credentials true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How it work in action (I'm using httpie instead of curl):&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;$ http -ph POST https://example.com/ Origin:https://google.com
&lt;/span&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Accept-Ranges&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bytes&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Allow-Credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;Access-Control-Allow-Origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://google.com&lt;/span&gt;
&lt;span class="na"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Keep-Alive&lt;/span&gt;
&lt;span class="na"&gt;Content-Encoding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gzip&lt;/span&gt;
&lt;span class="na"&gt;Content-Length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1039&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;text/html&lt;/span&gt;
&lt;span class="na"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Thu, 12 Oct 2023 08:50:33 GMT&lt;/span&gt;
&lt;span class="na"&gt;ETag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"9a1-6020521d58f80-gzip"&lt;/span&gt;
&lt;span class="na"&gt;Keep-Alive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;timeout=5, max=100&lt;/span&gt;
&lt;span class="na"&gt;Last-Modified&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Thu, 03 Aug 2023 13:55:26 GMT&lt;/span&gt;
&lt;span class="na"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Apache/2.4.56 (Debian)&lt;/span&gt;
&lt;span class="na"&gt;Strict-Transport-Security&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;max-age=31536000; includeSubDomains&lt;/span&gt;
&lt;span class="na"&gt;Vary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Accept-Encoding&lt;/span&gt;
&lt;span class="na"&gt;X-Content-Type-Options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nosniff&lt;/span&gt;
&lt;span class="na"&gt;X-Frame-Options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;disabled&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want it only for specific Origins:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;    &lt;span class="nc"&gt;SetEnvIf&lt;/span&gt; Origin "^https?://(example.com|www.example.com)$" GOODORIGIN=$0
    &lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="ss"&gt;set&lt;/span&gt; Access-Control-Allow-Origin %{GOODORIGIN}e env=GOODORIGIN
    &lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="ss"&gt;set&lt;/span&gt; Access-Control-Allow-Credentials "true" env=GOODORIGIN
    &lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="ss"&gt;merge&lt;/span&gt; Vary Origin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>apache2</category>
      <category>cors</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Mix static &amp; client-side rendering on same page with SvelteKit</title>
      <dc:creator>Yaroslav Polyakov</dc:creator>
      <pubDate>Wed, 18 Jan 2023 16:08:39 +0000</pubDate>
      <link>https://dev.to/yaroslaff/mix-static-client-side-rendering-on-same-page-with-sveltekit-4b61</link>
      <guid>https://dev.to/yaroslaff/mix-static-client-side-rendering-on-same-page-with-sveltekit-4b61</guid>
      <description>&lt;p&gt;I love static websites, because they are very fast and very good for SEO, google can 'read' it much better. But these days you need JavaScript almost everywhere.&lt;/p&gt;

&lt;p&gt;And I like Svelte as very easy to learn and use lightweight framework.&lt;/p&gt;

&lt;p&gt;I've found out, that it's not very simple to mix static rendering and CSR on same page. But possible. I will use time (JavaScript Date() result) as example data, but in production it can be your data, e.g. "BFGoodrich tyre" or "Red apples" or "War and Peace by Leo Tolstoy".&lt;/p&gt;

&lt;p&gt;Our example page will print very simple text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Date: Wed, 18 Jan 2023 15:49:03 GMT
Build: Wed, 18 Jan 2023 15:49:01 GMT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First line (Date:) is content you calculated on client-side, when page is loaded. Second line (Build:) is build-time, something you calculated during &lt;code&gt;npm run build&lt;/code&gt; which must be visible to search engine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create project
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create svelte@latest hybrid
&lt;span class="nb"&gt;cd &lt;/span&gt;hybrid
npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Enable static adapter
&lt;/h2&gt;

&lt;p&gt;Install it: &lt;code&gt;npm i -D @sveltejs/adapter-static&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In svelte.config.js disable adapter-auto and use adapter-static:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;adapter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@sveltejs/adapter-static&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can generate static website with &lt;code&gt;npm run build&lt;/code&gt; and preview it with &lt;code&gt;npm run preview&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  src/routes/+page.server.js
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prerender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toUTCString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  src/routes/+page.svelte:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$app/environment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;buildtime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;}{&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toUTCString&lt;/span&gt;&lt;span class="p"&gt;()}{&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;br&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nx"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;buildtime&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;run: &lt;code&gt;npm run build &amp;amp;&amp;amp; npm run preview&lt;/code&gt; and open &lt;a href="http://localhost:4173/" rel="noopener noreferrer"&gt;http://localhost:4173/&lt;/a&gt; you will see result. If you will reload page in a second, Date will change, but Build will stay same.&lt;/p&gt;

&lt;p&gt;Also, if you will open build/index.html you will see there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;...
Date: 
&lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
Build: Wed, 18 Jan 2023 15:58:18 GMT
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you see, our statically generated content is clearly visible in page. &lt;/p&gt;

&lt;h2&gt;
  
  
  Explanation
&lt;/h2&gt;

&lt;p&gt;in &lt;code&gt;+page.server.js&lt;/code&gt; we set &lt;code&gt;prerendering=true&lt;/code&gt; to generate static HTML site (with JS) as a result. And we return data with current Date(). We must convert it to string here, because client browser may have different timezone and Build: date will be "flashing" (initially it will have date in our timezone, and in fraction of second it will be overwritten). Not nice.&lt;/p&gt;

&lt;p&gt;in &lt;code&gt;+page.svelte&lt;/code&gt; we use this data. Also we conditionally display new Date() (I used &lt;code&gt;.toUTCString()&lt;/code&gt; here just to have both dates to look similar, it's not really needed). &lt;/p&gt;

&lt;p&gt;Without &lt;code&gt;{#if}&lt;/code&gt; you'd get one date built-in HTML (displayed immediately when page loaded) and other date will overwrite it. Not nice visual effect. With &lt;code&gt;{#if}&lt;/code&gt; we suppress first date and display only CSR date over empty page space.&lt;/p&gt;

&lt;p&gt;Using this method you can combine benefits for static and client-side rendered content at any SvelteKit page.&lt;/p&gt;

</description>
      <category>hackathon</category>
      <category>glsl</category>
      <category>blockchain</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Shell oneliner to generate passwords</title>
      <dc:creator>Yaroslav Polyakov</dc:creator>
      <pubDate>Thu, 12 Jan 2023 10:38:19 +0000</pubDate>
      <link>https://dev.to/yaroslaff/shell-oneliner-to-generate-passwords-47i8</link>
      <guid>https://dev.to/yaroslaff/shell-oneliner-to-generate-passwords-47i8</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 10 character random string from specified alphabet&lt;/span&gt;
&amp;lt; /dev/urandom &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-dc&lt;/span&gt; &lt;span class="s1"&gt;'[:graph:]'&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-c10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bash allows redirections at any part of command, so &lt;code&gt;&amp;lt; file command args&lt;/code&gt; above is same as &lt;code&gt;command args &amp;lt; file&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;KrvJz?TgbO
T[7/9Lg9L9
bp[je2Og*l
93:m_Ss$z5
C}Z=-Nj-mn
mG&amp;lt;85C&amp;gt;!i~
%&amp;gt;7/]AWpMd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you do not want so many special characters, you may use something like: &lt;code&gt;'[:alnum:]_$#%-'&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;JCPHawXEvr
orq#0S7cUk
82H7g_cHtY
um-#ACmny4
dYQFqGsX_d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>discuss</category>
      <category>gratitude</category>
    </item>
    <item>
      <title>Drop [almost] all outbound mail in postfix for tests</title>
      <dc:creator>Yaroslav Polyakov</dc:creator>
      <pubDate>Thu, 12 Jan 2023 10:04:40 +0000</pubDate>
      <link>https://dev.to/yaroslaff/drop-almost-all-outbound-mail-in-postfix-for-tests-3onh</link>
      <guid>https://dev.to/yaroslaff/drop-almost-all-outbound-mail-in-postfix-for-tests-3onh</guid>
      <description>&lt;h2&gt;
  
  
  Why to drop mail?
&lt;/h2&gt;

&lt;p&gt;While troubleshooting mailman installation, I've come to a problem: I need to do many tests, but I do not want to disturb recipients of maillist with dozens of test messages. I do not know, if mailman3 has any feature for this kind of testing, but postfix has. &lt;/p&gt;

&lt;h2&gt;
  
  
  How to drop postfix mail except to whitelisted addresses
&lt;/h2&gt;

&lt;p&gt;First, make sure, you have transport map enabled.&lt;/p&gt;

&lt;p&gt;Usually, this line could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;transport_maps = hash:/etc/postfix/transport
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, create other transport file, my /etc/postfix/blackhole:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mydomain.net :
mymailbox@gmail.com :
* discard:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this config postfix will deliver to *@mydomain.net and to &lt;a href="mailto:mymailbox@gmail.com"&gt;mymailbox@gmail.com&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;run &lt;code&gt;postmap blackhole&lt;/code&gt; to generate /etc/postfix/blackhole.db.&lt;/p&gt;

&lt;p&gt;add it to postfix transport with comma (if you already has transport map):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;transport_maps = hash:/path/to/other/transport/map, hash:/etc/postfix/blackhole
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(or as single element, if you had no transport_maps).&lt;/p&gt;

&lt;p&gt;Restart postfix: &lt;code&gt;postfix reload&lt;/code&gt;. You're ready.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;p&gt;I sent few mails  and here is what I have in logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Jan 12 09:53:17 list2 postfix/smtp[62239]: DB97418C0808: to=&amp;lt;mymailbox@gmail.com&amp;gt;, relay=gmail-smtp-in.l.google.com[173.194.76.27]:25, delay=0.41, delays=0.03/0.02/0.14/0.22, dsn=2.0.0, status=sent (250 2.0.0 OK  1673517197 g15-20020a056000118f00b002bdd88acc3dsi514695wrx.503 - gsmtp)

Jan 12 09:53:34 list2 postfix/discard[62251]: 7943118C0808: to=&amp;lt;test@test.com&amp;gt;, relay=none, delay=0.02, delays=0.02/0/0/0, dsn=2.0.0, status=sent (test.com)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First is log line for real delivery (&lt;code&gt;relay=&lt;/code&gt; remote mailserver) and second is log line for blackhole delivery, &lt;code&gt;relay=none&lt;/code&gt;).&lt;/p&gt;

</description>
      <category>tooling</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to get country by IP address</title>
      <dc:creator>Yaroslav Polyakov</dc:creator>
      <pubDate>Mon, 09 Jan 2023 11:59:49 +0000</pubDate>
      <link>https://dev.to/yaroslaff/how-to-get-country-by-ip-address-3o48</link>
      <guid>https://dev.to/yaroslaff/how-to-get-country-by-ip-address-3o48</guid>
      <description>&lt;p&gt;&lt;a href="https://ipdeny.com/" rel="noopener noreferrer"&gt;ipdeny.com&lt;/a&gt; provides nice free service for this. Download &lt;a href="https://www.ipdeny.com/ipblocks/" rel="noopener noreferrer"&gt;country block&lt;/a&gt; for any country you want and use it in your code.&lt;/p&gt;

&lt;p&gt;country block is simple CIDR list, e.g. for Afghanistan it starts with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;23.88.192.0/19
43.230.209.0/24
43.250.136.0/22
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>geolocation</category>
      <category>country</category>
      <category>ip</category>
    </item>
    <item>
      <title>Every C program has main()? (False)</title>
      <dc:creator>Yaroslav Polyakov</dc:creator>
      <pubDate>Wed, 04 Jan 2023 22:09:28 +0000</pubDate>
      <link>https://dev.to/yaroslaff/every-c-program-has-mainfalse-2g0a</link>
      <guid>https://dev.to/yaroslaff/every-c-program-has-mainfalse-2g0a</guid>
      <description>&lt;p&gt;actually, &lt;code&gt;_start&lt;/code&gt; is real magic word.&lt;/p&gt;

&lt;p&gt;nomain.c:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;_exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;register&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello world!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;_exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gcc &lt;span class="nt"&gt;-o&lt;/span&gt; nomain nomain.c &lt;span class="nt"&gt;-nostartfiles&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;./nomain 
Hello world!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>beginners</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>apt-file: which deb package to install to get X?</title>
      <dc:creator>Yaroslav Polyakov</dc:creator>
      <pubDate>Wed, 04 Jan 2023 09:05:29 +0000</pubDate>
      <link>https://dev.to/yaroslaff/apt-file-which-deb-package-to-install-to-get-x-41ck</link>
      <guid>https://dev.to/yaroslaff/apt-file-which-deb-package-to-install-to-get-x-41ck</guid>
      <description>&lt;p&gt;You need to get file X (e.g. hugo), what package to install?&lt;/p&gt;

&lt;p&gt;Long time ago, I got used to visit &lt;a href="https://packages.debian.org/" rel="noopener noreferrer"&gt;packages.debian.org&lt;/a&gt;, scroll down to second search form "Search the contents of packages" and search there.&lt;/p&gt;

&lt;p&gt;It's much easier to search with apt-file right from CLI:&lt;br&gt;
Install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;apt-file
apt-file update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now search:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ apt-file search hugo
fish-common: /usr/share/fish/completions/hugo.fish
gargoyle-free: /usr/lib/gargoyle/hugo
hugo: /usr/bin/hugo
hugo: /usr/share/bash-completion/completions/hugo
hugo: /usr/share/doc/hugo/changelog.Debian.amd64.gz
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but if we will search for 'gcc', we will find 170000+ results because apt-find looks for substring match. (and 30k results for 'mc' substring). We should use &lt;code&gt;-x&lt;/code&gt;/&lt;code&gt;--regexp&lt;/code&gt; search:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ apt-file -x search bin/gcc$
gcc: /usr/bin/gcc                         
icecc: /usr/lib/icecc/bin/gcc
nvidia-cuda-toolkit: /usr/lib/nvidia-cuda-toolkit/bin/gcc
pentium-builder: /usr/bin/gcc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>emptystring</category>
    </item>
    <item>
      <title>fail2ban regex works as CLI param, but not as file (Solution)</title>
      <dc:creator>Yaroslav Polyakov</dc:creator>
      <pubDate>Sun, 01 Jan 2023 15:29:05 +0000</pubDate>
      <link>https://dev.to/yaroslaff/fail2ban-regex-works-as-cli-param-but-not-as-file-solution-1bm7</link>
      <guid>https://dev.to/yaroslaff/fail2ban-regex-works-as-cli-param-but-not-as-file-solution-1bm7</guid>
      <description>&lt;p&gt;When writing new fail2ban filter, I see my regexes are working well in CLI test, but not from filter.d file.&lt;/p&gt;

&lt;p&gt;Running from CLI (success):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;root@liste:/etc/fail2ban/filter.d# fail2ban-regex /var/log/apache2/access_log &lt;span class="s1"&gt;'&amp;lt;HOST&amp;gt;.*/cgi-bin/mailman/subscribe/.*'&lt;/span&gt;

Running tests
&lt;span class="o"&gt;=============&lt;/span&gt;

Use   failregex line : &amp;lt;HOST&amp;gt;.&lt;span class="k"&gt;*&lt;/span&gt;/cgi-bin/mailman/subscribe/.&lt;span class="k"&gt;*&lt;/span&gt;
Use         log file : /var/log/apache2/access_log
Use         encoding : UTF-8


Results
&lt;span class="o"&gt;=======&lt;/span&gt;

Failregex: 7530 total
|-  &lt;span class="c"&gt;#) [# of hits] regular expression&lt;/span&gt;
|   1&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;7530] &amp;lt;HOST&amp;gt;.&lt;span class="k"&gt;*&lt;/span&gt;/cgi-bin/mailman/subscribe/.&lt;span class="k"&gt;*&lt;/span&gt;
&lt;span class="sb"&gt;`&lt;/span&gt;-

Ignoreregex: 0 total

Date template hits:
|- &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="c"&gt;# of hits] date format&lt;/span&gt;
|  &lt;span class="o"&gt;[&lt;/span&gt;7796] Day&lt;span class="o"&gt;(&lt;/span&gt;?P&amp;lt;_sep&amp;gt;[-/]&lt;span class="o"&gt;)&lt;/span&gt;MON&lt;span class="o"&gt;(&lt;/span&gt;?P&lt;span class="o"&gt;=&lt;/span&gt;_sep&lt;span class="o"&gt;)&lt;/span&gt;ExYear[ :]?24hour:Minute:Second&lt;span class="o"&gt;(&lt;/span&gt;?:&lt;span class="se"&gt;\.&lt;/span&gt;Microseconds&lt;span class="o"&gt;)&lt;/span&gt;?&lt;span class="o"&gt;(&lt;/span&gt;?: Zone offset&lt;span class="o"&gt;)&lt;/span&gt;?
&lt;span class="sb"&gt;`&lt;/span&gt;-

Lines: 7796 lines, 0 ignored, 7530 matched, 266 missed
&lt;span class="o"&gt;[&lt;/span&gt;processed &lt;span class="k"&gt;in &lt;/span&gt;1.68 sec]

Missed line&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt;: too many to print.  Use &lt;span class="nt"&gt;--print-all-missed&lt;/span&gt; to print all 266 lines
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;7.5K matched. Great! now, put this regex into file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[INCLUDES]
before = common.conf
[Definition]
failregex = &amp;lt;HOST&amp;gt;.*/cgi-bin/mailman/subscribe/.*
ignoreregex =
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And.... 0 matched! :-(&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;root@liste:/etc/fail2ban/filter.d# fail2ban-regex /var/log/apache2/access_log /etc/fail2ban/filter.d/mailman-subscribe.conf 
...
Lines: 7796 lines, 0 ignored, 0 matched, 7796 missed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Solution: just add empty &lt;code&gt;datepattern =&lt;/code&gt; to rule.&lt;/p&gt;

&lt;p&gt;And now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;root@liste:/etc/fail2ban/filter.d# fail2ban-regex /var/log/apache2/access_log /etc/fail2ban/filter.d/mailman-subscribe.conf 
...
Lines: 7796 lines, 0 ignored, 7530 matched, 266 missed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>security</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
