lifeHi — I'm KhanhIceTea
Thinker, writer, ice-tea drinker.
Notes on tech, ideas, and life systems. Written slowly. Read on your phone, in bed, or with tea.
Recent writing
Tech · life · thinking
life
aiLearn Claude Prompt Engineering Course
Learn React Router v7 - part 1 : Routing
techServer Island in Web : behind the 'land'
techSame vendor fallback is pointless
lifeNo.1 Productivity Hack Of My Life
lifeGame of Life vs Life of Game
lifeAn
lifeBeing kind
lifeReady for 1%
lifeOver some-thing
lifeWe were born and died in same way, so live differently
Today I Learned
Short notes, kept as they land
#TIL : Storing master key inside MacOS keychain
Today, I read the source of Chromium, then see it implement the encryption data is so easy to understand.
Because all of encryption needs "THE KEY", so each security layer, it has to have the master key. Chromium has one to, all its encrypted data using the same master key, store inside the OS "keychain" (macOS keychain, Windows DAPI, ...). The first boot time, the app generate its master key, then next boot, it loads the key from Keychain and store in process memory, and use this key to encrypt and decrypt all the data it wants.
Then I checked the source and a bit suprise about the master key is only 128bits. I thought nowaday, at least 256 bits needed because computation powers. But I'm wrong, 128bits is safe enough this century (read this : https://hackernoon.com/is-128-bit-encryption-enough-cp2i3aoy )
#TIL : Run multiple AlpineJS inits and effects on same element
This trick allows you to run multiple init and effects using AlpineJS on same element
<div x-init x-init.1="console.log('click 1, a = ' + a)" x-init.2="console.log('click 2, b = ' + b)" x-effect.1="console.log('a is changed')" @click="a = 100" x-data.1='{"a":1, "b":3}' x-data.2='{"b":2}' x-text="'a = ' + a + ' , b = ' + b" > Hello world </div>Check this demo on JSBin : https://jsbin.com/vetunuhade/edit?html,js,console,output
#TIL : HTML Form no trigger submit when press Enter key on input
Long time ago, I think all form will submit on pressing Enter into any input element (mean it's default behavior of html form and you don't do anything with JS event handling)
Buttttt, today I just know that a form only submit when you pressing Enter IF the form has a SUBMIT button.
This form will not submit on Enter
<form action="abc.php" id="form1"> <input type="text" name="email"> <input type="text" name="username"> </form>And this won't to (because the button has type="button", not "submit")
<form action="abc.php" id="form1"> <input type="text" name="email"> <input type="text" name="username"> <button type="button" name="_action" value="hi">Hi</button> </form>This form will submit on Enter ( because default type of button is "submit" :D )
<form action="abc.php" id="form1"> <input type="text" name="email"> <input type="text" name="username"> <button name="_action" value="hi">Hi</button> </form>This form will submit on Enter ( and the "_action" field will be "hi", so the Enter key will trigger a virtual click on the first SUBMIT button in the form )
<form action="abc.php" id="form1"> <input type="text" name="email"> <input type="text" name="username"> <button name="_action" value="hi">Hi</button> <button name="_action" value="hello">Hello</button> </form>This form will submit on Enter ( and the "_action" field will be "hello", because the first submit button is Hello )
<form action="abc.php" id="form1"> <input type="text" name="email"> <input type="text" name="username"> <button type="button" name="_action" value="hi">Hi</button> <button name="_action" value="hello">Hello</button> </form>BONUS : This form will submit on Enter ;) haha
<form action="abc.php" id="form1"> <input type="text" name="email"> <input type="text" name="username"> </form> <button name="_action" value="hello" form="form1">Hello</button>This trick works even you hide the button (using css)
#TIL : Using Curl to check downtime and ssl cert expiration
Before I wrote a cron script to check website is down, but it can't check multiple endpoint and can't alert if ssl certificates is about to expired.
So, I created this bash snippet function to check multiple endpoints (and their SSL certificates)
#!/bin/bash function checkEndpoint() { URL="$1" FIND="$2" RESPONSE=$(curl -m 10 -s "$URL") CONTENT=$(echo $RESPONSE | grep "$FIND") if [ $? -ne 0 ]; then echo "Error: $URL same down. Please check!" return 1 fi # Check SSL certificate expiration HOST=$(echo "$URL" | sed -E 's|https?://([^/]+).*|\1|') EXPIRY_DATE=$(echo | openssl s_client -connect "$HOST:443" -servername "$HOST" 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2) EXPIRY_TIMESTAMP=$(date -d "$EXPIRY_DATE" +%s) CURRENT_TIMESTAMP=$(date +%s) DAYS_LEFT=$(( (EXPIRY_TIMESTAMP - CURRENT_TIMESTAMP) / 86400 )) if [ "$DAYS_LEFT" -le 7 ]; then echo "Error: $URL - SSL certificate will expire in $DAYS_LEFT days." return 1 fi return 0 } function checkAndAlert() { CHAT_ID="telegram_chat_id" BASIC_AUTH_BOT_PARAM="bot*****:*********" ALERT_MSG=$(checkEndpoint "$1" "$2") if [ $? -ne 0 ]; then curl -s -m 10 --get --data-urlencode "chat_id=$CHAT_ID" --data-urlencode "text=$ALERT_MSG" "https://api.telegram.org/$BASIC_AUTH_BOT_PARAM/sendMessage" return 1 fi } checkAndAlert "https://google.com/" "google" checkAndAlert "https://news.ycombinator.com" "Hacker News"#TIL : PHP memory allocation when passing arguments into function
In PHP, when you pass variables into another function arguments, it
- Copy the variable memory if the argument is scalar data type (int, float, bool, ...), because it's cheap operations
- Copy a
shadow clone jutsuvariable zval struct (24-32 bytes), then point the real data pointer of dynamically data type (array, string, $object)
Below testing will say more than me
<?php class A { public $arr; public function __construct() { $this->arr = array_fill(0, 10000, "Hello world"); } public function push(){ $this->arr[] = "ok"; } } function haha() { $a = func_get_args()[0]; mem("inside func haha, after func_get_args"); return $a; } function a($b, $c) { $a = new A(); $str = str_repeat("Helo", 100000); mem("after create an object A"); $x = haha($a, $str, $b, $c); mem("after call func_get_args"); $x->arr[] = "there"; var_dump($a->arr[count($a->arr) - 1]); var_dump($x->arr[count($x->arr) - 1]); $x->push(); var_dump($a->arr[count($a->arr) - 1]); var_dump($x->arr[count($x->arr) - 1]); mem("after modify arr property"); // var_dump($a === $x); return $b+$c; } function mem($msg = null) { if ($msg) print_r($msg . " : "); echo (memory_get_usage(false) . " bytes\n"); } mem("start"); var_dump(a(1,2)); mem("end");This is the result
start : 469464 bytes after create an object A : 1137200 bytes inside func haha, after func_get_args : 1137200 bytes after call func_get_args : 1137200 bytes string(5) "there" string(5) "there" string(2) "ok" string(2) "ok" after modify arr property : 1137200 bytes int(3) end : 469464 bytesSurprise ! :D