2022-07-12
🤿 Diving Deeper Into The Web Environment
I was having some tasks related to deploying different web-applications on linux os like python(django/flask), php(laravel), java(spring) and dotnetcore. I was blindly following some tutorials to get the things up and running. after reviewing some basic concepts I thoghut it will be good to share this video. I will try to discuss some concepts that will lead to a deeper unnderstanding of the web environment.
Youtube Link Diving Deeper Into The Web Environment
Now, I'm preparing this content while listening to this calm and peaceful voice ... happy reading 😊
Diagrams:
Agenda

Processes / Threads / CPU scheduler

Terminal Device

Terminal Emulator

Standard Streams [stdin, stdout, stderr] / Stream Redirection

Pipes

Socket Communication Domains

Sockets API

Static Pages

Common Gateway Interface

Nginx / WSGI Server / WSGI Application / Python

Nginx / PHP-FPM / PHP

Code Examples:
Files
🤖 Discovering the files in unix
sudo evtest
# Available devices:
# /dev/input/event0: Lid Switch
# /dev/input/event1: Power Button
# /dev/input/event2: Sleep Button
# /dev/input/event3: Power Button
# /dev/input/event4: AT Translated Set 2 keyboard
# /dev/input/event5: AlpsPS/2 ALPS DualPoint Stick
# /dev/input/event6: AlpsPS/2 ALPS DualPoint TouchPad
# /dev/input/event7: ST LIS3LV02DL Accelerometer
# /dev/input/event8: Dell WMI hotkeys
# /dev/input/event9: Laptop_Integrated_Webcam_HD: In
# /dev/input/event10: HDA Intel PCH Dock Mic
# /dev/input/event11: HDA Intel PCH Dock Line Out
# /dev/input/event12: HDA Intel PCH Front Headphone
# /dev/input/event13: Video Bus
# /dev/input/event14: Video Bus
# /dev/input/event15: HDA Intel HDMI HDMI/DP,pcm=3
# /dev/input/event16: HDA Intel HDMI HDMI/DP,pcm=7
# /dev/input/event17: HDA Intel HDMI HDMI/DP,pcm=8
# /dev/input/event18: HDA Intel HDMI HDMI/DP,pcm=9
# /dev/input/event19: HDA Intel HDMI HDMI/DP,pcm=10
sudo cat /dev/input/event6 # TouchPad character device file
# K��bb�9 K��bb�5��hK���#K���K���5K���6cK���K
# ���cK���$K���K��b�5 K��b�6hK��b�
# K��b�hK��b�%K��b�K��b$�5K��b$�K��b$� K��b$�K��b�#'K�
# 5K��b��6mK��b��Z�^C
ls -al /dev/input
# total 0
# drwxr-xr-x 2 root root 60 Jul 12 19:08 by-id
# drwxr-xr-x 2 root root 160 Jul 12 19:08 by-path
# crw-rw---- 1 root input 13, 64 Jul 12 19:08 event0
# crw-rw---- 1 root input 13, 65 Jul 12 19:08 event1
# crw-rw---- 1 root input 13, 66 Jul 12 19:08 event2
# crw-rw---- 1 root input 13, 67 Jul 12 19:08 event3
# crw-rw---- 1 root input 13, 68 Jul 12 19:08 event4
# crw-rw---- 1 root input 13, 69 Jul 12 19:08 event5
# crw-rw---- 1 root input 13, 70 Jul 12 19:08 event6
# crw-rw-r-- 1 root input 13, 0 Jul 12 19:08 js0
# crw-rw---- 1 root input 13, 63 Jul 12 19:08 mice
# crw-rw---- 1 root input 13, 32 Jul 12 19:08 mouse0
# crw-rw---- 1 root input 13, 33 Jul 12 19:08 mouse1
Standard Streams
🤖 counter.py
import time
for index in range(1000):
print(index, flush=True)
time.sleep(1)
🤖 Discovering Standard Streams
python counter.py
# 0
# 1
# 2
# 3
# ..
ls -al /proc/648820/fd
# total 0
# lrwx------ 1 me me 64 Jul 12 22:00 0 -> /dev/pts/5
# lrwx------ 1 me me 64 Jul 12 22:00 1 -> /dev/pts/5
# lrwx------ 1 me me 64 Jul 12 22:00 2 -> /dev/pts/5
# redirect:
# - stdout (file-discriptor=1) to log file
# - stderr (file-discriptor=2) to log-err file
python counter.py 1> log 2> err-log
tail -f log
# 0
# 1
# 2
# 3
# ..
tail -f err-log
# Traceback (most recent call last):
# File "/media/hard/abdelaziz/dev/projects/me/meta/socket/standard-streams/counter.py", line 5, in <module>
# time.sleep(1)
# KeyboardInterrupt
Pipes
unnamed pipes
🤖 sqrt.py
from math import sqrt
import os
print('========== PID: {pid} =========='.format(pid=os.getpid()))
# print sqrt each loop
while True:
number = input("> ")
if number == '':
break
print(sqrt(float(number)), flush=True)
🤖 Unnamed Pipes
python counter.py | python sqrt.py
========== PID: 678604 ==========
> 0.0
> 1.0
> 1.4142135623730951
named pipes
🤖 writer.py
import os
import io
print('========== PID: {pid} =========='.format(pid=os.getpid()))
# open the write end of the pipe
pipe_file_name = 'pipe'
if os.path.exists(pipe_file_name):
os.remove(pipe_file_name)
os.mkfifo(pipe_file_name)
pipe = io.open(pipe_file_name, 'w')
# start sending the messages
while True:
message = input("> ")
if len(message) == 0:
break
pipe.write(message + '\n')
pipe.flush()
🤖 reader.py
import os
import io
print('========== PID: {pid} =========='.format(pid=os.getpid()))
# open the read end of the pipe
pipe_file_name = 'pipe'
pipe = io.open(pipe_file_name, 'r')
# start receiving the messages
while True:
message = pipe.readline()[:-1]
if len(message) == 0:
break
print(f'received: {message}')
Signals
🤖 added code
import signal
import sys
def terminate_handler(*args):
print('salam')
sys.exit(0)
signal.signal(signal.SIGINT, terminate_handler)
Sockets
unix communication domain
🤖 server.py
import os
import socket
class Server:
""" delivering [🍗, 🍟, ☕] """
def __init__(self, client_socket_address, server_socket_address):
self.client_socket_address = client_socket_address
self.server_socket_address = server_socket_address
# remove the previous socket path
if os.path.exists(self.server_socket_address):
os.remove(self.server_socket_address)
self.server_socket = socket.socket(
family=socket.AF_UNIX,
type=socket.SOCK_DGRAM
)
self.server_socket.bind(self.server_socket_address)
def listen(self):
while True:
message = self.server_socket.recv(1024).decode()
if len(message) == 0:
self.server_socket.close()
break
print(f'making "{message}"')
self.send_response(message)
def send_response(self, message):
self.server_socket.connect(self.client_socket_address)
print(f'start delivering "{message}"')
self.server_socket.send(f'delivering "{message}"'.encode())
Server(
server_socket_address='./server.sock',
client_socket_address='./client.sock',
).listen()
🤖 client.py
import os
import socket
class Client:
""" order [🍗, 🍟, ☕] """
def __init__(self, client_socket_address, server_socket_address):
self.client_socket_address = client_socket_address
self.server_socket_address = server_socket_address
# remove the previous socket path
if os.path.exists(self.client_socket_address):
os.remove(self.client_socket_address)
self.client_socket = socket.socket(
family=socket.AF_UNIX,
type=socket.SOCK_DGRAM
)
self.client_socket.bind(self.client_socket_address)
def send_request(self):
self.client_socket.connect(self.server_socket_address)
while True:
message = input("> ")
self.client_socket.send(message.encode())
if len(message) == 0:
self.client_socket.close()
break
self.wait_response()
def wait_response(self):
message = self.client_socket.recv(1024).decode()
print(f'received that server is {message}')
Client(
server_socket_address='./server.sock',
client_socket_address='./client.sock',
).send_request()
internet communication domain
🤖 changed code
# using AF_INET address family
self.client_socket = socket.socket(
family=socket.AF_INET,
type=socket.SOCK_DGRAM
)
# address format
Client(
server_socket_address=('127.0.0.1', 9000),
client_socket_address=('127.0.0.1', 11000)
)