雑記

中古PCを児童養護施設へ寄贈

サブのマシンとして使用していたノートPC(MacBook Air 2019)1台を都内の児童養護施設へ寄贈しました。開発で使うことは難しいのですが,事務用PCあるいは学習用PCとしては十分に使用可能ですし,購入後3年未満でApple Care+も有効な状態ですから,役に立てて頂ければ幸いです。

雑記

低レベルWebサーバ

WebAPI試験用のモックを作るついでに,Socketを使った低レベルのWebサーバをPythonで作りました。http://localhost:8080/*.htmlでアクセスするとindex.htmlファイルを返して,それ以外はNot Found(404)を返します。またhttp://localhost:8080/quitをリクエストするとサーバが停止します。

※セキュリティに関しては一切考慮していないので,インターネット公開するサーバでは実行しないでください。ディレクトリトラバーサルは簡単に実行できるでしょう。脆弱サーバの実験用です。

import re
import time
import socket

HOST = '127.0.0.1'
PORT = 8080
BUFFER_SIZE = 4096

def main():
  print("Server Listening")
  while True:
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
      sock.bind((HOST, PORT))
      sock.listen(2)
      sock.settimeout(10)
      connection = None
      try:
        connection, address = sock.accept()
        print("connection from {} has been established!".format(address))
        recv = connection.recv(BUFFER_SIZE)
        print(recv)
        data = parse(recv.decode('UTF-8'))
        if data['url'] == '/quit':
          break
        response = create_response(data)
        print(response)
        connection.send(response.encode('UTF-8'))
      except TimeoutError as e:
        continue
      except Exception as e:
        print(str(e))
        response = format_response(500, "Internal Server Error", "text/plain",  str(e))
        if connection:
          connection.send(response.encode('UTF-8'))
      finally:
        if connection:
          connection.shutdown(socket.SHUT_RDWR)
          connection.close()
        time.sleep(1)

def parse(recv):
  array = recv.splitlines()
  data = {}
  if len(array) > 0:
    m = re.match(r'(GET|POST|PATCH|PUT|DELETE|HEAD)\s+(.*)\s+(.*)', array[0])
    if m:
      data['method'] = m.group(1)
      data['url'] = m.group(2)
      data['payload'] = array[len(array) - 1]
  return data


def create_response(data):
  if re.match(r'.*\.html', data['url']):
    with open('index.html', 'r', encoding='utf-8') as f:
      body = f.read()
      return format_response(200, "OK", "text/html; charset=utf-8", body)
  return format_response(404, "Not Found", "text/plain", "{} Not Found".format(data['url']))

def format_response(code, status, type, body):
  response = "HTTP/1.0 {} {}\nContent-Type: {}\n\n{}\n"
  return response.format(code, status, type, body);

if __name__ == '__main__':
  main()

簡単なhtmlファイルを置いて実行してみます。

<!DOCTYPE html>
<html lang="ja">
<head>
	<title>Hello</title>
</head>
<body>
	<h1>Hello World</h1>
</body>
</html>

Server Listening
connection from (‘127.0.0.1’, 55843) has been established!
b’GET /aaa.html HTTP/1.1\r\nHost: localhost:8080\r\nConnection: keep-alive\r\nsec-ch-ua: ” Not A;Brand”;v=”99″, “Chromium”;v=”101″, “Opera”;v=”87″\r\nsec-ch-ua-mobile: ?0\r\nsec-ch-ua-platform: “Windows”\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36 OPR/87.0.4390.45\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\nSec-Fetch-Site: none\r\nSec-Fetch-Mode: navigate\r\nSec-Fetch-User: ?1\r\nSec-Fetch-Dest: document\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: ja,en-US;q=0.9,en;q=0.8\r\n\r\n’
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8

<!DOCTYPE html>
<html lang=”ja”>
<head>
<title>Hello</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>


connection from (‘127.0.0.1’, 55848) has been established!
b’GET /favicon.ico HTTP/1.1\r\nHost: localhost:8080\r\nConnection: keep-alive\r\nsec-ch-ua: ” Not A;Brand”;v=”99″, “Chromium”;v=”101″, “Opera”;v=”87″\r\nsec-ch-ua-mobile: ?0\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36 OPR/87.0.4390.45\r\nsec-ch-ua-platform: “Windows”\r\nAccept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8\r\nSec-Fetch-Site: same-origin\r\nSec-Fetch-Mode: no-cors\r\nSec-Fetch-Dest: image\r\nReferer: http://localhost:8080/aaa.html\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: ja,en-US;q=0.9,en;q=0.8\r\n\r\n’
HTTP/1.0 404 Not Found
Content-Type: text/plain

/favicon.ico Not Found

雑記

ウクライナ軍支援

ウクライナ軍をサポートしているNGOへ寄付することができました。先日Patron経由で送金したものの,Patronの規約に違反するとしてアカウントが削除されてしまったようです(注1)。”TO CONTRIBUTE”というボタンから直接送金しようとしましたが,クレカの追加認証が通りませんでした。そこで,FONDYから送金してみたところ,ようやく送金できました。

https://savelife.in.ua/en/donate/


まずは上のURLへアクセスします。図の赤枠で囲んであるFondy.euというリンクをクリックします。

画面が表示されたら,右上のセレクトボックスで言語を選択します。日本語は選択肢にないので,英語を選びましょう。

英語の表示になったらクレジットカード情報とメールアドレス,金額を入力してCHECKOUTボタンを押します。2月25日のレートで1UAH = 3.8946JPYでした。


カード会社によっては追加の認証が入ります。成功するとPayment is approvedと表示されます。

注1)https://www.businessinsider.in/politics/world/news/patreon-took-down-an-account-run-by-one-of-ukraines-biggest-charitable-foundations-because-the-organization-uses-donations-to-supply-equipment-for-the-countrys-military/articleshow/89839104.cms


雑記

所得税確定申告

今日から所得税の確定申告が始まりました。早速e-taxでマイナンバーカードを使って申告を行い,PayEasyで納付しました。自宅からすべてできるのはありがたいです。

雑記

物理メモリ故障

メインで使っているLenovo製PCのメモリが故障しました。有償保守契約があったので修理工場に「入院」して検査をしてもらったところ,2枚装填されているメモリのうちの1枚が故障しているということでした。メモリも購入後3年間の保証がついているものだったので,交換部品を送ってもらうことになりました。

雑記

産業廃棄物処理

10年ほど使ったレーザー複合機をリプレースしたので,古いものを処分しました。「産業廃棄物」に該当するため,自治体では改修してくれず,産廃業者に依頼しました。モノクロレーザ複合機を家庭用して使っていたと主張するのは無理がありますから仕方がありません。産業廃棄物処理はルールが厳しく,厳格に管理されています。マニフェストという書類を業者間で受け渡していくようです。