Тренировка создание echo сервера на bash

This commit is contained in:
Виталий Туров 2024-11-28 21:12:50 +03:00
parent a568e6bb38
commit 6b73f03ffc
6 changed files with 148 additions and 0 deletions

4
bash/rest/404.html Normal file
View File

@ -0,0 +1,4 @@
HTTP/1.1 404 NotFound
Content-Type: text/html
<h1>Sorry, not found</h1>

48
bash/rest/home.html Normal file
View File

@ -0,0 +1,48 @@
HTTP/1.1 200 OK
Content-Type: text/html
<!DOCTYPE html>
<html>
<head>
<style>
section {
display: inline-block;
margin-left: 40%;
margin-top: 10%;
}
section p {
color: black;
}
</style>
</head>
<body>
<section>
<p>Hello, {{name}}</p>
<form method="POST" action="/logout">
<input type="submit" value="Logout" />
</form>
<a href="javascript:void(0)">Blue theme</a>
</section>
</body>
<footer>
<script>
let themeElem = document.querySelector('a');
let nameElem = document.querySelector('section > p');
themeElem.addEventListener('click', function(evt) {
if (nameElem.style.color == 'blue') {
nameElem.style.color = 'black';
themeElem.text = 'Blue theme';
} else {
nameElem.style.color = 'blue';
themeElem.text = 'Black theme';
}
})
</script>
</footer>
</html>

7
bash/rest/login.html Normal file
View File

@ -0,0 +1,7 @@
HTTP/1.1 200 OK
Content-Type: text/html
<form method="POST" action="/login">
<input type="text" name="name" />
<input type="submit" value="Login" />
</form>

View File

@ -0,0 +1,3 @@
HTTP/1.1 301
Location: http://localhost:3000/
Set-Cookie: {{cookie_name}}={{cookie_value}}; path=/; HttpOnly

View File

@ -0,0 +1,3 @@
HTTP/1.1 301
Location: http://localhost:3000/login
Set-Cookie: {{cookie_name}}={{cookie_value}}; path=/; HttpOnly; Expires=Thu, 01 Jan 1970 00:00:00 GMT

83
bash/rest/server.bash Executable file
View File

@ -0,0 +1,83 @@
#!/bin/bash
### Create the response FIFO
rm -f response
mkfifo response
function handle_GET_home() {
RESPONSE=$(cat home.html |
sed "s/{{$COOKIE_NAME}}/$COOKIE_VALUE/")
}
function handle_GET_login() {
RESPONSE=$(cat login.html)
}
function handle_POST_login() {
RESPONSE=$(cat post-login.http |
sed "s/{{cookie_name}}/$INPUT_NAME/" |
sed "s/{{cookie_value}}/$INPUT_VALUE/")
}
function handle_POST_logout() {
RESPONSE=$(cat post-logout.http |
sed "s/{{cookie_name}}/$COOKIE_NAME/" |
sed "s/{{cookie_value}}/$COOKIE_VALUE/")
}
function handle_not_found() {
RESPONSE=$(cat 404.html)
}
function handleRequest() {
## Read request
while read line; do
echo $line
trline=$(echo $line | tr -d '[\r\n]')
[ -z "$trline" ] && break
HEADLINE_REGEX='(.*?)\s(.*?)\sHTTP.*?'
[[ "$trline" =~ $HEADLINE_REGEX ]] &&
REQUEST=$(echo $trline | sed -E "s/$HEADLINE_REGEX/\1 \2/")
CONTENT_LENGTH_REGEX='Content-Length:\s(.*?)'
[[ "$trline" =~ $CONTENT_LENGTH_REGEX ]] &&
CONTENT_LENGTH=$(echo $trline | sed -E "s/$CONTENT_LENGTH_REGEX/\1/")
COOKIE_REGEX='Cookie:\s(.*?)\=(.*?).*?'
[[ "$trline" =~ $COOKIE_REGEX ]] &&
read COOKIE_NAME COOKIE_VALUE <<<$(echo $trline | sed -E "s/$COOKIE_REGEX/\1 \2/")
done
## Read body
if [ ! -z "$CONTENT_LENGTH" ]; then
BODY_REGEX='(.*?)=(.*?)'
while read -n$CONTENT_LENGTH -t1 line; do
echo $line
trline=$(echo $line | tr -d '[\r\n]')
[ -z "$trline" ] && break
read INPUT_NAME INPUT_VALUE <<<$(echo $trline | sed -E "s/$BODY_REGEX/\1 \2/")
done
fi
## Route to the response handlers
case "$REQUEST" in
"GET /login") handle_GET_login ;;
"GET /") handle_GET_home ;;
"POST /login") handle_POST_login ;;
"POST /logout") handle_POST_logout ;;
*) handle_not_found ;;
esac
echo -e "$RESPONSE" >response
}
echo 'Listening on 3000...'
while true; do
cat response | nc -lN 3000 | handleRequest
done