Тренировка создание echo сервера на bash
This commit is contained in:
parent
a568e6bb38
commit
6b73f03ffc
4
bash/rest/404.html
Normal file
4
bash/rest/404.html
Normal 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
48
bash/rest/home.html
Normal 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
7
bash/rest/login.html
Normal 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>
|
3
bash/rest/post-login.http
Normal file
3
bash/rest/post-login.http
Normal file
@ -0,0 +1,3 @@
|
||||
HTTP/1.1 301
|
||||
Location: http://localhost:3000/
|
||||
Set-Cookie: {{cookie_name}}={{cookie_value}}; path=/; HttpOnly
|
3
bash/rest/post-logout.http
Normal file
3
bash/rest/post-logout.http
Normal 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
83
bash/rest/server.bash
Executable 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
|
Loading…
Reference in New Issue
Block a user