diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 000000000..42cd73d95 --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/vendor/ \ No newline at end of file diff --git a/app/app/BracesChecker.php b/app/app/BracesChecker.php new file mode 100644 index 000000000..7fec9f6fc --- /dev/null +++ b/app/app/BracesChecker.php @@ -0,0 +1,52 @@ +handle($braces[$i])) { + return false; + } + } + return !$this->hasBraces(); + } + + private function handle(string $brace): bool + { + if ($brace === ')') { + return $this->removeBrace(); + } + $this->addBrace(); + return true; + } + + private function removeBrace(): bool + { + if (!$this->hasBraces()) { + return false; + } + array_pop($this->braces); + return true; + } + + private function addBrace(): void + { + $this->braces[] = ')'; + } + + private function hasBraces(): bool + { + return count($this->braces) > 0; + } +} diff --git a/app/app/Request.php b/app/app/Request.php new file mode 100644 index 000000000..6ebe32ece --- /dev/null +++ b/app/app/Request.php @@ -0,0 +1,21 @@ +post = $_POST; + } + + public function get(string $key, string $default = ''): string + { + $value = $this->post[$key] ?? null; + return is_string($value) ? $value : $default; + } +} diff --git a/app/app/Response.php b/app/app/Response.php new file mode 100644 index 000000000..a5a88ca88 --- /dev/null +++ b/app/app/Response.php @@ -0,0 +1,38 @@ +initSuccess(); + } else { + $this->initError(); + } + } + + public function send(): string + { + header($this->header); + return $this->message; + } + + private function initSuccess(): void + { + $this->header = 'HTTP/1.1 200 OK'; + $this->message = 'OK'; + } + + private function initError(): void + { + $this->header = 'HTTP/1.1 400 Bad request'; + $this->message = 'Incorrect string'; + } +} diff --git a/app/composer.json b/app/composer.json new file mode 100644 index 000000000..fcd4f5119 --- /dev/null +++ b/app/composer.json @@ -0,0 +1,23 @@ +{ + "name": "rmulyukov/hw4", + "type": "project", + "authors": [ + { + "name": "Mulyukov Rustyam" + } + ], + "autoload": { + "psr-4": { + "Rmulyukov\\Hw4\\": "app/" + } + }, + "config": { + "platform": { + "php": "8.2" + } + }, + "require": { + "php":"^8.2", + "ext-memcache": "*" + } +} diff --git a/app/composer.lock b/app/composer.lock new file mode 100644 index 000000000..13c60c9e6 --- /dev/null +++ b/app/composer.lock @@ -0,0 +1,23 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "af6946a056ec0c28269adbf6afce8d2c", + "packages": [], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^8.2" + }, + "platform-dev": [], + "platform-overrides": { + "php": "8.2" + }, + "plugin-api-version": "2.6.0" +} diff --git a/app/public/index.php b/app/public/index.php new file mode 100644 index 000000000..dc22e8a2a --- /dev/null +++ b/app/public/index.php @@ -0,0 +1,13 @@ +get('string'); +$isCorrectString = (new BracesChecker())->check($string); +echo (new Response($isCorrectString))->send(); diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..8f7b324a3 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,68 @@ +version: '3.9' + +services: + nginx-proxy: + container_name: proxy-hw4 + hostname: proxy-hw4 + build: + context: ./docker + dockerfile: proxy-nginx/Dockerfile + ports: + - "8080:80" + networks: + - hw4-network + + nginx-balancer1: + container_name: balancer1-hw4 + hostname: balancer1-hw4 + build: + context: ./docker + dockerfile: balancer-nginx/Dockerfile + volumes: + - ./app:/hw4/app + networks: + - hw4-network + + nginx-balancer2: + container_name: balancer2-hw4 + hostname: balancer2-hw4 + build: + context: ./docker + dockerfile: balancer-nginx/Dockerfile + volumes: + - ./app:/hw4/app + networks: + - hw4-network + + php1: + container_name: php1-hw4 + hostname: php1-hw4 + build: + context: ./docker + dockerfile: php/Dockerfile + volumes: + - ./app:/hw4/app + networks: + - hw4-network + + php2: + container_name: php2-hw4 + hostname: php2-hw4 + build: + context: ./docker + dockerfile: php/Dockerfile + volumes: + - ./app:/hw4/app + networks: + - hw4-network + + memcache: + container_name: memcache-hw4 + hostname: memcache-hw4 + image: memcached:1.6.23-alpine + networks: + - hw4-network + +networks: + hw4-network: + driver: bridge \ No newline at end of file diff --git a/docker/balancer-nginx/Dockerfile b/docker/balancer-nginx/Dockerfile new file mode 100644 index 000000000..9a78728ca --- /dev/null +++ b/docker/balancer-nginx/Dockerfile @@ -0,0 +1,5 @@ +FROM nginx:1.25.0-alpine + +COPY ./balancer-nginx/conf.d /etc/nginx/conf.d + +WORKDIR /hw4/app \ No newline at end of file diff --git a/docker/balancer-nginx/conf.d/default.conf b/docker/balancer-nginx/conf.d/default.conf new file mode 100644 index 000000000..b12ac3178 --- /dev/null +++ b/docker/balancer-nginx/conf.d/default.conf @@ -0,0 +1,26 @@ +upstream php { + server php1-hw4:9000; + server php2-hw4:9000; +} + +server { + index index.php; + root /hw4/app/public; + + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location ~ \.php$ { + try_files $uri =404; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass php; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } + + location ~/\.ht { + deny all; + } +} \ No newline at end of file diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile new file mode 100644 index 000000000..dd6ad6d25 --- /dev/null +++ b/docker/php/Dockerfile @@ -0,0 +1,16 @@ +FROM php:8.2-fpm-alpine + +RUN apk update && apk add --no-cache --virtual .build-temp-deps \ + autoconf make gcc g++ zlib-dev \ + && apk update && apk add --no-cache libmemcached-dev \ + #memcache + && pecl install memcache \ + && docker-php-ext-enable memcache \ + #composer + && curl -sS https://getcomposer.org/installer | php -- --install-dir=/bin --filename=composer --quiet \ + && rm -rf /root/.composer/cache \ + && apk del --no-cache -f .build-temp-deps + +COPY ./php/conf.d /usr/local/etc/php/conf.d + +WORKDIR /hw4/app \ No newline at end of file diff --git a/docker/php/conf.d/session.ini b/docker/php/conf.d/session.ini new file mode 100644 index 000000000..479651ed4 --- /dev/null +++ b/docker/php/conf.d/session.ini @@ -0,0 +1,2 @@ +session.save_handler = memcached +session.save_path = "memcached:11211" \ No newline at end of file diff --git a/docker/proxy-nginx/Dockerfile b/docker/proxy-nginx/Dockerfile new file mode 100644 index 000000000..f07d7a08c --- /dev/null +++ b/docker/proxy-nginx/Dockerfile @@ -0,0 +1,3 @@ +FROM nginx:1.25.0-alpine + +COPY ./proxy-nginx/conf.d /etc/nginx/conf.d \ No newline at end of file diff --git a/docker/proxy-nginx/conf.d/default.conf b/docker/proxy-nginx/conf.d/default.conf new file mode 100644 index 000000000..b82019e63 --- /dev/null +++ b/docker/proxy-nginx/conf.d/default.conf @@ -0,0 +1,17 @@ +upstream nginx-balancers { + least_conn; + server balancer1-hw4:80; + server balancer2-hw4:80; +} + +server { + listen 80; + + location / { + proxy_pass http://nginx-balancers; + } + + location ~/\.ht { + deny all; + } +} \ No newline at end of file