├── .github └── workflows │ ├── deploy-docs.yml │ ├── qa.yml │ ├── release.yml │ └── testing.yml ├── .gitignore ├── README.md ├── autumn-properties.json ├── docker ├── Dockerfile ├── app │ ├── StartWinow.os │ ├── autumn-properties.json │ ├── controls │ │ └── Индекс.os │ ├── files │ │ └── wine_and_acorns.jpg │ └── view │ │ ├── about.html │ │ ├── contact.html │ │ ├── index.html │ │ └── main.html ├── docker-entrypoint.sh └── start.sh ├── docs ├── hw1.png ├── hw10.png ├── hw11.png ├── hw12.png ├── hw2.png ├── hw3.png ├── hw4.png ├── hw5.png ├── hw6.png ├── hw7.png ├── hw8.png ├── hw9.png ├── product │ └── index.md ├── sse.gif ├── static │ ├── hw1.png │ ├── hw10.png │ ├── hw11.png │ ├── hw12.png │ ├── hw2.png │ ├── hw3.png │ ├── hw4.png │ ├── hw5.png │ ├── hw6.png │ ├── hw7.png │ ├── hw8.png │ ├── hw9.png │ ├── sse.gif │ └── ws-chat.gif └── ws-chat.gif ├── example ├── autumn-properties.json ├── hwapp │ ├── files │ │ ├── fun │ │ │ └── zl2.jpg │ │ └── zl1.jpg │ ├── view │ │ ├── chat.html │ │ ├── chatlogin.html │ │ ├── console.html │ │ ├── main.html │ │ ├── main_sse.html │ │ ├── printarray.html │ │ ├── result-form.html │ │ ├── send-form.html │ │ └── view1.html │ ├── ВебСокетЧат.os │ ├── ИнтерактивныйКонтролПриветствия.os │ ├── КонсольНаВебСокетах.os │ ├── КонтролВыключатель.os │ ├── КонтролМета.os │ ├── КонтролПолученияЖСОН.os │ ├── КонтролПриветствия.os │ ├── КонтролРаботаСОтображениям.os │ ├── КонтролСУправлениемДоступом.os │ ├── ОтправкаФайлов.os │ └── СерверныеСобытия.os └── ЗапускПримера.os ├── packagedef ├── sonar-project.properties ├── src └── Классы │ ├── АннотацияКонтроллер.os │ ├── АннотацияЛогВебСервера.os │ ├── БрокерСообщенийВебСокетов.os │ ├── БрокерСообщенийСобытийСервера.os │ ├── ВходящийЗапрос.os │ ├── ДанныеСоставнойФормы.os │ ├── ЗапускательВебПриложения.os │ ├── ИнициализацияЖелудейСервера.os │ ├── ИнициализацияНастроекСервера.os │ ├── КонструкторыПараметров.os │ ├── КонтрольСоединенийСерверныхСобытий.os │ ├── Кука.os │ ├── Куки.os │ ├── Маршрутизатор.os │ ├── МенеджерВходящихСоединений.os │ ├── МенеджерДоступа.os │ ├── МенеджерОтображений.os │ ├── МенеджерСессий.os │ ├── Настройки.os │ ├── НативныйВебСервер.os │ ├── ОбработчикЗапросов.os │ ├── ОбработчикСоединений.os │ ├── Ответ.os │ ├── ПарсерЗапросов.os │ ├── Парсеры.os │ ├── Перечисления.os │ ├── ПодготовительОтветов.os │ ├── ПодпискаНаВебСокет.os │ ├── ПодпискиСерверныхСобытий.os │ ├── ПрикладнойВебСервер.os │ ├── РегистраторКаталогаФайлов.os │ ├── СборщикМаршрутов.os │ ├── СерверноеСобытие.os │ ├── СессияПользователя.os │ ├── СлушательПорта.os │ ├── СоединенияВебСокетов.os │ ├── СоединенияСерверныхСобытий.os │ ├── ТопикиСерверныхСобытий.os │ ├── ФабрикаВебСерверов.os │ ├── ФабрикаОтветов.os │ ├── ХттпОтвет.os │ ├── Шаблон.os │ └── ШифрованиеВебСокета.os ├── tasks ├── coverage.os ├── oscript.cfg └── test.os ├── tests ├── alltest.os ├── app │ ├── files │ │ └── textfile.txt │ ├── view │ │ ├── 1.html │ │ ├── 2.html │ │ ├── 3.html │ │ └── main.html │ ├── КонтролВебСокета.os │ ├── КонтролССЕ.os │ ├── КонтролТестирования.os │ ├── КонтролТестированияОтображений.os │ ├── КорневойКонтрол.os │ └── ССЕКлиент.os ├── features │ ├── client1 │ ├── client2 │ ├── img.jpg │ ├── multipart-form-data │ ├── server1 │ └── server2 ├── mock │ ├── мокПередОбработкойОтображения.os │ ├── мокПослеОбработкиОтображения.os │ └── мокПослеОбработкиОтображения2.os ├── parser.os └── templateProcessor.os └── tools └── proxy.os /.github/workflows/deploy-docs.yml: -------------------------------------------------------------------------------- 1 | name: Публикация документации 2 | 3 | on: 4 | push: 5 | paths: 6 | - 'docs/**' 7 | branches: 8 | - 'master' 9 | workflow_dispatch: 10 | 11 | jobs: 12 | deploy-docs: 13 | uses: autumn-library/workflows/.github/workflows/deploy-docs.yml@main 14 | with: 15 | github_repository: autumn-library/winow 16 | secrets: inherit 17 | -------------------------------------------------------------------------------- /.github/workflows/qa.yml: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # Copyright (C) 2020 Tymko Oleg and contributors 3 | # All rights reserved. 4 | 5 | name: Контроль качества 6 | # Любой пуш и pr в проекте но с фильтром по основному проекту 7 | on: [push, pull_request] 8 | jobs: 9 | build: 10 | if: github.repository == 'autumn-library/winow' 11 | runs-on: ${{ matrix.os }} 12 | strategy: 13 | fail-fast: false 14 | matrix: 15 | os: [ubuntu-latest] 16 | oscript_version: ['stable'] 17 | 18 | steps: 19 | # Загрузка проекта 20 | - name: Актуализация 21 | uses: actions/checkout@v2 22 | 23 | # Вычисление имени ветки 24 | - name: Compute branch name 25 | uses: nelonoel/branch-name@v1.0.1 26 | 27 | # Установка OneScript конкретной версии 28 | - name: Установка OneScript 29 | uses: otymko/setup-onescript@v1.1 30 | with: 31 | version: ${{ matrix.oscript_version }} 32 | 33 | # Установка зависимостей пакета 34 | - name: Установка зависимостей 35 | run: | 36 | opm install opm 37 | opm install -l --dev 38 | 39 | # Запуск тестов и сбор покрытия кода 40 | - name: Покрытие кода 41 | run: oscript ./tasks/coverage.os 42 | 43 | - name: Извлечение версии пакета 44 | shell: bash 45 | run: echo "##[set-output name=version;]`cat packagedef | grep ".Версия(" | sed 's|[^"]*"||' | sed -r 's/".+//'`" 46 | id: extract_version 47 | 48 | - name: Setup sonarqube 49 | uses: warchant/setup-sonar-scanner@v8 50 | 51 | # Анализ проекта в SonarQube (ветка) 52 | - name: Анализ в SonarQube (branch) 53 | if: github.event_name == 'push' 54 | env: 55 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 56 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 57 | run: sonar-scanner 58 | -Dsonar.host.url=https://sonar.openbsl.ru 59 | -Dsonar.branch.name=${{ env.BRANCH_NAME }} 60 | -Dsonar.projectVersion=${{ steps.extract_version.outputs.version }} 61 | 62 | # Анализ проекта в SonarQube (PR) 63 | # https://docs.sonarqube.org/latest/analysis/pull-request/ 64 | - name: Анализ в SonarQube (pull-request) 65 | if: github.event_name == 'pull_request' 66 | env: 67 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 68 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 69 | run: sonar-scanner 70 | -Dsonar.host.url=https://sonar.openbsl.ru 71 | -Dsonar.pullrequest.key=${{ github.event.pull_request.number }} 72 | -Dsonar.pullrequest.branch=${{ github.event.pull_request.head.ref }} 73 | -Dsonar.pullrequest.base=${{ github.event.pull_request.base.ref }} 74 | -Dsonar.scm.revision=${{ github.event.pull_request.head.sha }} 75 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Публикация релиза 2 | 3 | on: 4 | release: 5 | types: 6 | - published 7 | workflow_dispatch: 8 | 9 | jobs: 10 | release: 11 | uses: autumn-library/workflows/.github/workflows/release.yml@main 12 | with: 13 | package_mask: "winow-*.ospx" 14 | secrets: 15 | PUSH_TOKEN: ${{ secrets.PUSH_TOKEN }} 16 | -------------------------------------------------------------------------------- /.github/workflows/testing.yml: -------------------------------------------------------------------------------- 1 | name: Тестирование 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | 8 | jobs: 9 | test: 10 | strategy: 11 | fail-fast: false 12 | matrix: 13 | oscript_version: ['stable', 'dev'] 14 | uses: autumn-library/workflows/.github/workflows/test.yml@main 15 | with: 16 | oscript_version: ${{ matrix.oscript_version }} 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .DS_Store 3 | example/hwapp/upload 4 | *.ospx 5 | out/ 6 | oscript_modules/ 7 | tests/tmp 8 | -------------------------------------------------------------------------------- /autumn-properties.json: -------------------------------------------------------------------------------- 1 | { "winow": 2 | { 3 | "КаталогСПриложениями": "./tests/app", 4 | "ЗадержкаПередЧтениемСокета": 65, 5 | "КаталогиСФайлами": { 6 | "/tests": "./tests/app/files" 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG DOCKER_USERNAME=library 2 | ARG BASE_IMAGE=debian 3 | ARG BASE_TAG=bullseye-slim 4 | 5 | FROM library/adoptopenjdk:latest 6 | 7 | # Installing mono and oscript dependencies 8 | ARG MONO_VERSION=6.12.0.122 9 | 10 | RUN apt-get update \ 11 | && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ 12 | ca-certificates \ 13 | gnupg \ 14 | dirmngr \ 15 | wget \ 16 | && apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF \ 17 | && echo "deb http://download.mono-project.com/repo/debian stable-buster main" > /etc/apt/sources.list.d/mono-official-stable.list \ 18 | && apt-get update \ 19 | && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ 20 | mono-runtime \ 21 | ca-certificates-mono \ 22 | libmono-i18n4.0-all \ 23 | libmono-system-runtime-serialization4.0-cil \ 24 | && rm -rf /etc/apt/sources.list.d/mono-official-stable.list \ 25 | && apt-get update \ 26 | && cert-sync --user /etc/ssl/certs/ca-certificates.crt \ 27 | && rm -rf \ 28 | /var/lib/apt/lists/* \ 29 | /var/cache/debconf \ 30 | /tmp/* 31 | 32 | # remove DST Root CA X3 cert if it exists 33 | #COPY ./scripts/remove-dst-root-ca-x3.sh /remove-dst-root-ca-x3.sh 34 | #RUN chmod +x /remove-dst-root-ca-x3.sh \ 35 | # && /remove-dst-root-ca-x3.sh \ 36 | # && rm /remove-dst-root-ca-x3.sh 37 | 38 | # Installing oscript 39 | ARG OVM_REPOSITORY_OWNER=oscript-library 40 | ARG OVM_VERSION=v1.0.0-RC16 41 | ARG ONESCRIPT_VERSION=stable 42 | ARG ONESCRIPT_PACKAGES="autumn winow json" 43 | 44 | RUN wget https://github.com/${OVM_REPOSITORY_OWNER}/ovm/releases/download/${OVM_VERSION}/ovm.exe \ 45 | && mv ovm.exe /usr/local/bin/ \ 46 | && echo 'mono /usr/local/bin/ovm.exe "$@"' | tee /usr/local/bin/ovm \ 47 | && chmod +x /usr/local/bin/ovm \ 48 | && ovm use --install ${ONESCRIPT_VERSION} 49 | 50 | ENV OSCRIPTBIN=/root/.local/share/ovm/current/bin 51 | ENV PATH="$OSCRIPTBIN:$PATH" 52 | 53 | # Update and prepare oscript packages 54 | RUN opm install opm \ 55 | && opm update --all \ 56 | && opm install ${ONESCRIPT_PACKAGES} 57 | 58 | COPY ./docker-entrypoint.sh / 59 | RUN chmod 755 /docker-entrypoint.sh \ 60 | && chmod +x /docker-entrypoint.sh 61 | 62 | COPY ./app/ /opt/app/winow/ 63 | 64 | ENTRYPOINT ["/docker-entrypoint.sh"] 65 | -------------------------------------------------------------------------------- /docker/app/StartWinow.os: -------------------------------------------------------------------------------- 1 | #Использовать autumn 2 | #Использовать winow 3 | 4 | Поделка = Новый Поделка; 5 | Поделка.ЗапуститьПриложение(); -------------------------------------------------------------------------------- /docker/app/autumn-properties.json: -------------------------------------------------------------------------------- 1 | { "winow": 2 | { 3 | "КаталогСПриложениями": "./controls", 4 | "Порт": 80, 5 | "ЗадержкаПередЧтениемСокета": 65, 6 | "КаталогиСФайлами": { 7 | "/img": "./files" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /docker/app/controls/Индекс.os: -------------------------------------------------------------------------------- 1 | &Пластилин Перем МенеджерОтображений Экспорт; 2 | 3 | &Контроллер("/") 4 | &Отображение(Шаблон = "./view/main.html", Метод = "ПолучитьМодельКонтрола") 5 | Процедура ПриСозданииОбъекта() 6 | 7 | КонецПроцедуры 8 | 9 | Функция ПолучитьМодельКонтрола() Экспорт 10 | Модель = Новый Структура("Заголовок", "Минималистичный веб сервер WINOW"); 11 | 12 | Возврат Модель; 13 | КонецФункции 14 | 15 | &ТочкаМаршрута("") 16 | &Отображение("./view/index.html") 17 | Процедура Главная(Ответ) Экспорт 18 | Ответ.Модель = Новый Структура("АвторПожелания", "сервер WINOW"); 19 | КонецПроцедуры 20 | 21 | &ТочкаМаршрута("about") 22 | &Отображение("./view/about.html") 23 | Процедура ОСебе(Ответ) Экспорт 24 | Библиотеки = Новый Массив; 25 | Библиотеки.Добавить(Новый Структура("Имя, Адрес", "autumn","https://github.com/autumn-library/autumn")); 26 | Библиотеки.Добавить(Новый Структура("Имя, Адрес", "autumn-dduck ","https://github.com/autumn-library/autumn-dduck")); 27 | Библиотеки.Добавить(Новый Структура("Имя, Адрес", "autumn-killjoy-flavour ","https://github.com/autumn-library/autumn-killjoy-flavour")); 28 | Библиотеки.Добавить(Новый Структура("Имя, Адрес", "autumn-logos ","https://github.com/autumn-library/autumn-logos")); 29 | 30 | Ответ.Модель = Новый Структура("Библиотеки", Библиотеки); 31 | КонецПроцедуры 32 | 33 | &ТочкаМаршрута("contact") 34 | &Отображение("./view/contact.html") 35 | Процедура Контакты() Экспорт 36 | 37 | КонецПроцедуры -------------------------------------------------------------------------------- /docker/app/files/wine_and_acorns.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docker/app/files/wine_and_acorns.jpg -------------------------------------------------------------------------------- /docker/app/view/about.html: -------------------------------------------------------------------------------- 1 |
2 |
Вино и желуди
3 | WINOW - это тебе не OneScript.WEB 4 |
5 | А так же стоит посмотреть на Библиотеки: 6 | 11 |
-------------------------------------------------------------------------------- /docker/app/view/contact.html: -------------------------------------------------------------------------------- 1 |
2 | Все о наших репозиториях можно найти ТУТ 3 |
-------------------------------------------------------------------------------- /docker/app/view/index.html: -------------------------------------------------------------------------------- 1 |
2 | Привет, ты на стартовой странице WINOW 3 |
4 | Точное серверное время: {{ТекущаяДата()}} 5 |
6 | Наилучшие пожелания от {{Модель.АвторПожелания}} 7 |
-------------------------------------------------------------------------------- /docker/app/view/main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{Модель.Заголовок}} 5 | 6 | 36 | 37 | 38 | 39 | 40 |
41 | Главная 42 | Контакты 43 | О нас 44 |
45 | 46 |
47 | @Контент 48 |
49 | 50 | -------------------------------------------------------------------------------- /docker/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cd /opt/app/winow/ 4 | oscript StartWinow.os 5 | -------------------------------------------------------------------------------- /docker/start.sh: -------------------------------------------------------------------------------- 1 | docker stop my-running-app 2 | docker rm my-running-app 3 | docker build -t test-winow . 4 | docker run -dit --name my-running-app -p 3331:80 test-winow 5 | -------------------------------------------------------------------------------- /docs/hw1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/hw1.png -------------------------------------------------------------------------------- /docs/hw10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/hw10.png -------------------------------------------------------------------------------- /docs/hw11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/hw11.png -------------------------------------------------------------------------------- /docs/hw12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/hw12.png -------------------------------------------------------------------------------- /docs/hw2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/hw2.png -------------------------------------------------------------------------------- /docs/hw3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/hw3.png -------------------------------------------------------------------------------- /docs/hw4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/hw4.png -------------------------------------------------------------------------------- /docs/hw5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/hw5.png -------------------------------------------------------------------------------- /docs/hw6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/hw6.png -------------------------------------------------------------------------------- /docs/hw7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/hw7.png -------------------------------------------------------------------------------- /docs/hw8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/hw8.png -------------------------------------------------------------------------------- /docs/hw9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/hw9.png -------------------------------------------------------------------------------- /docs/sse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/sse.gif -------------------------------------------------------------------------------- /docs/static/hw1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/static/hw1.png -------------------------------------------------------------------------------- /docs/static/hw10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/static/hw10.png -------------------------------------------------------------------------------- /docs/static/hw11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/static/hw11.png -------------------------------------------------------------------------------- /docs/static/hw12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/static/hw12.png -------------------------------------------------------------------------------- /docs/static/hw2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/static/hw2.png -------------------------------------------------------------------------------- /docs/static/hw3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/static/hw3.png -------------------------------------------------------------------------------- /docs/static/hw4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/static/hw4.png -------------------------------------------------------------------------------- /docs/static/hw5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/static/hw5.png -------------------------------------------------------------------------------- /docs/static/hw6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/static/hw6.png -------------------------------------------------------------------------------- /docs/static/hw7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/static/hw7.png -------------------------------------------------------------------------------- /docs/static/hw8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/static/hw8.png -------------------------------------------------------------------------------- /docs/static/hw9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/static/hw9.png -------------------------------------------------------------------------------- /docs/static/sse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/static/sse.gif -------------------------------------------------------------------------------- /docs/static/ws-chat.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/static/ws-chat.gif -------------------------------------------------------------------------------- /docs/ws-chat.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/docs/ws-chat.gif -------------------------------------------------------------------------------- /example/autumn-properties.json: -------------------------------------------------------------------------------- 1 | { "winow": 2 | { 3 | "Порт": 3333, 4 | "ИмяХоста": "localhost", 5 | "АвтоСтарт": true, 6 | "КаталогСПриложениями": "./hwapp", 7 | "КаталогиСФайлами": { 8 | "/images": "./hwapp/files" 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /example/hwapp/files/fun/zl2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/example/hwapp/files/fun/zl2.jpg -------------------------------------------------------------------------------- /example/hwapp/files/zl1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/example/hwapp/files/zl1.jpg -------------------------------------------------------------------------------- /example/hwapp/view/chat.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Chat Example 6 | 178 | 179 | 180 | 181 |
182 | 183 |
184 | 185 |
186 |
    187 | 188 |
189 |
190 | 191 |
192 | 193 | 194 | 195 | 196 |
197 | 198 |
199 | 200 |
201 | 202 | 203 | 292 | -------------------------------------------------------------------------------- /example/hwapp/view/chatlogin.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 110 | Welcome 111 | 112 | 113 | 114 | 115 | 116 | 117 |
118 | 119 | 120 |
121 | 122 | 123 | -------------------------------------------------------------------------------- /example/hwapp/view/console.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | i am not jenkins 6 | 7 | 8 | 9 |
10 | 11 |
12 | 13 |
14 | 15 |
16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 92 | -------------------------------------------------------------------------------- /example/hwapp/view/main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{Модель.Заголовок}} 5 | 6 | 7 |
Шапка страницы! Дата получения запроса: {{Модель.Дата}}
8 | 9 | @Контент 10 | 11 |
Подвал страницы
12 | 13 | -------------------------------------------------------------------------------- /example/hwapp/view/main_sse.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 66 | 67 | Вино и желуди 68 |
69 | 0 70 |
71 |
Сейчас смотрят: 0
72 |
73 | 74 | 75 |
76 | 77 |
78 | 80 | 81 |
82 |
83 |
-------------------------------------------------------------------------------- /example/hwapp/view/printarray.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | {% Для Каждого СтрокаИзМассива из Модель Цикл %} 4 | 5 |
Значение строки: {{ СтрокаИзМассива }}
6 | 7 | {% КонецЦикла; %} 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /example/hwapp/view/result-form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Отправка формы 5 | 6 | 7 |
Получили данные
8 | 9 |
Имя
10 |
{{Модель.Имя}}
11 | 12 |
Дата рождения
13 |
{{Модель.ДатаРождения}}
14 | 15 |
Фото
16 |
17 | Red dot 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /example/hwapp/view/send-form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Отправка формы 5 | 6 | 7 |
Отправим данные
8 | 9 |
10 |
11 | 12 | 13 |
14 |
15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 |
Подвал страницы
26 | 27 | -------------------------------------------------------------------------------- /example/hwapp/view/view1.html: -------------------------------------------------------------------------------- 1 |
Привет! Это отображение из шаблона. Точное время {{ ТекущаяДата() }} 2 |
3 |
Ты это не увидишь, но тут объявляются переменные
4 | {% 5 | ОднаПеременная = 1; 6 | ВтораяПеременная = "Секрет"; 7 | %} 8 |
9 |
Вот твое случайное число {{ Модель.СлучайноеЧисло }}
10 | 11 | {% Если Модель.СлучайноеЧисло > 5 Тогда %} 12 | 13 |
Случайное число БОЛЬШЕ пяти
14 | 15 | {% Иначе %} 16 | 17 |
Случайное число НЕ больше пяти
18 | 19 | {% КонецЕсли; %} 20 | 21 |
22 |
Давай выведу строки из массива:
23 | 24 | {{ ВывестиПоШаблону("./hwapp/view/printarray.html", Модель.МассивСтрок) }} 25 | 26 |
27 |
Давай выведу строки из второго массива:
28 | 29 | {{ ВывестиПоШаблону("./hwapp/view/printarray.html", Модель.ВторойМассив) }} 30 | 31 |
32 |
Ранее я объявил переменные, теперь покажу их
33 |
ОднаПеременная = {{ ОднаПеременная }}
34 |
ВтораяПеременная = {{ ВтораяПеременная }}
35 | -------------------------------------------------------------------------------- /example/hwapp/ВебСокетЧат.os: -------------------------------------------------------------------------------- 1 | &Пластилин Перем БрокерСообщенийВебСокетов; 2 | 3 | Перем КешИменПользователей; 4 | 5 | &Контроллер("/chat") 6 | Процедура ПриСозданииОбъекта() 7 | КешИменПользователей = Новый Соответствие(); 8 | КонецПроцедуры 9 | 10 | &ТочкаМаршрута("message") 11 | Процедура ВходящееСообщение(Идентификатор, Топик, Сообщение) Экспорт 12 | 13 | ИмяПользователя = КешИменПользователей.Получить(Идентификатор); 14 | 15 | Сообщить(СтрШаблон("Получено сообщение %1 от %2", Сообщение, ИмяПользователя)); 16 | 17 | 18 | Массив = Новый Массив(); 19 | Массив.Добавить(Идентификатор); 20 | 21 | ТекстПолучения = ФорматированноеСообщение(ИмяПользователя, Сообщение, Истина); 22 | ТекстОтправки = ФорматированноеСообщение(ИмяПользователя, Сообщение, Ложь); 23 | 24 | БрокерСообщенийВебСокетов.ОтправитьСообщениеВсемКроме(Топик, ТекстПолучения, Массив); 25 | БрокерСообщенийВебСокетов.ОтправитьСообщениеСписку(Топик, ТекстОтправки, Массив); 26 | 27 | КонецПроцедуры 28 | 29 | &Отображение("./hwapp/view/chat.html") 30 | &ТочкаМаршрута("") 31 | Процедура Главная(Сессия, Ответ) Экспорт 32 | Имя = КешИменПользователей.Получить(Сессия.Идентификатор()); 33 | Если Имя = Неопределено Тогда 34 | Ответ.Перенаправить("/chat/login"); 35 | КонецЕсли; 36 | КонецПроцедуры 37 | 38 | &ТочкаМаршрута("login") 39 | &Отображение("./hwapp/view/chatlogin.html") 40 | Процедура Логин() Экспорт 41 | КонецПроцедуры 42 | 43 | &ТочкаМаршрута("loginprocess") 44 | Процедура ОбработкаЛогина(ИмяПользователя, Сессия, Ответ) Экспорт 45 | Если НЕ ЗначениеЗаполнено(ИмяПользователя) Тогда 46 | ГенераторСлучайныхЧисел = Новый ГенераторСлучайныхЧисел(ТекущаяУниверсальнаяДатаВМиллисекундах()); 47 | ИмяПользователя = "Noname" + Строка(ГенераторСлучайныхЧисел.СлучайноеЧисло(1, 999)); 48 | КонецЕсли; 49 | Сообщить(СтрШаблон("Регистрация пользователя %1", ИмяПользователя)); 50 | КешИменПользователей.Вставить(Сессия.Идентификатор(), ИмяПользователя); 51 | Ответ.Перенаправить("/chat"); 52 | КонецПроцедуры 53 | 54 | &ПриПодключенииВебСокета("/chat/message") 55 | Процедура ПриПодключенииПользователя(Идентификатор) Экспорт 56 | 57 | ИмяПользователя = КешИменПользователей.Получить(Идентификатор); 58 | 59 | Сообщить(СтрШаблон("Подключился %1", ИмяПользователя)); 60 | 61 | ТекстСообщенияГостю = ФорматированноеСообщение("Оракул", "Привет " + ИмяПользователя + " !", Истина); 62 | 63 | БрокерСообщенийВебСокетов.ОтправитьСообщениеВсем("/chat/message", ТекстСообщенияГостю); 64 | КонецПроцедуры 65 | 66 | &ПриОтключенииВебСокета("/chat/message") 67 | Процедура ПриОтключенииПользователя(Идентификатор) Экспорт 68 | ИмяПользователя = КешИменПользователей.Получить(Идентификатор); 69 | 70 | Сообщить(СтрШаблон("Отключился %1", ИмяПользователя)); 71 | 72 | ТекстСообщения = ФорматированноеСообщение("Оракул", ИмяПользователя + " покинул чат", Истина); 73 | 74 | БрокерСообщенийВебСокетов.ОтправитьСообщениеВсем("/chat/message", ТекстСообщения); 75 | КонецПроцедуры 76 | 77 | Функция ФорматированноеСообщение(Автор, Текст, Получен) 78 | ОбъектДляПарсинга = Новый Структура("Author, Time, Text, rcv", Автор, Формат(ТекущаяДата(), "ДФ=ЧЧ:мм"), Текст, Получен); 79 | 80 | Запись = новый ЗаписьJSON; 81 | Запись.УстановитьСтроку(); 82 | ЗаписатьJSON(Запись, ОбъектДляПарсинга); 83 | 84 | Возврат Запись.Закрыть(); 85 | КонецФункции -------------------------------------------------------------------------------- /example/hwapp/ИнтерактивныйКонтролПриветствия.os: -------------------------------------------------------------------------------- 1 | &Пластилин 2 | Перем Парсеры Экспорт; 3 | 4 | &Контроллер("/greeter") 5 | Процедура ПриСозданииОбъекта() 6 | 7 | КонецПроцедуры 8 | 9 | &ТочкаМаршрута("postjsonbody") 10 | Процедура ПроверкаПостЗапросаКакОбъект(Ответ, ТелоЗапросОбъект, ЗаголовкиЗапроса) Экспорт 11 | Ответ.УстановитьТипКонтента("txt"); 12 | Ответ.ТелоТекст = ЗаголовкиЗапроса["Content-Type"] + ТипЗнч(ТелоЗапросОбъект)// СтрШаблон("%1 %2", ТелоЗапросОбъект["Имя"], ТелоЗапросОбъект["Фамилия"]); 13 | КонецПроцедуры 14 | 15 | &ТочкаМаршрута("getparamsbyname") 16 | Процедура ПроверкаГетПараметровПоИмени(Ответ, ИмяКошки, ИмяСобаки) Экспорт 17 | Ответ.УстановитьТипКонтента("txt"); 18 | Ответ.ТелоТекст = СтрШаблон("%1 И %2", "Кошка=" + ИмяКошки, "Собака=" + ИмяСобаки); 19 | КонецПроцедуры 20 | 21 | &ТочкаМаршрута("calc/{Число1}/multiply/{Число2}") 22 | Процедура ШаблонныеПараметрыУмножение(Ответ, Число1, Число2) Экспорт 23 | Ответ.УстановитьТипКонтента("txt"); 24 | Ответ.ТелоТекст = Число(Число1) * Число(Число2); 25 | КонецПроцедуры 26 | 27 | &ТочкаМаршрута("templateuri/{Ягода}/{Фрукт}/{Овощь}") 28 | Процедура ШаблонныеПараметрыПути(Ответ, Фрукт, Овощь, Ягода) Экспорт 29 | Ответ.УстановитьТипКонтента("txt"); 30 | Ответ.ТелоТекст = СтрШаблон("%1 %2 %3", Ягода, Фрукт, Овощь); 31 | КонецПроцедуры 32 | 33 | &ТочкаМаршрута("getparams") 34 | Процедура Приветствие(ПараметрыЗапросаИменные, Ответ) Экспорт 35 | 36 | Ответ.УстановитьТипКонтента("html"); 37 | 38 | Имя = ПараметрыЗапросаИменные["name"]; 39 | Фамилия = ПараметрыЗапросаИменные["familia"]; 40 | 41 | Ответ.ТелоТекст = СтрШаблон(" 42 | |
Имя: %1
43 | |
Фамилия: %2
", Имя, Фамилия); 44 | 45 | КонецПроцедуры 46 | 47 | &ТочкаМаршрута("calc") 48 | Процедура Калькулятор(ПараметрыЗапросаПорядковые, Ответ) Экспорт 49 | 50 | Ответ.УстановитьТипКонтента("html"); 51 | 52 | Если ПараметрыЗапросаПорядковые.Количество() <> 3 Тогда 53 | 54 | Решение = "Неверное число параметров"; 55 | 56 | ИначеЕсли Не (ПараметрыЗапросаПорядковые[0] = "minus" 57 | И НЕ ПараметрыЗапросаПорядковые[0] = "plus") Тогда 58 | Решение = "Операция не распознана"; 59 | 60 | Иначе 61 | Попытка 62 | Число1 = Число(ПараметрыЗапросаПорядковые[1]); 63 | Число2 = Число(ПараметрыЗапросаПорядковые[2]); 64 | 65 | Если ПараметрыЗапросаПорядковые[0] = "minus" Тогда 66 | Решение = Число1 - Число2; 67 | Иначе 68 | Решение = Число1 + Число2; 69 | КонецЕсли 70 | 71 | Исключение 72 | Решение = "Ошибка конвертации в число" 73 | КонецПопытки; 74 | КонецЕсли; 75 | 76 | Ответ.ТелоТекст = СтрШаблон(" 77 | |
Ответ: %1
", Решение); 78 | 79 | КонецПроцедуры 80 | 81 | &ТочкаМаршрута("inputstepen") 82 | Процедура ВводСтепени(Ответ) Экспорт 83 | 84 | Ответ.УстановитьТипКонтента("html"); 85 | 86 | Ответ.ТелоТекст = 87 | "
88 | |
89 | |
90 | |
91 | |

92 | | 93 | |
"; 94 | 95 | КонецПроцедуры 96 | 97 | &ТочкаМаршрута("resultstepen") 98 | Процедура ВозводительВСтепень(Ответ, ТелоЗапроса) Экспорт 99 | 100 | Ответ.УстановитьТипКонтента("html"); 101 | 102 | ПостПараметры = Парсеры.ПараметрыИзТекста(ТелоЗапроса); 103 | 104 | Попытка 105 | Решение = Pow(ПостПараметры["chislo"], ПостПараметры["stepen"]); 106 | Исключение 107 | Решение = "Ошибка при расчетах " + ОписаниеОшибки(); 108 | КонецПопытки; 109 | 110 | Ответ.ТелоТекст = СтрШаблон(" 111 | |
Ответ: %1
", Решение); 112 | 113 | КонецПроцедуры 114 | 115 | &ТочкаМаршрута("setcookie") 116 | Процедура УстановитьКуку(Ответ) Экспорт 117 | 118 | Ответ.УстановитьТипКонтента("html"); 119 | 120 | ИмяКуки = "LastEnterDate"; 121 | ЗначениеКуки = ТекущаяДата(); 122 | 123 | НоваяКука = Ответ.Куки.Добавить(ИмяКуки, ЗначениеКуки); 124 | 125 | Ответ.ТелоТекст = " 126 | |
Кука установлена
"; 127 | 128 | КонецПроцедуры 129 | 130 | &ТочкаМаршрута("readcookie") 131 | Процедура ПрочитатьКуку(КукиЗапроса, Ответ) Экспорт 132 | 133 | Ответ.УстановитьТипКонтента("html"); 134 | 135 | ИмяКуки = "LastEnterDate"; 136 | 137 | ЗначениеКуки = КукиЗапроса.ПолучитьЗначениеПоИмени(ИмяКуки); 138 | 139 | Ответ.ТелоТекст = СтрШаблон(" 140 | |
Кука: %1
", ЗначениеКуки); 141 | 142 | КонецПроцедуры 143 | 144 | &ТочкаМаршрута("setsessiondata") 145 | Процедура УстановитьДанныеСессии(Ответ, ДанныеСессии) Экспорт 146 | 147 | Ответ.УстановитьТипКонтента("html"); 148 | 149 | ИмяПараметраСессии = "ДатаПоследнегоВхода"; 150 | ЗначениеПараметраСессии = ТекущаяДата(); 151 | 152 | 153 | ДанныеСессии[ИмяПараметраСессии] = ЗначениеПараметраСессии; 154 | 155 | Ответ.ТелоТекст = " 156 | |
Данные сессии установлены
"; 157 | 158 | КонецПроцедуры 159 | 160 | &ТочкаМаршрута("readsessiondata") 161 | Процедура ПрочитатьДанныеСессии(Ответ, ДанныеСессии) Экспорт 162 | 163 | Ответ.УстановитьТипКонтента("html"); 164 | 165 | ИмяПараметраСессии = "ДатаПоследнегоВхода"; 166 | ЗначениеПараметраСессии = ДанныеСессии[ИмяПараметраСессии]; 167 | 168 | Ответ.ТелоТекст = СтрШаблон(" 169 | |
Значение параметра сессии: %1
", ЗначениеПараметраСессии); 170 | 171 | КонецПроцедуры -------------------------------------------------------------------------------- /example/hwapp/КонсольНаВебСокетах.os: -------------------------------------------------------------------------------- 1 | &Пластилин Перем БрокерСообщенийВебСокетов; 2 | 3 | &Контроллер("/console") 4 | Процедура ПриСозданииОбъекта() 5 | 6 | КонецПроцедуры 7 | 8 | &ТочкаМаршрута("run") 9 | Процедура ВходящееСообщение(Идентификатор, Топик, Сообщение) Экспорт 10 | 11 | ВывестиСтрокиВБраузере(">" + Сообщение, Топик, Идентификатор); 12 | 13 | ЗапуститьПоцесс(Сообщение, Идентификатор, Топик); 14 | 15 | КонецПроцедуры 16 | 17 | &Отображение("./hwapp/view/console.html") 18 | &ТочкаМаршрута("") 19 | Процедура Главная() Экспорт 20 | 21 | КонецПроцедуры 22 | 23 | Процедура ЗапуститьПоцесс(ТекстКоманды, Идентификатор, Топик) 24 | Сообщить("Получена команда " + ТекстКоманды); 25 | Процесс = СоздатьПроцесс(ТекстКоманды,,Истина); 26 | Процесс.Запустить(); 27 | Пока НЕ Процесс.Завершен 28 | ИЛИ Процесс.ПотокВывода.ЕстьДанные 29 | ИЛИ Процесс.ПотокОшибок.ЕстьДанные Цикл 30 | 31 | Приостановить(500); 32 | 33 | ОчереднаяСтрокаВывода = Процесс.ПотокВывода.Прочитать(); 34 | ОчереднаяСтрокаОшибок = Процесс.ПотокОшибок.Прочитать(); 35 | Если Не ПустаяСтрока(ОчереднаяСтрокаВывода) Тогда 36 | ВывестиСтрокиВБраузере(ОчереднаяСтрокаВывода, Топик, Идентификатор); 37 | КонецЕсли; 38 | 39 | Если Не ПустаяСтрока(ОчереднаяСтрокаОшибок) Тогда 40 | ВывестиСтрокиВБраузере(ОчереднаяСтрокаОшибок, Топик, Идентификатор); 41 | КонецЕсли; 42 | 43 | КонецЦикла; 44 | Сообщить("Команда обработана " + ТекстКоманды); 45 | КонецПроцедуры 46 | 47 | Процедура ВывестиСтрокиВБраузере(Текст, Топик, Идентификатор) 48 | 49 | Для Каждого ТекСтрока из СтрРазделить(Текст, Символы.ПС) Цикл 50 | БрокерСообщенийВебСокетов.ОтправитьСообщение(Топик, ФорматированноеСообщение(ТекСтрока), Идентификатор); 51 | КонецЦикла; 52 | 53 | КонецПроцедуры 54 | 55 | Функция ФорматированноеСообщение(ВыводКоманды) 56 | 57 | ОбъектДляПарсинга = Новый Структура("output", ВыводКоманды); 58 | 59 | Запись = новый ЗаписьJSON; 60 | Запись.УстановитьСтроку(); 61 | ЗаписатьJSON(Запись, ОбъектДляПарсинга); 62 | 63 | Возврат Запись.Закрыть(); 64 | КонецФункции -------------------------------------------------------------------------------- /example/hwapp/КонтролВыключатель.os: -------------------------------------------------------------------------------- 1 | &Пластилин 2 | Перем СлушательПорта Экспорт; 3 | 4 | &Контроллер("/shutdown") 5 | Процедура ПриСозданииОбъекта() 6 | 7 | КонецПроцедуры 8 | 9 | &ТочкаМаршрута("") 10 | Процедура Выключить() Экспорт 11 | СлушательПорта.Остановить(); 12 | КонецПроцедуры; -------------------------------------------------------------------------------- /example/hwapp/КонтролМета.os: -------------------------------------------------------------------------------- 1 | &Контроллер("/meta") 2 | Процедура ПриСозданииОбъекта() 3 | 4 | КонецПроцедуры 5 | 6 | &ТочкаМаршрута("") 7 | Процедура Приветствие(Ответ) Экспорт 8 | 9 | Ответ.ТелоТекст = СтрШаблон(" 10 | |
%1
", "Это мета контрол"); 11 | 12 | КонецПроцедуры 13 | 14 | -------------------------------------------------------------------------------- /example/hwapp/КонтролПолученияЖСОН.os: -------------------------------------------------------------------------------- 1 | #Использовать json 2 | 3 | &Пластилин 4 | Перем МенеджерОтображений Экспорт; 5 | 6 | &Контроллер("/json") 7 | Процедура ПриСозданииОбъекта() 8 | 9 | КонецПроцедуры 10 | 11 | &ТочкаМаршрута("getdata") 12 | Процедура ВернутьЖсон(Ответ) Экспорт 13 | 14 | Массив = Новый Массив(); 15 | Массив.Добавить("Привет"); 16 | Массив.Добавить(17); 17 | 18 | Структура = Новый Структура(); 19 | Структура.Вставить("Дата", ТекущаяДата()); 20 | Структура.Вставить("Булево", Истина); 21 | Структура.Вставить("Число", 2); 22 | Структура.Вставить("Дробь", 10/3); 23 | Структура.Вставить("Строка", "Привет дорогой пользователь"); 24 | Структура.Вставить("Массив", Массив); 25 | 26 | Парсер = Новый ПарсерJSON(); 27 | СтруктураТекстом = Парсер.ЗаписатьJSON(Структура); 28 | 29 | Ответ.УстановитьТипКонтента("json"); 30 | Ответ.ТелоТекст = СтруктураТекстом; 31 | 32 | КонецПроцедуры -------------------------------------------------------------------------------- /example/hwapp/КонтролПриветствия.os: -------------------------------------------------------------------------------- 1 | &Пластилин 2 | Перем МенеджерОтображений Экспорт; 3 | 4 | &Контроллер("/") 5 | Процедура ПриСозданииОбъекта() 6 | 7 | КонецПроцедуры 8 | 9 | &ТочкаМаршрута("/") 10 | Процедура Приветствие(Ответ) Экспорт 11 | 12 | Ответ.ТелоТекст = СтрШаблон(" 13 | |
%1
", "Привет новый дивный мир !"); 14 | 15 | КонецПроцедуры 16 | 17 | &ТочкаМаршрута("/err") 18 | Процедура Ошибка() Экспорт 19 | 20 | ВызватьИсключение "У меня ошибка"; 21 | 22 | КонецПроцедуры 23 | 24 | &ТочкаМаршрута("/redir") 25 | Процедура Перенаправление(Ответ) Экспорт 26 | 27 | Ответ.Перенаправить("/"); 28 | 29 | КонецПроцедуры 30 | 31 | Функция КастомныйШаблон404() 32 | Возврат " 33 | |

{{ Модель.КодСостояния }}

34 | |
{{ Модель.ТекстСообщения }}
35 | |
Искомый ресурс {{ Модель.Запрос.Путь }} не найден
"; 36 | КонецФункции 37 | 38 | &ФинальныйШтрих 39 | Процедура ПостИнициализация() Экспорт 40 | МенеджерОтображений.УстановитьШаблон404(КастомныйШаблон404()); 41 | КонецПроцедуры -------------------------------------------------------------------------------- /example/hwapp/КонтролРаботаСОтображениям.os: -------------------------------------------------------------------------------- 1 | 2 | &Контроллер("/demoviews") 3 | &Отображение(Шаблон = "./hwapp/view/main.html", Метод = "ПолучитьМодельКонтрола") 4 | Процедура ПриСозданииОбъекта() 5 | 6 | КонецПроцедуры 7 | 8 | Функция ПолучитьМодельКонтрола(Запрос) Экспорт 9 | Модель = Новый Структура("Заголовок, Дата", "Демонстрация работы отображений", Запрос.ДатаПолучения); 10 | 11 | Возврат Модель; 12 | КонецФункции 13 | 14 | &Отображение("./hwapp/view/view1.html") 15 | &ТочкаМаршрута("demo1") 16 | Процедура ДемонстрацияОтображения(Ответ) Экспорт 17 | 18 | Ответ.УстановитьТипКонтента("html"); 19 | 20 | ГСЧ = Новый ГенераторСлучайныхЧисел(); 21 | 22 | СлучайноеЧисло = ГСЧ.СлучайноеЧисло(1, 10); 23 | 24 | Массив = Новый Массив(); 25 | 26 | Для Сч = 1 по СлучайноеЧисло Цикл 27 | Массив.Добавить(Строка(Новый УникальныйИдентификатор())); 28 | КонецЦикла; 29 | 30 | Модель = Новый Структура(); 31 | Модель.Вставить("СлучайноеЧисло", СлучайноеЧисло); 32 | Модель.Вставить("МассивСтрок", Массив); 33 | 34 | МассивФруктов = Новый Массив(); 35 | МассивФруктов.Добавить("Яблоко"); 36 | МассивФруктов.Добавить("Апельсин"); 37 | МассивФруктов.Добавить("Банан"); 38 | МассивФруктов.Добавить("Желудь"); 39 | 40 | Модель.Вставить("ВторойМассив", МассивФруктов); 41 | 42 | Ответ.Модель = Модель; 43 | 44 | КонецПроцедуры -------------------------------------------------------------------------------- /example/hwapp/КонтролСУправлениемДоступом.os: -------------------------------------------------------------------------------- 1 | &Пластилин 2 | Перем МенеджерДоступа Экспорт; 3 | 4 | &Контроллер("/sec") 5 | Процедура ПриСозданииОбъекта() 6 | 7 | КонецПроцедуры 8 | 9 | &ФинальныйШтрих 10 | Процедура ПроинициализироватьРоли() Экспорт 11 | МенеджерДоступа.ДобавитьТокен("Админ", "123"); 12 | МенеджерДоступа.ДобавитьТокен("Пользователь", "111"); 13 | 14 | МенеджерДоступа.ДобавитьРольЛогина("Админ", "Администраторы"); 15 | МенеджерДоступа.ДобавитьРольЛогина("Админ", "Пользователи"); 16 | 17 | МенеджерДоступа.ДобавитьРольЛогина("Пользователь", "Пользователи"); 18 | КонецПроцедуры 19 | 20 | &Роли("Пользователи") 21 | &ТочкаМаршрута("user") 22 | Процедура Пользователь(Ответ) Экспорт 23 | 24 | Ответ.ТелоТекст = "Пользователи"; 25 | 26 | КонецПроцедуры 27 | 28 | &Роли("Администраторы") 29 | &ТочкаМаршрута("admin") 30 | Процедура Админ(Ответ) Экспорт 31 | Ответ.ТелоТекст = "Админка"; 32 | КонецПроцедуры 33 | 34 | &ТочкаМаршрута("free") 35 | Процедура Все(Ответ) Экспорт 36 | Ответ.ТелоТекст = "Все подрят"; 37 | КонецПроцедуры 38 | 39 | &Роли("Администраторы, Пользователи") 40 | &ТочкаМаршрута("usradm") 41 | Процедура АдминыИПользователи(Ответ) Экспорт 42 | Ответ.ТелоТекст = "Админы и пользователи"; 43 | КонецПроцедуры -------------------------------------------------------------------------------- /example/hwapp/ОтправкаФайлов.os: -------------------------------------------------------------------------------- 1 | 2 | &Контроллер("/files") 3 | Процедура ПриСозданииОбъекта() 4 | 5 | КонецПроцедуры 6 | 7 | &Отображение("./hwapp/view/send-form.html") 8 | &ТочкаМаршрута("send") 9 | Процедура ФормаОтправкиФайлов() Экспорт 10 | 11 | КонецПроцедуры 12 | 13 | &Отображение("./hwapp/view/result-form.html") 14 | &ТочкаМаршрута("uploadForm") 15 | Процедура ОбработкаФормы(ДанныеФормы, Ответ) Экспорт 16 | 17 | Ответ.Модель = Новый Структура("Имя, ДатаРождения, Фото"); 18 | 19 | Ответ.Модель.Имя = ДанныеФормы.НайтиЗначениеСтрокойПоМетаданным(Новый Структура("name", "name")); 20 | Ответ.Модель.ДатаРождения = ДанныеФормы.НайтиЗначениеСтрокойПоМетаданным(Новый Структура("name", "age")); 21 | Ответ.Модель.Фото = ПолучитьBase64СтрокуИзДвоичныхДанных(ДанныеФормы.НайтиЗначениеПоМетаданным(Новый Структура("name", "file"))); 22 | 23 | КонецПроцедуры; -------------------------------------------------------------------------------- /example/hwapp/СерверныеСобытия.os: -------------------------------------------------------------------------------- 1 | 2 | &Пластилин Перем БрокерСообщенийСобытийСервера; 3 | &пластилин Перем ФабрикаОтветов; 4 | 5 | Перем КоличествоЛайков; 6 | Перем ИмяТопика; 7 | Перем СейчасСмотрят; 8 | Перем Комментарии; 9 | 10 | &Контроллер("/sse") 11 | &Отображение(Шаблон = "./hwapp/view/main_sse.html") 12 | Процедура ПриСозданииОбъекта(&Пластилин ТопикиСерверныхСобытий) 13 | 14 | ИмяТопика = "/sse/acorndiscussion"; 15 | КоличествоЛайков = 3; 16 | СейчасСмотрят = 0; 17 | 18 | ТопикиСерверныхСобытий.Добавить(ИмяТопика, 19 | Новый Действие(ЭтотОбъект, "НовоеПодключениеССЕ"), 20 | Новый Действие(ЭтотОбъект, "ОтключениеССЕ")); 21 | 22 | Комментарии = Новый ТаблицаЗначений(); 23 | Комментарии.Колонки.Добавить("Имя"); 24 | Комментарии.Колонки.Добавить("Комментарий"); 25 | Комментарии.Колонки.Добавить("Дата"); 26 | 27 | КонецПроцедуры 28 | 29 | Процедура НовоеПодключениеССЕ(Сессия, ИД) Экспорт 30 | СейчасСмотрят = СейчасСмотрят + 1; 31 | 32 | Сообщение = ФабрикаОтветов.СерверноеСобытие(); 33 | Сообщение.ТипСобытия("like") 34 | .ДобавитьСтроку(Строка(КоличествоЛайков)); 35 | БрокерСообщенийСобытийСервера.ОтправитьСообщениеПоИдСоединения(ИД, Сообщение); 36 | 37 | Сообщение = ФабрикаОтветов.СерверноеСобытие(); 38 | Сообщение.ТипСобытия("watch") 39 | .ДобавитьСтроку(Строка(СейчасСмотрят)); 40 | БрокерСообщенийСобытийСервера.ОтправитьСообщениеВсем(ИмяТопика, Сообщение); 41 | 42 | Для Каждого Комментарий из Комментарии Цикл 43 | Сообщение = СообщениеИзСтрокиКомментария(Комментарий); 44 | БрокерСообщенийСобытийСервера.ОтправитьСообщениеПоИдСоединения(ИД, Сообщение); 45 | КонецЦикла; 46 | 47 | КонецПроцедуры 48 | 49 | Процедура ОтключениеССЕ(Сессия, ИД) Экспорт 50 | СейчасСмотрят = СейчасСмотрят - 1; 51 | 52 | Сообщение = ФабрикаОтветов.СерверноеСобытие(); 53 | Сообщение.ТипСобытия("watch") 54 | .ДобавитьСтроку(Строка(СейчасСмотрят)); 55 | БрокерСообщенийСобытийСервера.ОтправитьСообщениеВсем(ИмяТопика, Сообщение); 56 | КонецПроцедуры 57 | 58 | &ТочкаМаршрута("") 59 | Процедура ОсновнаяТочка() Экспорт 60 | 61 | КонецПроцедуры 62 | 63 | &ТочкаМаршрута("postcomment") 64 | Процедура ЗапоститьКомментарий(ТелоЗапросОбъект) Экспорт 65 | ДобавитьКомментарий(ТелоЗапросОбъект.name, ТелоЗапросОбъект.comment); 66 | КонецПроцедуры 67 | 68 | &ТочкаМаршрута("addLike") 69 | Процедура ПоставитьЛайк() Экспорт 70 | КоличествоЛайков = КоличествоЛайков + 1; 71 | Попытка 72 | Сообщение = ФабрикаОтветов.СерверноеСобытие(); 73 | Сообщение.ТипСобытия("like") 74 | .ДобавитьСтроку(Строка(КоличествоЛайков)); 75 | БрокерСообщенийСобытийСервера.ОтправитьСообщениеВсем(ИмяТопика, Сообщение); 76 | Исключение 77 | Сообщить(ОписаниеОшибки()); 78 | КонецПопытки; 79 | КонецПроцедуры 80 | 81 | Процедура ОповеститьОКомментарии(СтрокаКомментария) 82 | 83 | Сообщение = СообщениеИзСтрокиКомментария(СтрокаКомментария); 84 | 85 | БрокерСообщенийСобытийСервера.ОтправитьСообщениеВсем(ИмяТопика, Сообщение); 86 | 87 | КонецПроцедуры 88 | 89 | Функция СообщениеИзСтрокиКомментария(СтрокаКомментария) 90 | СтрокаШаблон = "
%1 - %2
91 | |
%3
"; 92 | Текст = СтрШаблон(СтрокаШаблон, СтрокаКомментария.Имя, СтрокаКомментария.Дата, СтрокаКомментария.Комментарий); 93 | 94 | Сообщение = ФабрикаОтветов.СерверноеСобытие(); 95 | Сообщение.ТипСобытия("newComment") 96 | .ДобавитьСтроку(Текст); 97 | 98 | Возврат Сообщение; 99 | КонецФункции 100 | 101 | Процедура ДобавитьКомментарий(Имя, Комментарий) 102 | 103 | НовыйКомментарий = Комментарии.Добавить(); 104 | НовыйКомментарий.Имя = Имя; 105 | НовыйКомментарий.Комментарий = Комментарий; 106 | НовыйКомментарий.Дата = ТекущаяДата(); 107 | 108 | ОповеститьОКомментарии(НовыйКомментарий); 109 | 110 | КонецПроцедуры -------------------------------------------------------------------------------- /example/ЗапускПримера.os: -------------------------------------------------------------------------------- 1 | #Использовать autumn 2 | #Использовать ".." 3 | 4 | Поделка = Новый Поделка; 5 | Поделка.ЗапуститьПриложение(); -------------------------------------------------------------------------------- /packagedef: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////// 2 | // Описание пакета для сборки и установки 3 | // Полную документацию см. на hub.oscript.io/packaging 4 | // 5 | 6 | /////////////////////////////////////////////////////////////////// 7 | // Процедуры установки пакета с клиентской машины 8 | /////////////////////////////////////////////////////////////////// 9 | 10 | 11 | // Вызывается пакетным менеджером перед установкой пакета на клиентскую машину. 12 | // 13 | // Параметры: 14 | // КаталогУстановкиПакета - строка. Путь в который пакетный менеджер устанавливает текущий пакет. 15 | // ЧтениеZipФайла - ЧтениеZipФайла. Архив пакета. 16 | // 17 | Процедура ПередУстановкой(Знач КаталогУстановкиПакета, Знач ЧтениеZipФайла) Экспорт 18 | // TODO: Реализуйте спец. логику перед установкой, если требуется 19 | КонецПроцедуры 20 | 21 | 22 | // Вызывается пакетным менеджером после распаковки пакета на клиентскую машину. 23 | // 24 | // Параметры: 25 | // КаталогУстановкиПакета - строка. Путь в который пакетный менеджер устанавливает текущий пакет. 26 | // СтандартнаяОбработка - Булево. Возможность отменить стандартную обработку. 27 | // 28 | Процедура ПриУстановке(Знач КаталогУстановкиПакета, СтандартнаяОбработка) Экспорт 29 | // TODO: Реализуйте спец. логику установки, если требуется 30 | КонецПроцедуры 31 | 32 | 33 | /////////////////////////////////////////////////////////////////// 34 | // Процедуры сборки пакета 35 | /////////////////////////////////////////////////////////////////// 36 | 37 | 38 | // Вызывается пакетным менеджером перед началом сборки пакета. 39 | // 40 | // Параметры: 41 | // РабочийКаталог - Строка - Текущий рабочий каталог с исходниками пакета. 42 | // 43 | Процедура ПередСборкой(Знач РабочийКаталог) Экспорт 44 | // TODO: Реализуйте спец. логику сборки, если требуется 45 | КонецПроцедуры 46 | 47 | 48 | // Вызывается пакетным менеджером после помещения файлов в пакет. 49 | // 50 | // Параметры: 51 | // РабочийКаталог - Строка - Текущий рабочий каталог с исходниками пакета. 52 | // АрхивПакета - ЗаписьZIPФайла - ZIP-архив с содержимым пакета (включаемые файлы). 53 | // 54 | Процедура ПриСборке(Знач РабочийКаталог, Знач АрхивПакета) Экспорт 55 | // TODO: Реализуйте спец. логику сборки, если требуется 56 | // АрхивПакета.Добавить(ПолныйПутьНужногоФайла, 57 | // РежимСохраненияПутейZIP.СохранятьОтносительныеПути, 58 | // РежимОбработкиПодкаталоговZIP.ОбрабатыватьРекурсивно); 59 | КонецПроцедуры 60 | 61 | 62 | // Вызывается пакетным менеджером после сборки пакета. 63 | // 64 | // Параметры: 65 | // РабочийКаталог - Строка - Текущий рабочий каталог с исходниками пакета. 66 | // ПутьКФайлуПакета - Строка - Полный путь к собранному файлу пакета. 67 | // 68 | Процедура ПослеСборки(Знач РабочийКаталог, Знач ПутьКФайлуПакета) Экспорт 69 | // TODO: Реализуйте спец. логику сборки, если требуется 70 | КонецПроцедуры 71 | 72 | 73 | 74 | Описание.Имя("winow") 75 | .Версия("0.9.0") 76 | .Автор("Никита Иванченко") 77 | .АдресАвтора("https://github.com/Nivanchenko") 78 | .Описание("Минималистичный веб-сервер на нативном OneScript") 79 | .ВерсияСреды("1.9.2") 80 | .ВключитьФайл("src") 81 | .ВключитьФайл("packagedef") 82 | .ВключитьФайл("lib.config") 83 | .ВключитьФайл("README.md") 84 | .ВключитьФайл("package-loader.os") 85 | .ЗависитОт("asserts", "1.4.0") 86 | .ЗависитОт("autumn", "4.3.9") 87 | .ЗависитОт("json") 88 | .ЗависитОт("autumn-logos", "1.2.0") 89 | .ЗависитОт("semaphore", "1.1.0") 90 | .ЗависитОт("fs") 91 | .РазработкаЗависитОт("1commands") 92 | .РазработкаЗависитОт("1testrunner") 93 | .РазработкаЗависитОт("coverage") 94 | ; 95 | -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=winow 2 | sonar.projectName=winow 3 | sonar.sources=./src 4 | sonar.tests=./tests 5 | sonar.sourceEncoding=UTF-8 6 | sonar.coverageReportPaths=out/genericCoverage.xml 7 | -------------------------------------------------------------------------------- /src/Классы/АннотацияКонтроллер.os: -------------------------------------------------------------------------------- 1 | &Аннотация(Значение = "Контроллер") 2 | &Желудь 3 | &Прозвище("Контроллер") 4 | Процедура ПриСозданииОбъекта(Значение = "/") 5 | 6 | КонецПроцедуры -------------------------------------------------------------------------------- /src/Классы/АннотацияЛогВебСервера.os: -------------------------------------------------------------------------------- 1 | &Аннотация("ЛогВебСервера") 2 | &Лог("oscript.lib.winow") 3 | Процедура ПриСозданииОбъекта() 4 | КонецПроцедуры -------------------------------------------------------------------------------- /src/Классы/БрокерСообщенийВебСокетов.os: -------------------------------------------------------------------------------- 1 | &Пластилин Перем ШифрованиеВебСокета; 2 | 3 | &Пластилин Перем КонструкторыПараметров; 4 | &Пластилин Перем СоединенияВебСокетов; 5 | 6 | Перем Рефлектор; 7 | Перем КешОбработчиков; 8 | Перем ПодпискиПодключения; 9 | Перем ПодпискиОтключения; 10 | Перем _Маршрутизатор; 11 | 12 | &Желудь 13 | Процедура ПриСозданииОбъекта(&Пластилин Перечисления, &Пластилин Маршрутизатор) 14 | Рефлектор = Новый Рефлектор(); 15 | КешОбработчиков = Новый Соответствие(); 16 | _Маршрутизатор = Маршрутизатор; 17 | 18 | ПодпискиПодключения = Маршрутизатор.ПолучитьПодписки(Перечисления.ВидыПодписокВебСокета.ПриПодключенииВебСокета); 19 | ПодпискиОтключения = Маршрутизатор.ПолучитьПодписки(Перечисления.ВидыПодписокВебСокета.ПриОтключенииВебСокета); 20 | КонецПроцедуры 21 | 22 | Процедура ВходящееСообщение(Идентификатор, Топик, ДвоичныеДанныеСообщения) Экспорт 23 | 24 | ДанныеСообщения = ШифрованиеВебСокета.РаспаковатьСообщение(ДвоичныеДанныеСообщения); 25 | 26 | Если ДанныеСообщения.ТипСообщения = 0 Тогда // Продолжение 27 | 28 | ИначеЕсли ДанныеСообщения.ТипСообщения = 1 Тогда // Текстовый фрейм 29 | 30 | Обработчик = НайтиОбработчик(Топик); 31 | Параметры = КонструкторыПараметров.СформироватьМассивНеобходимыхПараметров(Обработчик.Действие.Параметры, 32 | Новый Структура("Идентификатор, Топик, Сообщение", 33 | Идентификатор, 34 | Топик, 35 | ДанныеСообщения.Сообщение)); 36 | 37 | Рефлектор.ВызватьМетод(Обработчик.Действие.Желудь, Обработчик.Действие.ИмяМетода, Параметры); 38 | 39 | ИначеЕсли ДанныеСообщения.ТипСообщения = 2 Тогда // бинарные данные 40 | 41 | ИначеЕсли ДанныеСообщения.ТипСообщения = 3 Тогда // 42 | 43 | ИначеЕсли ДанныеСообщения.ТипСообщения = 4 Тогда// 44 | 45 | ИначеЕсли ДанныеСообщения.ТипСообщения = 5 Тогда // 46 | 47 | ИначеЕсли ДанныеСообщения.ТипСообщения = 6 Тогда // 48 | 49 | ИначеЕсли ДанныеСообщения.ТипСообщения = 7 Тогда // 50 | 51 | ИначеЕсли ДанныеСообщения.ТипСообщения = 8 Тогда // Закрытие соединения 52 | // СоединенияВебСокетов.НайтиИЗакрытьСоединениеПоИдентификаторуИТопику(Топик, Идентификатор); 53 | ИначеЕсли ДанныеСообщения.ТипСообщения = 9 Тогда // Пинг 54 | 55 | ИначеЕсли ДанныеСообщения.ТипСообщения = 10 Тогда // Понг 56 | 57 | ИначеЕсли ДанныеСообщения.ТипСообщения = 11 Тогда // 58 | 59 | ИначеЕсли ДанныеСообщения.ТипСообщения = 12 Тогда // 60 | 61 | ИначеЕсли ДанныеСообщения.ТипСообщения = 13 Тогда // 62 | 63 | ИначеЕсли ДанныеСообщения.ТипСообщения = 14 Тогда // 64 | 65 | ИначеЕсли ДанныеСообщения.ТипСообщения = 15 Тогда // 66 | 67 | ИначеЕсли ДанныеСообщения.ТипСообщения = 16 Тогда // 68 | 69 | КонецЕсли; 70 | 71 | КонецПроцедуры 72 | 73 | Процедура ОтправитьСообщение(Топик, Сообщение, Идентификатор) Экспорт 74 | ДанныеСоединения = СоединенияВебСокетов.ПолучитьСоединениеПоИдентификатору(Топик, Идентификатор); 75 | Если НЕ ДанныеСоединения = Неопределено Тогда 76 | УпакованноеСообщение = ШифрованиеВебСокета.ЗапаковатьСообщениеТекстовоеСообщение(Сообщение); 77 | ДанныеСоединения.Соединение.ОтправитьДвоичныеДанные(УпакованноеСообщение); 78 | КонецЕсли; 79 | КонецПроцедуры 80 | 81 | Процедура ОтправитьСообщениеВсем(Топик, Сообщение) Экспорт 82 | Соединения = СоединенияВебСокетов.ПолучитьСоединенияПоТопику(Топик); 83 | УпакованноеСообщение = ШифрованиеВебСокета.ЗапаковатьСообщениеТекстовоеСообщение(Сообщение); 84 | Для Каждого ДанныеСоединения из Соединения Цикл 85 | ДанныеСоединения.Соединение.ОтправитьДвоичныеДанные(УпакованноеСообщение); 86 | КонецЦикла; 87 | КонецПроцедуры 88 | 89 | Процедура ОтправитьСообщениеСписку(Топик, Сообщение, СписокИдентификаторов) Экспорт 90 | Соединения = СоединенияВебСокетов.ПолучитьСоединенияПоТопикуСпискуИдентификаторов(Топик, СписокИдентификаторов); 91 | УпакованноеСообщение = ШифрованиеВебСокета.ЗапаковатьСообщениеТекстовоеСообщение(Сообщение); 92 | Для Каждого ДанныеСоединения из Соединения Цикл 93 | ДанныеСоединения.Соединение.ОтправитьДвоичныеДанные(УпакованноеСообщение); 94 | КонецЦикла; 95 | КонецПроцедуры 96 | 97 | Процедура ОтправитьСообщениеВсемКроме(Топик, Сообщение, СписокИсключенийИдентификаторов) Экспорт 98 | Соединения = СоединенияВебСокетов.ПолучитьСоединенияПоТопикуКромеСпискаИдентификаторов(Топик, СписокИсключенийИдентификаторов); 99 | УпакованноеСообщение = ШифрованиеВебСокета.ЗапаковатьСообщениеТекстовоеСообщение(Сообщение); 100 | Для Каждого ДанныеСоединения из Соединения Цикл 101 | ДанныеСоединения.Соединение.ОтправитьДвоичныеДанные(УпакованноеСообщение); 102 | КонецЦикла; 103 | КонецПроцедуры 104 | 105 | Процедура ПриПодключении(Топик, Идентификатор) Экспорт 106 | ОбработатьСобытиеПодписки(Топик, Идентификатор, ПодпискиПодключения); 107 | КонецПроцедуры 108 | 109 | Процедура ПриОтключении(Топик, Идентификатор) Экспорт 110 | ОбработатьСобытиеПодписки(Топик, Идентификатор, ПодпискиОтключения); 111 | КонецПроцедуры 112 | 113 | Процедура ОбработатьСобытиеПодписки(Топик, Идентификатор, ПодпискиВебСокета) 114 | ОписаниеПодписки = ПодпискиВебСокета.Получить(Топик); 115 | Если не ОписаниеПодписки = Неопределено Тогда 116 | Параметры = КонструкторыПараметров.СформироватьМассивНеобходимыхПараметров(ОписаниеПодписки.Параметры, 117 | Новый Структура("Идентификатор", Идентификатор)); 118 | Рефлектор.ВызватьМетод(ОписаниеПодписки.Объект, ОписаниеПодписки.Метод, Параметры); 119 | КонецЕсли; 120 | КонецПроцедуры 121 | 122 | Функция НайтиОбработчик(Топик) 123 | 124 | Обработчик = КешОбработчиков.Получить(Топик); 125 | Если Обработчик = Неопределено Тогда 126 | Обработчик = _Маршрутизатор.НайтиОбработчикИПараметрыПоПолномуПути(Топик); 127 | КешОбработчиков.Вставить(Топик, Обработчик); 128 | КонецЕсли; 129 | 130 | Возврат Обработчик; 131 | 132 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/БрокерСообщенийСобытийСервера.os: -------------------------------------------------------------------------------- 1 | 2 | &Пластилин Перем СоединенияСерверныхСобытий; 3 | &Пластилин Перем ТопикиСерверныхСобытий; 4 | 5 | &Желудь 6 | Процедура ПриСозданииОбъекта() 7 | 8 | КонецПроцедуры 9 | 10 | Функция КоличествоСоединений(Топик) Экспорт 11 | Возврат СоединенияСерверныхСобытий.Количество(Топик); 12 | КонецФункции 13 | 14 | Процедура ОтправитьСообщениеВсем(Топик, Сообщение) Экспорт 15 | ПроверитьТопик(Топик); 16 | 17 | Соединения = СоединенияСерверныхСобытий.ПолучитьСоединенияПоТопику(Топик); 18 | 19 | ОтправитьСообщениеКлиентам(Соединения, Сообщение); 20 | 21 | КонецПроцедуры 22 | 23 | Процедура ОтправитьСообщениеПоИдСоединения(ИдСоединения, Сообщение) Экспорт 24 | 25 | Соединения = СоединенияСерверныхСобытий.ПолучитьСоединениеПоИдСоединения(ИдСоединения); 26 | 27 | ОтправитьСообщениеКлиентам(Соединения, Сообщение); 28 | 29 | КонецПроцедуры 30 | 31 | Процедура ОтправитьСообщениеСписку(Топик, Сообщение, СписокИдентификаторов) Экспорт 32 | ПроверитьТопик(Топик); 33 | 34 | Соединения = СоединенияСерверныхСобытий.ПолучитьСоединенияПоТопикуСпискуИдентификаторов(Топик, СписокИдентификаторов); 35 | 36 | ОтправитьСообщениеКлиентам(Соединения, Сообщение); 37 | 38 | КонецПроцедуры 39 | 40 | Процедура ОтправитьСообщениеВсемКроме(Топик, Сообщение, СписокИсключенийИдентификаторов) Экспорт 41 | ПроверитьТопик(Топик); 42 | 43 | Соединения = СоединенияСерверныхСобытий.ПолучитьСоединенияПоТопикуКромеСпискаИдентификаторов(Топик, СписокИсключенийИдентификаторов); 44 | 45 | ОтправитьСообщениеКлиентам(Соединения, Сообщение); 46 | 47 | КонецПроцедуры 48 | 49 | Процедура ОтправитьСообщение(Идентификатор, Топик, Сообщение) Экспорт 50 | ПроверитьТопик(Топик); 51 | 52 | Соединения = СоединенияСерверныхСобытий.ПолучитьСоединениеПоИдентификатору(Топик, Идентификатор); 53 | 54 | ОтправитьСообщениеКлиентам(Соединения, Сообщение); 55 | 56 | КонецПроцедуры 57 | 58 | Процедура ОтправитьСообщениеКлиентам(Соединения, Сообщение) 59 | 60 | ДДСобщения = ПолучитьДвоичныеДанныеИзСтроки(Сообщение.Сформировать()); 61 | 62 | Для Каждого Соединение из Соединения Цикл 63 | ОтправитьВПопытке(Соединение.Соединение, ДДСобщения); 64 | КонецЦикла; 65 | 66 | КонецПроцедуры 67 | 68 | Функция ОтправитьВПопытке(Соединение, ДвоичныеДанныеОтвета) Экспорт 69 | Попытка 70 | Соединение.ОтправитьДвоичныеДанные(ДвоичныеДанныеОтвета); 71 | Возврат Истина; 72 | Исключение 73 | Возврат Ложь; 74 | КонецПопытки; 75 | КонецФункции 76 | 77 | Процедура ПроверитьТопик(Топик) 78 | Если Не ТопикиСерверныхСобытий.Существует(Топик) Тогда 79 | ВызватьИсключение СтрШаблон("Топик %1 не зарегистрирован", Топик); 80 | КонецЕсли; 81 | КонецПроцедуры 82 | 83 | -------------------------------------------------------------------------------- /src/Классы/ВходящийЗапрос.os: -------------------------------------------------------------------------------- 1 | #Использовать json 2 | 3 | Перем ТекстЗапроса Экспорт; 4 | Перем Заголовки Экспорт; 5 | Перем Тело Экспорт; 6 | Перем ТелоДвоичныеДанные Экспорт; 7 | Перем Метод Экспорт; 8 | Перем ПолныйПуть Экспорт; 9 | Перем Путь Экспорт; 10 | Перем ПараметрыИменные Экспорт; 11 | Перем ПараметрыПорядковые Экспорт; 12 | Перем ДатаПолучения Экспорт; 13 | Перем ДвоичныеДанные Экспорт; 14 | Перем Сессия Экспорт; 15 | Перем КлючРукопожатия Экспорт; 16 | Перем АдресУдаленногоУзла Экспорт; 17 | Перем ПортУдаленногоУзла Экспорт; 18 | 19 | Перем Куки Экспорт; 20 | Перем Парсеры; 21 | Перем Настройки; 22 | Перем ДанныеФормы; 23 | 24 | 25 | &Желудь 26 | &Характер("Компанейский") 27 | &ОсобоеОбращение(ОтключитьВсеНапильники = Истина) 28 | Процедура ПриСозданииОбъекта( 29 | &Пластилин("Куки") _Куки, 30 | &Пластилин("Парсеры") _Парсеры, 31 | &Пластилин("Настройки") _Настройки 32 | ) 33 | 34 | ТекстЗапроса = ""; 35 | Заголовки = Новый Соответствие(); 36 | Тело = ""; 37 | Метод = ""; 38 | ПолныйПуть = ""; 39 | Путь = ""; 40 | ПараметрыИменные = Новый Соответствие(); 41 | ПараметрыПорядковые = Новый Массив(); 42 | ДатаПолучения = ТекущаяДата(); 43 | АдресУдаленногоУзла = ""; 44 | ПортУдаленногоУзла = 0; 45 | 46 | Куки = _Куки; 47 | Парсеры = _Парсеры; 48 | Настройки = _Настройки; 49 | 50 | КонецПроцедуры 51 | 52 | Функция ЗначенияПараметровДляТочкиМаршрута() Экспорт 53 | Результат = Новый Соответствие(); 54 | Результат.Вставить("Запрос", ЭтотОбъект); 55 | Результат.Вставить("ТекстЗапроса", ТекстЗапроса); 56 | Результат.Вставить("ЗаголовкиЗапроса", Заголовки); 57 | Результат.Вставить("ТелоЗапроса", Тело); 58 | Результат.Вставить("ТелоЗапросаСоответствие", ТелоЗапросаСоответствие()); 59 | Результат.Вставить("ТелоЗапросаДвоичныеДанные", ТелоДвоичныеДанные); 60 | Результат.Вставить("МетодЗапроса", Метод); 61 | Результат.Вставить("ПолныйПутьЗапроса", ПолныйПуть); 62 | Результат.Вставить("ПутьЗапроса", Путь); 63 | Результат.Вставить("ПараметрыЗапросаИменные", ПараметрыИменные); 64 | Результат.Вставить("ПараметрыЗапросаПорядковые", ПараметрыПорядковые); 65 | Результат.Вставить("ДатаПолученияЗапроса", ДатаПолучения); 66 | Результат.Вставить("ДвоичныеДанныеЗапроса", ДвоичныеДанные); 67 | Результат.Вставить("КукиЗапроса", Куки); 68 | Результат.Вставить("ТелоЗапросОбъект", ТелоЗапросОбъект()); 69 | Результат.Вставить("ДанныеФормы", ДанныеФормы()); 70 | Результат.Вставить("АдресУдаленногоУзла", АдресУдаленногоУзла); 71 | Результат.Вставить("ПортУдаленногоУзла", ПортУдаленногоУзла); 72 | 73 | ДополнитьСоответствие(Результат, Результат["ТелоЗапросаСоответствие"]); 74 | ДополнитьСоответствие(Результат, Результат["ПараметрыЗапросаИменные"]); 75 | 76 | Возврат Результат; 77 | КонецФункции 78 | 79 | Процедура УстановитьДанныеФормы(НовыеДанныеФормы) Экспорт 80 | 81 | ДанныеФормы = НовыеДанныеФормы; 82 | 83 | КонецПроцедуры 84 | 85 | Функция ДанныеФормы() 86 | 87 | Если Не ДанныеФормы = Неопределено Тогда 88 | Возврат ДанныеФормы; 89 | КонецЕсли; 90 | 91 | ДанныеФормы = Новый ДанныеСоставнойФормы(); 92 | 93 | ЧастьРазделителя = ПолучитьДвоичныеДанныеИзСтроки("--"); 94 | ЧастьРазделителяСВКПС = ПолучитьДвоичныеДанныеИзСтроки("--" + Символы.ВК + Символы.ПС); 95 | 96 | Если СтрНайти(НРег(Заголовки["Content-Type"]), "multipart/form-data") > 0 Тогда 97 | РазделительДанных = СокрЛП(СтрЗаменить(Заголовки["Content-Type"], "multipart/form-data; boundary=", "")); 98 | РазделительДанныхДД = ПолучитьДвоичныеДанныеИзСтроки(РазделительДанных); 99 | 100 | ДДФормы = Парсеры.РазделитьДвоичныеДанныеРазделителемВМассив(ТелоДвоичныеДанные, РазделительДанныхДД); 101 | 102 | Для Каждого ЧастьФормы из ДДФормы Цикл 103 | Если ЧастьФормы = ЧастьРазделителяСВКПС 104 | ИЛИ ЧастьФормы = ЧастьРазделителя Тогда 105 | Продолжить; 106 | КонецЕсли; 107 | 108 | РазделенныеДанные = РазделитьДвоичныеДанныеПоляДанныхФормы(ЧастьФормы); 109 | Если РазделенныеДанные = Неопределено Тогда 110 | Продолжить; 111 | КонецЕсли; 112 | 113 | Структура = Новый Структура("Метаданные, Значение", Новый Соответствие); 114 | Структура.Значение = РазделенныеДанные.Значение; 115 | 116 | СтрокиМетаданных = СтрРазделить(ПолучитьСтрокуИзДвоичныхДанных(РазделенныеДанные.Метаданные), Символы.ПС, Ложь); 117 | 118 | ПлоскиеЗаголовки = Новый Соответствие(); 119 | 120 | Для Каждого СтрокаМетаданных из СтрокиМетаданных Цикл 121 | РазделеннаяСтрока = Парсеры.РазделитьСтроку(СтрокаМетаданных, ":"); 122 | ПлоскиеЗаголовки.Вставить(СокрЛП(РазделеннаяСтрока.Лево), СокрЛП(РазделеннаяСтрока.Право)); 123 | Структура.Метаданные.Вставить(СокрЛП(РазделеннаяСтрока.Лево), 124 | УбратьКовычкиИзЗначенийСоответствия(Парсеры.ПараметрыИзТекста(РазделеннаяСтрока.Право, "; "))); 125 | КонецЦикла; 126 | 127 | Структура.Метаданные.Вставить("Заголовки", ПлоскиеЗаголовки); 128 | 129 | ДанныеФормы.Добавить(Структура); 130 | 131 | КонецЦикла 132 | 133 | КонецЕсли; 134 | 135 | Возврат ДанныеФормы; 136 | КонецФункции 137 | 138 | Функция УбратьКовычкиИзЗначенийСоответствия(Соответствие) 139 | Результат = Новый Соответствие(); 140 | Для Каждого КиЗ Из Соответствие Цикл 141 | Результат.Вставить(СокрЛП(КиЗ.Ключ), СокрЛП(СтрЗаменить(КиЗ.Значение, """", ""))); 142 | КонецЦикла; 143 | Возврат Результат; 144 | КонецФункции 145 | 146 | Функция ТелоЗапросОбъект() Экспорт 147 | Результат = Неопределено; 148 | 149 | Если ЗначениеЗаполнено(Тело) 150 | И 151 | СтрНайти(НРег(СокрЛП(Заголовки["Content-Type"])), "application/json") > 0 Тогда 152 | 153 | Парсер = Новый ПарсерJSON(); 154 | Результат = Парсер.ПрочитатьJSON(Тело, Истина, Ложь, Настройки.АвтоматическиПриводитьОбъектыКСтруктуре); 155 | 156 | КонецЕсли; 157 | 158 | Возврат Результат; 159 | КонецФункции 160 | 161 | Функция ТелоЗапросаСоответствие() 162 | Результат = Новый Соответствие(); 163 | 164 | Если ЗначениеЗаполнено(Тело) И СокрЛП(Заголовки["Content-Type"]) = "application/x-www-form-urlencoded" Тогда 165 | Результат = Парсеры.ПараметрыИзТекста(Тело); 166 | КонецЕсли; 167 | 168 | Возврат Результат; 169 | КонецФункции 170 | 171 | Функция РазделитьДвоичныеДанныеПоляДанныхФормы(ЧастьФормы) 172 | 173 | Структура = Новый Структура("Метаданные, Значение", Новый Соответствие); 174 | 175 | ЧастьРазделителя = ПолучитьДвоичныеДанныеИзСтроки("--"); 176 | РазделительСтрок = ПолучитьДвоичныеДанныеИзСтроки(Символы.ВК + Символы.ПС); 177 | 178 | РазделеннаяЧастьФормы = Парсеры.РазделитьДвоичныеДанныеРазделителемВМассив(ЧастьФормы, РазделительСтрок); 179 | 180 | Если РазделеннаяЧастьФормы[РазделеннаяЧастьФормы.ВГраница()] = ЧастьРазделителя Тогда 181 | РазделеннаяЧастьФормы.Удалить(РазделеннаяЧастьФормы.ВГраница()); 182 | КонецЕсли; 183 | 184 | Если РазделеннаяЧастьФормы.Количество() = 1 Тогда 185 | Структура.Метаданные = РазделеннаяЧастьФормы[0]; 186 | ИначеЕсли РазделеннаяЧастьФормы.Количество() > 1 Тогда 187 | МетаданныеДД = Новый Массив(); 188 | ЗначениеДД = Новый Массив(); 189 | 190 | ЭтоМетаданные = Истина; 191 | ПропущенПервыйРазделитель = Ложь; 192 | Для Каждого РазделеннаяЧасть Из РазделеннаяЧастьФормы Цикл 193 | ЭтоЗамененныйРазделитель = РазделеннаяЧасть.Размер() = 0; 194 | МетаданныеЗаполнены = МетаданныеДД.Количество() > 0; 195 | 196 | Если ЭтоМетаданные И ЭтоЗамененныйРазделитель И МетаданныеЗаполнены Тогда 197 | ЭтоМетаданные = Ложь; 198 | ПропущенПервыйРазделитель = Ложь; 199 | КонецЕсли; 200 | 201 | Если ЭтоЗамененныйРазделитель И Не ПропущенПервыйРазделитель Тогда 202 | ПропущенПервыйРазделитель = Истина; 203 | Продолжить; 204 | КонецЕсли; 205 | 206 | Если ЭтоМетаданные Тогда 207 | МассивДД = МетаданныеДД; 208 | Иначе 209 | МассивДД = ЗначениеДД; 210 | КонецЕсли; 211 | 212 | Если МассивДД.Количество() > 0 Тогда 213 | МассивДД.Добавить(РазделительСтрок); 214 | КонецЕсли; 215 | 216 | МассивДД.Добавить(РазделеннаяЧасть); 217 | КонецЦикла; 218 | 219 | Структура.Метаданные = СоединитьДвоичныеДанные(МетаданныеДД); 220 | Структура.Значение = СоединитьДвоичныеДанные(ЗначениеДД); 221 | Иначе 222 | Возврат Неопределено; 223 | КонецЕсли; 224 | 225 | Возврат Структура; 226 | КонецФункции 227 | 228 | Процедура ДополнитьСоответствие(Приемник, Источник) 229 | Для Каждого КиЗ Из Источник Цикл 230 | Приемник.Вставить(КиЗ.Ключ, КиЗ.Значение); 231 | КонецЦикла; 232 | КонецПроцедуры 233 | 234 | Функция ЭтоЗапросНаВебСокет() Экспорт 235 | КлючРукопожатия = Заголовки["Sec-WebSocket-Key"]; 236 | Возврат НЕ КлючРукопожатия = Неопределено И НЕ ПустаяСтрока(КлючРукопожатия); 237 | КонецФункции 238 | 239 | Функция ЭтоЗапросНаСерверныеСобытия() Экспорт 240 | Возврат СокрЛП(Заголовки["Accept"]) = "text/event-stream" 241 | И СокрЛП(Заголовки["Connection"]) = "keep-alive"; 242 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/ДанныеСоставнойФормы.os: -------------------------------------------------------------------------------- 1 | 2 | Перем ДанныеФормы; 3 | 4 | Процедура ПриСозданииОбъекта() 5 | ДанныеФормы = Новый Массив(); 6 | КонецПроцедуры 7 | 8 | Функция Количество() Экспорт 9 | Возврат ДанныеФормы.Количество(); 10 | КонецФункции 11 | 12 | Процедура Добавить(Значение) Экспорт 13 | ДанныеФормы.Добавить(Значение); 14 | КонецПроцедуры 15 | 16 | Функция ПолучитьПоИндексу(Индекс) Экспорт 17 | Возврат ДанныеФормы[Индекс]; 18 | КонецФункции 19 | 20 | Функция НайтиДанныеПоМетаданным(Отбор) Экспорт 21 | 22 | Если Отбор.Количество() = 0 Тогда 23 | ВызватьИсключение "Отбор не может быть пустым"; 24 | КонецЕсли; 25 | 26 | Для каждого ЗначениеФормы Из ДанныеФормы Цикл 27 | Если МетаданныеСоответствуютОтбору(ЗначениеФормы.Метаданные, Отбор) Тогда 28 | Возврат ЗначениеФормы; 29 | КонецЕсли; 30 | КонецЦикла; 31 | 32 | Возврат Неопределено; 33 | 34 | КонецФункции 35 | 36 | Функция НайтиЗначениеПоМетаданным(Отбор) Экспорт 37 | 38 | Результат = НайтиДанныеПоМетаданным(Отбор); 39 | 40 | Если Результат = Неопределено Тогда 41 | Возврат Неопределено; 42 | Иначе 43 | Возврат Результат.Значение; 44 | КонецЕсли; 45 | 46 | КонецФункции 47 | 48 | Функция НайтиЗначениеСтрокойПоМетаданным(Отбор) Экспорт 49 | 50 | Результат = НайтиДанныеПоМетаданным(Отбор); 51 | 52 | Если Результат = Неопределено 53 | ИЛИ (НЕ Результат = Неопределено и Результат.Значение = Неопределено) Тогда 54 | Возврат Неопределено; 55 | Иначе 56 | Возврат ПолучитьСтрокуИзДвоичныхДанных(Результат.Значение); 57 | КонецЕсли; 58 | 59 | КонецФункции 60 | 61 | Функция МетаданныеСоответствуютОтбору(Метаданные, Отбор) 62 | 63 | Для Каждого ТекущийОтбор из Отбор Цикл 64 | ОтборНайден = Ложь; 65 | 66 | Для Каждого ТекущиеМетаданные из Метаданные Цикл 67 | Если СокрЛП(ТекущиеМетаданные.Значение[ТекущийОтбор.Ключ]) = СокрЛП(ТекущийОтбор.Значение) Тогда 68 | ОтборНайден = Истина; 69 | Прервать; 70 | КонецЕсли; 71 | КонецЦикла; 72 | 73 | Если НЕ ОтборНайден Тогда 74 | Возврат Ложь; 75 | КонецЕсли; 76 | КонецЦикла; 77 | 78 | Возврат Истина; 79 | 80 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/ЗапускательВебПриложения.os: -------------------------------------------------------------------------------- 1 | &Пластилин Перем ВебСервер; 2 | &Пластилин Перем ИнициализацияНастроекСервера; 3 | 4 | &Желудь 5 | Процедура ПриСозданииОбъекта() 6 | 7 | КонецПроцедуры 8 | 9 | Процедура Запустить() Экспорт 10 | ИнициализацияНастроекСервера.ИнициализацияКонтролов(); 11 | ВебСервер.Старт(); 12 | КонецПроцедуры -------------------------------------------------------------------------------- /src/Классы/ИнициализацияЖелудейСервера.os: -------------------------------------------------------------------------------- 1 | #Использовать logos 2 | 3 | Перем Лог; 4 | 5 | Перем КаталогСПриложениями; 6 | 7 | Процедура ПриИнициализацииПоделки(Поделка) Экспорт 8 | 9 | ДобавитьЖелудиПриложений(Поделка); 10 | 11 | КонецПроцедуры 12 | 13 | Процедура ДобавитьЖелудиПриложений(Поделка) 14 | 15 | Лог.Отладка(СтрШаблон("Чтение желудей приложения из %1", КаталогСПриложениями)); 16 | 17 | СчетчикКлассов = 0; 18 | 19 | Файлы = НайтиФайлы(КаталогСПриложениями, "*.os", Истина); 20 | Для Каждого Файл Из Файлы Цикл 21 | Лог.Отладка(СтрШаблон("Регистрация класса %1", Файл.ИмяБезРасширения)); 22 | ПодключитьСценарий(Файл.ПолноеИмя, Файл.ИмяБезРасширения); 23 | 24 | ТипЖелудя = Неопределено; 25 | Попытка 26 | ТипЖелудя = Тип(Файл.ИмяБезРасширения); 27 | СчетчикКлассов = СчетчикКлассов + 1; 28 | Исключение 29 | Продолжить; 30 | КонецПопытки; 31 | 32 | КонецЦикла; 33 | 34 | Лог.Отладка(СтрШаблон("Загружено классов приложения %1", СчетчикКлассов)); 35 | 36 | Поделка.ПросканироватьКаталог(КаталогСПриложениями); 37 | 38 | КонецПроцедуры 39 | 40 | &Заготовка 41 | Процедура ПриСозданииОбъекта(&Деталька(Значение = "winow.КаталогСПриложениями", ЗначениеПоУмолчанию = "./app") _КаталогСПриложениями) 42 | КаталогСПриложениями = _КаталогСПриложениями; 43 | 44 | Лог = Логирование.ПолучитьЛог("winow.init"); 45 | КонецПроцедуры -------------------------------------------------------------------------------- /src/Классы/ИнициализацияНастроекСервера.os: -------------------------------------------------------------------------------- 1 | #Использовать autumn-logos 2 | 3 | &Лог("winow.settingsInit") 4 | Перем Лог; 5 | 6 | &Пластилин(Значение = "Контроллер", Тип = "Массив") 7 | Перем Контроллы; 8 | 9 | &Пластилин Перем РегистраторКаталогаФайлов; 10 | &Пластилин Перем СборщикМаршрутов; 11 | &Пластилин Перем ВебСервер; 12 | 13 | &Деталька("winow.КаталогиСФайлами") 14 | Перем КаталогиСФайлами; 15 | 16 | &Деталька(Значение = "winow.АвтоСтарт", ЗначениеПоУмолчанию = Ложь) 17 | Перем АвтоСтарт; 18 | 19 | &Рогатка 20 | Процедура ПриСозданииОбъекта() 21 | 22 | КонецПроцедуры 23 | 24 | Процедура ПриЗапускеПриложения() Экспорт 25 | 26 | ИнициализацияКонтролов(); 27 | 28 | Старт(); 29 | 30 | КонецПроцедуры 31 | 32 | Процедура ИнициализацияКонтролов() Экспорт 33 | 34 | Лог.Отладка(СтрШаблон("Регистрация контролов %1", Контроллы.Количество())); 35 | 36 | Для Каждого Контролл из Контроллы Цикл 37 | СборщикМаршрутов.НайтиИЗарегистрироватьМаршруты(Контролл); 38 | КонецЦикла; 39 | 40 | РегистраторКаталогаФайлов.ОбновтитьСтатичныеФайлы(); 41 | 42 | КонецПроцедуры 43 | 44 | Процедура Старт() 45 | 46 | Если АвтоСтарт = Истина Тогда 47 | ВебСервер.Старт(); 48 | КонецЕсли; 49 | 50 | КонецПроцедуры -------------------------------------------------------------------------------- /src/Классы/КонструкторыПараметров.os: -------------------------------------------------------------------------------- 1 | 2 | &Желудь 3 | Процедура ПриСозданииОбъекта() 4 | 5 | КонецПроцедуры 6 | 7 | Функция СформироватьПараметрыТочкиМаршрута(Действие, ТребуемыеПараметры, ВходящийЗапрос, Ответ, Сессия) Экспорт 8 | 9 | ЗначенияПараметров = ЗначенияПараметровДляТочкиМаршрута(ВходящийЗапрос, Ответ, Сессия); 10 | 11 | Если Действие.УрлСодержитШаблон Тогда 12 | ПутьСПараметрами = ПараметрыИзУрлаСШаблоном(ВходящийЗапрос.Путь, Действие.АдресКонтроллера); 13 | ДополнитьЗначениямиПараметровУРЛ(Действие.ПараметрыУРЛ, ПутьСПараметрами, ЗначенияПараметров); 14 | КонецЕсли; 15 | 16 | Возврат СформироватьМассивНеобходимыхПараметров(ТребуемыеПараметры, ЗначенияПараметров); 17 | 18 | КонецФункции 19 | 20 | Функция ПараметрыИзУрлаСШаблоном(Путь, АдресКонтроллера) 21 | Если АдресКонтроллера = "/" Тогда 22 | Возврат Сред(Путь, 2); 23 | Иначе 24 | Возврат СтрЗаменить(Путь, АдресКонтроллера + "/", ""); 25 | КонецЕсли; 26 | КонецФункции 27 | 28 | Функция СформироватьМассивНеобходимыхПараметров(ТребуемыеПараметры, Значения) Экспорт 29 | Результат = Новый Массив(); 30 | 31 | Для Каждого Параметр из ТребуемыеПараметры Цикл 32 | Результат.Добавить(Значения.Получить(Параметр)); 33 | КонецЦикла; 34 | 35 | Возврат Результат; 36 | КонецФункции 37 | 38 | Процедура ДополнитьЗначениямиПараметровУРЛ(ПараметрыУРЛ, Путь, ЗначенияПараметров) 39 | ПутьВМассив = СтрРазделить(Путь, "/"); 40 | 41 | Для каждого ТекПараметрУРЛ Из ПараметрыУРЛ Цикл 42 | 43 | Если ТекПараметрУРЛ.Ключ <= ПутьВМассив.ВГраница() Тогда 44 | ЗначенияПараметров.Вставить(ТекПараметрУРЛ.Значение, ПутьВМассив[ТекПараметрУРЛ.Ключ]); 45 | Иначе 46 | ЗначенияПараметров.Вставить(ТекПараметрУРЛ.Значение); 47 | КонецЕсли; 48 | 49 | КонецЦикла; 50 | КонецПроцедуры 51 | 52 | Функция ЗначенияПараметровДляТочкиМаршрута(ВходящийЗапрос, Ответ, Сессия) 53 | Значения = Новый Соответствие(); 54 | ДополнитьСоответствие(Значения, ВходящийЗапрос.ЗначенияПараметровДляТочкиМаршрута()); 55 | ДополнитьСоответствие(Значения, Ответ.ЗначенияПараметровДляТочкиМаршрута()); 56 | ДополнитьСоответствие(Значения, Сессия.ЗначенияПараметровДляТочкиМаршрута()); 57 | Возврат Значения; 58 | КонецФункции 59 | 60 | Процедура ДополнитьСоответствие(Приемник, Источник) 61 | Для Каждого КиЗ Из Источник Цикл 62 | Приемник.Вставить(КиЗ.Ключ, КиЗ.Значение); 63 | КонецЦикла; 64 | КонецПроцедуры -------------------------------------------------------------------------------- /src/Классы/КонтрольСоединенийСерверныхСобытий.os: -------------------------------------------------------------------------------- 1 | 2 | Перем ИнтервалПроверки; 3 | Перем Сообщение; 4 | Перем Проверять; 5 | 6 | &Пластилин 7 | Перем СоединенияСерверныхСобытий; 8 | &Пластилин 9 | Перем БрокерСообщенийСобытийСервера; 10 | 11 | &Желудь 12 | Процедура ПриСозданииОбъекта(&Пластилин Настройки, &Пластилин ФабрикаОтветов) 13 | ИнтервалПроверки = Настройки.ИнтервалПроверкиСоединенийСерверныхСобытий; 14 | 15 | Сообщение = ПолучитьДвоичныеДанныеИзСтроки(ФабрикаОтветов.СерверноеСобытие() 16 | .ТипСобытия("ping") 17 | .ДобавитьСтроку("") 18 | .Сформировать()); 19 | 20 | КонецПроцедуры 21 | 22 | Процедура Старт() Экспорт 23 | 24 | Если Проверять = Истина Тогда 25 | Возврат; 26 | КонецЕсли; 27 | 28 | Проверять = Истина; 29 | ФоновыеЗадания.Выполнить(ЭтотОбъект, "ПроверятьВЦикле"); 30 | КонецПроцедуры 31 | 32 | Процедура Стоп() Экспорт 33 | Проверять = Ложь; 34 | КонецПроцедуры 35 | 36 | Процедура ПроверятьВЦикле() Экспорт 37 | 38 | Пока Проверять Цикл 39 | Приостановить(ИнтервалПроверки); 40 | Попытка 41 | НайтиИУдалитьСоединения(); 42 | Исключение 43 | Сообщить("Что-то пошло нетак в проверке соединений SSE " + ОписаниеОшибки()); 44 | КонецПопытки; 45 | 46 | КонецЦикла; 47 | 48 | КонецПроцедуры 49 | 50 | Процедура НайтиИУдалитьСоединения() 51 | 52 | ПулСоеднинений = СоединенияСерверныхСобытий.ПулСоединений(); 53 | ИдСоединенийКУдалению = Новый Массив(); 54 | Для Каждого СтрокаСоединения из ПулСоеднинений Цикл 55 | Если НЕ СоединениеАктивно(СтрокаСоединения.Соединение) Тогда 56 | ИдСоединенийКУдалению.Добавить(СтрокаСоединения.ИдСоединения); 57 | КонецЕсли; 58 | КонецЦикла; 59 | 60 | Для Каждого ИдСоединения из ИдСоединенийКУдалению Цикл 61 | СоединенияСерверныхСобытий.УдалитьСтрокуПулаПоИдСоединения(ИдСоединения); 62 | КонецЦикла; 63 | 64 | КонецПроцедуры 65 | 66 | Функция СоединениеАктивно(Соединение) 67 | Возврат БрокерСообщенийСобытийСервера.ОтправитьВПопытке(Соединение, Сообщение); 68 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/Кука.os: -------------------------------------------------------------------------------- 1 | Перем Имя Экспорт; 2 | Перем Значение Экспорт; 3 | Перем ТолькоХттп Экспорт; 4 | Перем ДатаИстечения Экспорт; 5 | Перем СрокЖизни Экспорт; 6 | Перем Путь Экспорт; 7 | Перем ТотжеСайт Экспорт; 8 | 9 | 10 | &Желудь 11 | &Характер("Компанейский") 12 | &ОсобоеОбращение(ОтключитьВсеНапильники = Истина) 13 | Процедура ПриСозданииОбъекта() 14 | 15 | ТолькоХттп = Истина; 16 | Путь = "/"; 17 | ТотжеСайт = "Lax"; 18 | 19 | КонецПроцедуры 20 | 21 | -------------------------------------------------------------------------------- /src/Классы/Куки.os: -------------------------------------------------------------------------------- 1 | Перем Поделка; 2 | Перем Куки; 3 | 4 | &Желудь 5 | &Характер("Компанейский") 6 | &ОсобоеОбращение(ОтключитьВсеНапильники = Истина) 7 | Процедура ПриСозданииОбъекта( 8 | &Пластилин("Поделка") _Поделка 9 | ) 10 | Поделка = _Поделка; 11 | Куки = Новый Соответствие(); 12 | КонецПроцедуры 13 | 14 | Функция Добавить(Имя, Значение) Экспорт 15 | 16 | НоваяКука = Поделка.НайтиЖелудь("Кука"); 17 | НоваяКука.Имя = Имя; 18 | НоваяКука.Значение = Значение; 19 | 20 | Куки.Вставить(Имя, НоваяКука); 21 | 22 | Возврат НоваяКука; 23 | 24 | КонецФункции 25 | 26 | Функция Получить() Экспорт 27 | Возврат Новый ФиксированноеСоответствие(Куки); 28 | КонецФункции 29 | 30 | Функция ПолучитьЗначениеПоИмени(Имя) Экспорт 31 | Кука = Куки.Получить(Имя); 32 | Если Кука = Неопределено Тогда 33 | Возврат Неопределено; 34 | Иначе 35 | Возврат Кука.Значение; 36 | КонецЕсли; 37 | КонецФункции 38 | 39 | Функция ПолучитьМассивСтрокКук() Экспорт 40 | Массив = Новый Массив(); 41 | 42 | Для Каждого КиЗ из Куки Цикл 43 | Массив.Добавить(КукаВСтроку(КиЗ.Значение)); 44 | КонецЦикла; 45 | 46 | Возврат Массив; 47 | КонецФункции 48 | 49 | Функция ПреобразоватьДатуДляКуки(Знач Дата) 50 | Дата = УниверсальноеВремя(Дата); 51 | Возврат Формат(Дата, "Л=en; ДФ='ддд, дд МММ гггг ЧЧ:мм:сс ''GMT'''"); 52 | КонецФункции 53 | 54 | Функция КукаВСтроку(Кука) Экспорт 55 | 56 | Результат = Новый Массив(); 57 | Результат.Добавить(СтрШаблон("Set-Cookie: %1=%2", Кука.Имя, Кука.Значение)); 58 | 59 | Если Кука.ТолькоХттп = Истина Тогда 60 | Результат.Добавить("HttpOnly"); 61 | КонецЕсли; 62 | 63 | Если ЗначениеЗаполнено(Кука.ДатаИстечения) Тогда 64 | Результат.Добавить(СтрШаблон("Expires=%1", ПреобразоватьДатуДляКуки(Кука.ДатаИстечения))); 65 | КонецЕсли; 66 | 67 | Если ЗначениеЗаполнено(Кука.СрокЖизни) Тогда 68 | Результат.Добавить(СтрШаблон("Max-Age=%1", Кука.СрокЖизни)); 69 | КонецЕсли; 70 | 71 | Если ЗначениеЗаполнено(Кука.Путь) Тогда 72 | Результат.Добавить(СтрШаблон("Path=%1", Кука.Путь)); 73 | КонецЕсли; 74 | 75 | Если ЗначениеЗаполнено(Кука.ТотжеСайт) Тогда 76 | Результат.Добавить(СтрШаблон("SameSite=%1", Кука.ТотжеСайт)); 77 | КонецЕсли; 78 | 79 | Возврат СтрСоединить(Результат, ";"); 80 | 81 | КонецФункции 82 | 83 | -------------------------------------------------------------------------------- /src/Классы/Маршрутизатор.os: -------------------------------------------------------------------------------- 1 | Перем ДеревоМаршрутов; 2 | Перем ПодпискиВебСокетов; 3 | 4 | &Желудь 5 | Процедура ПриСозданииОбъекта(&Пластилин Перечисления) 6 | 7 | ДеревоМаршрутов = Новый ДеревоЗначений(); 8 | ДеревоМаршрутов.Колонки.Добавить("ТочкаМаршрута"); 9 | ДеревоМаршрутов.Колонки.Добавить("Действие"); 10 | ДеревоМаршрутов.Колонки.Добавить("ПолныйПуть"); 11 | 12 | ПодпискиВебСокетов = Новый Соответствие(); 13 | 14 | Для Каждого КиЗ из Перечисления.ВидыПодписокВебСокета Цикл 15 | ПодпискиВебСокетов.Вставить(КиЗ.Ключ, Новый Соответствие()); 16 | КонецЦикла; 17 | 18 | КонецПроцедуры 19 | 20 | Процедура ДобавитьМаршрут(ПолныйПуть, Действие) Экспорт 21 | 22 | МассивТочек = МассивТочекИзПути(ПолныйПуть); 23 | 24 | СтрокиМаршрута = ДеревоМаршрутов.Строки; 25 | 26 | Для Каждого ТекТочка Из МассивТочек Цикл 27 | СтрокаМаршрута = НайтиИлиСоздатьСтрокуВСтроках(СтрокиМаршрута, ТекТочка); 28 | СтрокиМаршрута = СтрокаМаршрута.Строки; 29 | КонецЦикла; 30 | 31 | СтрокаМаршрута.Действие = Действие; 32 | СтрокаМаршрута.ПолныйПуть = ПолныйПуть; 33 | 34 | КонецПроцедуры 35 | 36 | Процедура ДобавитьПодписку(ВидПодписки, Топик, Объект, Метод, Параметры) Экспорт 37 | ПодпискиВебСокетов[ВидПодписки].Вставить(Топик, 38 | Новый Структура("Объект, Метод, Параметры", Объект, Метод, Параметры)); 39 | КонецПроцедуры 40 | 41 | Функция ПолучитьПодписки(ВидПодписки) Экспорт 42 | Возврат ПодпискиВебСокетов[ВидПодписки]; 43 | КонецФункции 44 | 45 | Функция НайтиИлиСоздатьСтрокуВСтроках(Строки, ТочкаМаршрута) 46 | 47 | ИскомаяСтрока = Строки.Найти(ТочкаМаршрута, "ТочкаМаршрута"); 48 | 49 | Если ИскомаяСтрока = Неопределено Тогда 50 | НоваяСтрока = Строки.Добавить(); 51 | НоваяСтрока.ТочкаМаршрута = ТочкаМаршрута; 52 | Возврат НоваяСтрока; 53 | Иначе 54 | Возврат ИскомаяСтрока; 55 | КонецЕсли; 56 | 57 | КонецФункции 58 | 59 | Функция МассивТочекИзПути(ПолныйПуть) 60 | 61 | Массив = Новый Массив(); 62 | Массив.Добавить("/"); 63 | Для Каждого ТекТочка из СтрРазделить(ПолныйПуть, "/", Ложь) Цикл 64 | Массив.Добавить(ТекТочка); 65 | КонецЦикла; 66 | 67 | Возврат Массив; 68 | 69 | КонецФункции 70 | 71 | Функция НайтиОбработчикИПараметрыПоПолномуПути(ПолныйПуть) Экспорт 72 | 73 | Структура = Новый Структура("Действие, Параметры", Неопределено, Новый Массив()); 74 | 75 | ТочкиМаршрута = МассивТочекИзПути(ПолныйПуть); 76 | 77 | СтрокиМаршрута = ДеревоМаршрутов.Строки; 78 | 79 | СчетчикПути = 0; 80 | 81 | ИскомоеДействие = НайтиОбработчикРекурсивно(СтрокиМаршрута, ТочкиМаршрута, СчетчикПути); 82 | 83 | Если СчетчикПути = 0 И ТочкиМаршрута.Количество() > 1 Тогда 84 | Возврат Структура; 85 | КонецЕсли; 86 | 87 | Структура.Действие = ИскомоеДействие; 88 | 89 | Для Сч = СчетчикПути + 1 По ТочкиМаршрута.ВГраница() Цикл 90 | Структура.Параметры.Добавить(ТочкиМаршрута[Сч]); 91 | КонецЦикла; 92 | 93 | Возврат Структура; 94 | 95 | КонецФункции 96 | 97 | Функция НайтиОбработчикРекурсивно(Строки, ТочкиМаршрута, СчетчикПути) 98 | 99 | Если СчетчикПути >= ТочкиМаршрута.Количество() Тогда 100 | Возврат Неопределено; 101 | КонецЕсли; 102 | 103 | ТекущаяТочка = ТочкиМаршрута[СчетчикПути]; 104 | 105 | НайденнаяСтрока = Строки.Найти(ТекущаяТочка, "ТочкаМаршрута"); 106 | 107 | Если НайденнаяСтрока = Неопределено Тогда 108 | НайденнаяСтрока = Строки.Найти(СимволПараметраТочкиМаршрута(), "ТочкаМаршрута"); 109 | КонецЕсли; 110 | 111 | Если НайденнаяСтрока = Неопределено Тогда 112 | Возврат Неопределено; 113 | КонецЕсли; 114 | 115 | ДействиеНаЭтомУровне = Неопределено; 116 | СчетчикПутиНаЭтомУромне = СчетчикПути; 117 | 118 | Если ЗначениеЗаполнено(НайденнаяСтрока.Действие) Тогда 119 | ДействиеНаЭтомУровне = НайденнаяСтрока.Действие; 120 | КонецЕсли; 121 | 122 | Если НЕ НайденнаяСтрока.Строки.Количество() = 0 Тогда 123 | 124 | СчетчикПути = СчетчикПути + 1; 125 | ДействиеНаСледующемУровне = НайтиОбработчикРекурсивно(НайденнаяСтрока.Строки, ТочкиМаршрута, СчетчикПути); 126 | 127 | Если Не ДействиеНаСледующемУровне = Неопределено Тогда 128 | ДействиеНаЭтомУровне = ДействиеНаСледующемУровне; 129 | Иначе 130 | СчетчикПути = СчетчикПутиНаЭтомУромне; 131 | КонецЕсли; 132 | 133 | КонецЕсли; 134 | 135 | Возврат ДействиеНаЭтомУровне; 136 | 137 | КонецФункции 138 | 139 | Функция СимволПараметраТочкиМаршрута() Экспорт 140 | Возврат "%*anyparam*%"; 141 | КонецФункции 142 | 143 | Функция ОписаниеТочкиМаршрута() Экспорт 144 | 145 | Действие = Новый Структура("УрлСодержитШаблон, АдресКонтроллера, Желудь, ИмяМетода, Параметры, ПараметрыУРЛ, Шаблон, МетодШаблона, ПараметрыШаблона, ВыводитьШаблонКонтрола" 146 | , Ложь, ""); 147 | Возврат Действие; 148 | 149 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/МенеджерВходящихСоединений.os: -------------------------------------------------------------------------------- 1 | 2 | &Пластилин Перем Настройки; 3 | &Пластилин Перем ПарсерЗапросов; 4 | &Пластилин Перем СоединенияВебСокетов; 5 | &Пластилин Перем СоединенияСерверныхСобытий; 6 | 7 | &Желудь 8 | Процедура ПриСозданииОбъекта() 9 | 10 | КонецПроцедуры 11 | 12 | Функция ПринятьСоединение(Соединение, ДвоичныеДанныеЗапроса) Экспорт 13 | 14 | Результат = ПарсерЗапросов.ОбработатьДвоичныеДанные(ДвоичныеДанныеЗапроса, Соединение.УдаленныйУзел); 15 | 16 | Если Результат.ЗакрыватьСоединение = Ложь Тогда 17 | СохранитьСоединение(Соединение, Результат.ТипСоединения, Результат.Идентификатор, Результат.Топик); 18 | КонецЕсли; 19 | 20 | Возврат Результат; 21 | 22 | КонецФункции 23 | 24 | Процедура СохранитьСоединение(Соединение, ТипСоединения, Идентификатор, Топик) 25 | 26 | Если ТипСоединения = "ВС" Тогда 27 | СоединенияВебСокетов.Добавить(Соединение, Идентификатор, Топик); 28 | ИначеЕсли ТипСоединения = "СС" Тогда 29 | СоединенияСерверныхСобытий.Добавить(Соединение, Идентификатор, Топик); 30 | КонецЕсли; 31 | 32 | КонецПроцедуры -------------------------------------------------------------------------------- /src/Классы/МенеджерДоступа.os: -------------------------------------------------------------------------------- 1 | Перем Токены; 2 | Перем ТаблицаЛогиновИРолей; 3 | Перем ТаблицаРолейТочекМаршрутов; 4 | Перем ПерваяСоль; 5 | Перем ВтораяСоль; 6 | 7 | &Пластилин Перем Парсеры; 8 | 9 | Процедура ДобавитьТокен(Логин, Токен) Экспорт 10 | Токены.Вставить(Логин, ЗасолитьТокен(Токен)); 11 | КонецПроцедуры 12 | 13 | Процедура ДобавитьРольЛогина(Логин, Роль) Экспорт 14 | НоваяРольЛогина = ТаблицаЛогиновИРолей.Добавить(); 15 | НоваяРольЛогина.Логин = Логин; 16 | НоваяРольЛогина.Роль = Роль; 17 | КонецПроцедуры 18 | 19 | Процедура ДобавитьРольТочкиМаршрута(Действие, Роль) Экспорт 20 | НоваяРольТочкиМаршрута = ТаблицаРолейТочекМаршрутов.Добавить(); 21 | НоваяРольТочкиМаршрута.Действие = Действие; 22 | НоваяРольТочкиМаршрута.Роль = Роль; 23 | КонецПроцедуры 24 | 25 | Процедура ДобавитьРолиТочкиДоступаСписком(Действие, СписокРолей) Экспорт 26 | Для Каждого ТекущаяРоль из СтрРазделить(СписокРолей, ",") Цикл 27 | ДобавитьРольТочкиМаршрута(Действие, СокрЛП(ТекущаяРоль)); 28 | КонецЦикла; 29 | КонецПроцедуры 30 | 31 | Функция РольДоступна(Логин, Роль) Экспорт 32 | Возврат ТаблицаЛогиновИРолей.НайтиСтроки(Новый Структура("Логин, Роль", Логин, Роль)).Количество() > 0; 33 | КонецФункции 34 | 35 | Функция ТочкаМаршрутаДоступна(Логин, Действие) Экспорт 36 | 37 | РолиТочкиМаршрута = ТаблицаРолейТочекМаршрутов.НайтиСтроки(Новый Структура("Действие", Действие)); 38 | 39 | Для Каждого ТекущаяРоль из РолиТочкиМаршрута Цикл 40 | Если РольДоступна(Логин, ТекущаяРоль.Роль) Тогда 41 | Возврат Истина; 42 | КонецЕсли; 43 | КонецЦикла; 44 | 45 | Возврат Ложь; 46 | 47 | КонецФункции 48 | 49 | Функция ТокенВалидный(Логин, Токен) Экспорт 50 | Возврат Токены[Логин] = ЗасолитьТокен(Токен); 51 | КонецФункции 52 | 53 | Функция ТочкаМаршрутаИмеетРоли(Действие) Экспорт 54 | Возврат НЕ ТаблицаРолейТочекМаршрутов.Найти(Действие, "Действие") = Неопределено; 55 | КонецФункции 56 | 57 | &Желудь 58 | Процедура ПриСозданииОбъекта() 59 | Инициализация(); 60 | КонецПроцедуры 61 | 62 | Процедура Инициализация() 63 | Токены = Новый Соответствие(); 64 | ТаблицаЛогиновИРолей = Новый ТаблицаЗначений(); 65 | ТаблицаРолейТочекМаршрутов = Новый ТаблицаЗначений(); 66 | 67 | ТаблицаЛогиновИРолей.Колонки.Добавить("Логин"); 68 | ТаблицаЛогиновИРолей.Колонки.Добавить("Роль"); 69 | 70 | ТаблицаРолейТочекМаршрутов.Колонки.Добавить("Действие"); 71 | ТаблицаРолейТочекМаршрутов.Колонки.Добавить("Роль"); 72 | 73 | ПерваяСоль = Строка(Новый УникальныйИдентификатор()); 74 | ВтораяСоль = Строка(Новый УникальныйИдентификатор()); 75 | КонецПроцедуры 76 | 77 | Функция ХешироватьСтроку(Строка) 78 | 79 | Хеширование = Новый ХешированиеДанных(ХешФункция.MD5); 80 | 81 | Хеширование.Добавить(Строка); 82 | 83 | Возврат Base64Строка(Хеширование.ХешСумма); 84 | 85 | КонецФункции 86 | 87 | Функция ЗасолитьТокен(Знач Токен) 88 | Возврат ХешироватьСтроку(СтрШаблон("%1%2%3", ПерваяСоль, ХешироватьСтроку(Токен), ВтораяСоль)); 89 | КонецФункции 90 | 91 | Функция ПолучитьАвторизационныеДанныеПоСтрокеЗаголовка(знач СтрокаЗаголовкаАвторизациии) Экспорт 92 | 93 | СтрокаЗаголовкаАвторизациии = СокрЛП(СтрокаЗаголовкаАвторизациии); 94 | Результат = Новый Структура("Логин, Токен", "", ""); 95 | 96 | Если СтрНачинаетсяС(СтрокаЗаголовкаАвторизациии, "Basic") Тогда 97 | СтрокаАвторизации = ПолучитьСтрокуИзДвоичныхДанных(Base64Значение(СтрЗаменить(СтрокаЗаголовкаАвторизациии, "Basic ", ""))); 98 | Разделенные = Парсеры.РазделитьСтроку(СтрокаАвторизации, ":"); 99 | Результат.Логин = СокрЛП(Разделенные.Лево); 100 | Результат.Токен = СокрЛП(Разделенные.Право); 101 | КонецЕсли; 102 | 103 | Возврат Результат; 104 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/МенеджерОтображений.os: -------------------------------------------------------------------------------- 1 | Перем ОтображенияДействий; 2 | Перем Отображения; 3 | 4 | &Желудь 5 | Процедура ПриСозданииОбъекта() 6 | 7 | ОтображенияДействий = Новый Соответствие(); 8 | Отображения = Новый Соответствие(); 9 | УстановитьСтандартныеШаблоны(); 10 | 11 | КонецПроцедуры 12 | 13 | Процедура ДобавитьОтображениеДействия(Действие, ПутьДоФайла) Экспорт 14 | 15 | ДобавитьОтображениеИзФайла(ПутьДоФайла); 16 | ОтображенияДействий.Вставить(Действие, ПутьДоФайла); 17 | 18 | КонецПроцедуры 19 | 20 | Процедура УстановитьСтандартныеШаблоны() 21 | УстановитьШаблон401(СтандартныйШаблон()); 22 | УстановитьШаблон403(СтандартныйШаблон()); 23 | УстановитьШаблон404(СтандартныйШаблон()); 24 | УстановитьШаблон500(СтандартныйШаблон()); 25 | КонецПроцедуры 26 | 27 | Процедура УстановитьШаблон401(Текст) Экспорт 28 | УстановитьОтображение(401, Текст); 29 | КонецПроцедуры 30 | 31 | Процедура УстановитьШаблон403(Текст) Экспорт 32 | УстановитьОтображение(403, Текст); 33 | КонецПроцедуры 34 | 35 | Процедура УстановитьШаблон404(Текст) Экспорт 36 | УстановитьОтображение(404, Текст); 37 | КонецПроцедуры 38 | 39 | Процедура УстановитьШаблон500(Текст) Экспорт 40 | УстановитьОтображение(500, Текст); 41 | КонецПроцедуры 42 | 43 | Функция СтандартныйШаблон() 44 | Возврат " 45 | |

{{ Модель.КодСостояния }}

46 | |
{{ Модель.ТекстСообщения }}
"; 47 | КонецФункции 48 | 49 | Функция ДобавитьОтображениеИзФайла(ПутьДоФайла) Экспорт 50 | 51 | Текст = ПолучитьОтображениеИзФайла(ПутьДоФайла); 52 | УстановитьОтображение(ПутьДоФайла, Текст); 53 | 54 | Возврат Текст; 55 | 56 | КонецФункции 57 | 58 | Процедура УстановитьОтображение(ПутьДоФайла, Текст) 59 | Отображения.Вставить(ПутьДоФайла, Текст); 60 | КонецПроцедуры 61 | 62 | Функция ПолучитьОтображениеДействия(Действие) Экспорт 63 | 64 | ПутьДоФайла = ОтображенияДействий.Получить(Действие); 65 | 66 | Если не ЗначениеЗаполнено(ПутьДоФайла) Тогда 67 | Возврат Неопределено; 68 | КонецЕсли; 69 | 70 | Возврат Отображения[ПутьДоФайла]; 71 | 72 | КонецФункции 73 | 74 | Функция ПолучитьОтображение(ПутьДоФайла) Экспорт 75 | 76 | Отображение = Отображения[ПутьДоФайла]; 77 | 78 | Если Отображение = Неопределено Тогда 79 | Отображение = ДобавитьОтображениеИзФайла(ПутьДоФайла); 80 | КонецЕсли; 81 | 82 | Возврат Отображение; 83 | 84 | КонецФункции 85 | 86 | Функция ПолучитьОтображениеИзФайла(ПутьДоФайла) Экспорт 87 | 88 | Файл = Новый Файл(ПутьДоФайла); 89 | Если Файл.Существует() Тогда 90 | Чтение = Новый ЧтениеТекста(); 91 | Чтение.Открыть(ПутьДоФайла, КодировкаТекста.UTF8); 92 | Текст = Чтение.Прочитать(); 93 | Чтение.Закрыть(); 94 | 95 | Возврат Текст; 96 | Иначе 97 | ВызватьИсключение СтрШаблон("Файл отображения не существует %1", ПутьДоФайла); 98 | КонецЕсли; 99 | 100 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/МенеджерСессий.os: -------------------------------------------------------------------------------- 1 | Перем Сессии; 2 | Перем Поделка; 3 | 4 | &Желудь 5 | Процедура ПриСозданииОбъекта( 6 | &Пластилин("Поделка") _Поделка 7 | ) 8 | Поделка = _Поделка; 9 | Сессии = Новый Соответствие(); 10 | КонецПроцедуры 11 | 12 | Функция НоваяСессия() 13 | 14 | Возврат Поделка.НайтиЖелудь("СессияПользователя"); 15 | 16 | КонецФункции 17 | 18 | Функция ПолучитьСессиюПоИдентификатору(Идентификатор) Экспорт 19 | ТекСессия = Сессии.Получить(Идентификатор); 20 | Если ТекСессия = Неопределено Тогда 21 | ТекСессия = НоваяСессия(); 22 | Сессии.Вставить(ТекСессия.Идентификатор(), ТекСессия); 23 | КонецЕсли; 24 | Возврат ТекСессия; 25 | КонецФункции 26 | 27 | Функция ПолучитьСессиюПоКукам(Куки) Экспорт 28 | ИдСессии = Куки.ПолучитьЗначениеПоИмени(ИмяКукаСессии()); 29 | Возврат ПолучитьСессиюПоИдентификатору(ИдСессии); 30 | КонецФункции 31 | 32 | Функция ИмяКукаСессии() Экспорт 33 | Возврат "SessionID"; 34 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/Настройки.os: -------------------------------------------------------------------------------- 1 | 2 | &Деталька(Значение = "winow.Порт", ЗначениеПоУмолчанию = 3333) 3 | Перем Порт Экспорт; 4 | 5 | &Деталька(Значение = "winow.ИмяХоста", ЗначениеПоУмолчанию = "localhost") 6 | Перем ИмяХоста Экспорт; 7 | 8 | &Деталька(Значение = "winow.ИспользоватьПрикладнойСервер", ЗначениеПоУмолчанию = Ложь) 9 | Перем ИспользоватьПрикладнойСервер Экспорт; 10 | 11 | &Деталька(Значение = "winow.ИнтервалПроверкиСоединенийСерверныхСобытий", ЗначениеПоУмолчанию = 5000) 12 | Перем ИнтервалПроверкиСоединенийСерверныхСобытий Экспорт; 13 | 14 | &Деталька(Значение = "winow.КаталогСПриложениями", ЗначениеПоУмолчанию = "./app") 15 | Перем КаталогСПриложениями Экспорт; 16 | 17 | &Деталька("winow.КаталогиСФайлами") 18 | Перем КаталогиСФайлами Экспорт; 19 | 20 | &Деталька(Значение = "winow.АвтоматическиПриводитьОбъектыКСтруктуре", ЗначениеПоУмолчанию = Истина) 21 | Перем АвтоматическиПриводитьОбъектыКСтруктуре Экспорт; 22 | 23 | &Деталька(Значение = "winow.ЗадержкаПередЧтениемСокета", ЗначениеПоУмолчанию = 0) 24 | Перем ЗадержкаПередЧтениемСокета Экспорт; 25 | 26 | &Деталька(Значение = "winow.ЗадержкаПередЗакрытиемСокета", ЗначениеПоУмолчанию = 0) 27 | Перем ЗадержкаПередЗакрытиемСокета Экспорт; 28 | 29 | &Деталька(Значение = "winow.РазмерБуфера", ЗначениеПоУмолчанию = 1024) 30 | Перем РазмерБуфера Экспорт; 31 | 32 | &Желудь 33 | Процедура ПриСозданииОбъекта() 34 | 35 | КонецПроцедуры 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/Классы/НативныйВебСервер.os: -------------------------------------------------------------------------------- 1 | 2 | &Пластилин 3 | Перем Настройки; 4 | 5 | &Пластилин 6 | Перем МенеджерСессий; 7 | 8 | &Пластилин 9 | &Табакерка 10 | Перем ВходящийЗапрос; 11 | 12 | &Пластилин 13 | Перем ОбработчикЗапросов; 14 | 15 | Перем ВебСервер; 16 | 17 | &Желудь 18 | Процедура ПриСозданииОбъекта() 19 | 20 | КонецПроцедуры 21 | 22 | Процедура Старт() Экспорт 23 | 24 | ЗапуститьСинхронно(); 25 | 26 | КонецПроцедуры 27 | 28 | Процедура ЗапуститьСинхронно() Экспорт 29 | ВебСервер = Новый ВебСервер(Настройки.Порт); 30 | ВебСервер.ДобавитьОбработчикЗапросов(ЭтотОбъект, "ОбработатьЗапрос"); 31 | ВебСервер.Запустить(); 32 | КонецПроцедуры 33 | 34 | Процедура ОбработатьЗапрос(Контекст, СледующийОбработчик) Экспорт // BSLLS:UnusedParameters-off 35 | 36 | Запрос = ЗапросИзКонтекста(Контекст); 37 | 38 | ОтветВино = ОбработчикЗапросов.СформироватьОтвет(Запрос); 39 | 40 | Ответ = ПодготовитьОтвет(ОтветВино); 41 | 42 | Заголовки = Ответ.ПолучитьЗаголовки(); 43 | Куки = Ответ.ПолучитьКуки(); 44 | 45 | Для Каждого Элемент Из Заголовки Цикл 46 | Контекст.Ответ.Заголовки[Элемент.Ключ] = Элемент.Значение; 47 | КонецЦикла; 48 | 49 | Для Каждого Кука Из Куки Цикл 50 | Контекст.Ответ.Куки.Добавить(Кука.Ключ, Кука.Значение.Значение, Кука.Значение.Параметры); 51 | КонецЦикла; 52 | 53 | Контекст.Ответ.КодСостояния = Ответ.ПолучитьКодСостояния(); 54 | 55 | БуферДвоичныхДанных = Ответ.ПолучитьТело(); 56 | 57 | Контекст.Ответ.Тело.Записать(БуферДвоичныхДанных, 0, БуферДвоичныхДанных.Размер); 58 | 59 | КонецПроцедуры 60 | 61 | Функция ПодготовитьОтвет(ОтветВино) 62 | Ответ = Новый ХттпОтвет; 63 | Ответ.КодСостояния(ОтветВино.СостояниеКод) 64 | .Заголовки(ОтветВино.Заголовки) 65 | .ТелоИзДвоичныхДанных(?(ОтветВино.ТелоДвоичныеДанные = Неопределено, 66 | ПолучитьДвоичныеДанныеИзСтроки(ОтветВино.ТелоТекст), 67 | ОтветВино.ТелоДвоичныеДанные)); 68 | 69 | Для Каждого Кука Из ОтветВино.Куки.Получить() Цикл 70 | ПараметрыКуки = Новый ПараметрыCookie; 71 | ПараметрыКуки.Путь = Кука.Значение.Путь; 72 | ПараметрыКуки.Истекает = Кука.Значение.ДатаИстечения; 73 | ПараметрыКуки.ТолькоHttp = Кука.Значение.ТолькоХттп; 74 | ПараметрыКуки.МаксимальныйВозраст = Кука.Значение.СрокЖизни; 75 | Ответ.Кука(Кука.Ключ, Кука.Значение.Значение, ПараметрыКуки); 76 | КонецЦикла; 77 | 78 | Возврат Ответ; 79 | КонецФункции 80 | 81 | Функция ЗапросИзКонтекста(Контекст) 82 | 83 | Запрос = ВходящийЗапрос.Достать(); 84 | Запрос.Метод = Контекст.Запрос.Метод; 85 | Для Каждого Заголовок из Контекст.Запрос.Заголовки Цикл 86 | Запрос.Заголовки.Вставить(Заголовок.Ключ, Заголовок.Значение); 87 | КонецЦикла; 88 | Для Каждого Кука Из Контекст.Запрос.Куки Цикл 89 | Запрос.Куки.Добавить(Кука.Ключ, Кука.Значение); 90 | КонецЦикла; 91 | 92 | Запрос.Путь = РаскодироватьСтроку(Контекст.Запрос.Путь, СпособКодированияСтроки.КодировкаURL); 93 | Запрос.ПолныйПуть = Контекст.Запрос.Путь + РаскодироватьСтроку(Контекст.Запрос.СтрокаПараметров,СпособКодированияСтроки.КодировкаURL); 94 | 95 | Если Контекст.Запрос.ЕстьФормыВТипеКонтента = Истина И 96 | СтрНачинаетсяС(НРег(Контекст.Запрос.ТипКонтента), "multipart/form-data") Тогда 97 | 98 | ДанныеФормы = Новый ДанныеСоставнойФормы(); 99 | Для Каждого ЭлементФормы Из Контекст.Запрос.Форма Цикл 100 | Структура = Новый Структура("Метаданные, Значение", Новый Соответствие); 101 | Структура.Метаданные.Вставить("name", ОбернутьВСоответствие("name",ЭлементФормы.Ключ)); 102 | Если ЭлементФормы.Значение.Количество() > 0 Тогда 103 | Структура.Значение = ПолучитьДвоичныеДанныеИзСтроки(ЭлементФормы.Значение[0]); 104 | КонецЕсли; 105 | ДанныеФормы.Добавить(Структура); 106 | КонецЦикла; 107 | 108 | Для Каждого ФайлФормы Из Контекст.Запрос.Форма.Файлы Цикл 109 | Структура = Новый Структура("Метаданные, Значение", Новый Соответствие); 110 | Структура.Метаданные.Вставить("ТипКонтента", ОбернутьВСоответствие("ТипКонтента",ФайлФормы.ТипКонтента)); 111 | Структура.Метаданные.Вставить("РасположениеКонтента", ОбернутьВСоответствие("РасположениеКонтента",ФайлФормы.РасположениеКонтента)); 112 | Структура.Метаданные.Вставить("name", ОбернутьВСоответствие("name",ФайлФормы.Имя)); 113 | Структура.Метаданные.Вставить("filename", ОбернутьВСоответствие("filename",ФайлФормы.ИмяФайла)); 114 | Заголовки = Новый Соответствие(); 115 | Для Каждого Заголовок Из ФайлФормы.Заголовки Цикл 116 | Заголовки.Вставить(Заголовок.Ключ, Заголовок.Значение); 117 | КонецЦикла; 118 | Структура.Метаданные.Вставить("Заголовки", ОбернутьВСоответствие("Заголовки", Заголовки)); 119 | 120 | Поток = ФайлФормы.ОткрытьПотокЧтения(); 121 | 122 | ЧтениеДанных = Новый ЧтениеДанных(Поток); 123 | Структура.Значение = ЧтениеДанных.Прочитать().ПолучитьДвоичныеДанные(); 124 | ДанныеФормы.Добавить(Структура); 125 | КонецЦикла; 126 | Запрос.УстановитьДанныеФормы(ДанныеФормы); 127 | Иначе 128 | 129 | ЧтениеДанных = Новый ЧтениеДанных(Контекст.Запрос.Тело); 130 | ДД = ЧтениеДанных.Прочитать().ПолучитьДвоичныеДанные(); 131 | 132 | Запрос.ТелоДвоичныеДанные = ДД; 133 | Запрос.Тело = ПолучитьСтрокуИзДвоичныхДанных(Запрос.ТелоДвоичныеДанные); 134 | 135 | КонецЕсли; 136 | 137 | Запрос.Сессия = МенеджерСессий.ПолучитьСессиюПоКукам(Запрос.Куки); 138 | 139 | Для Каждого Параметр Из Контекст.Запрос.Параметры Цикл 140 | Запрос.ПараметрыИменные.Вставить(Параметр.Ключ, Параметр.Значение); 141 | КонецЦикла; 142 | 143 | Возврат Запрос; 144 | 145 | КонецФункции 146 | 147 | Функция ОбернутьВСоответствие(Ключ, Значение) 148 | Соответствие = Новый Соответствие(); 149 | Соответствие.Вставить(Ключ, Значение); 150 | Возврат Соответствие; 151 | КонецФункции; 152 | -------------------------------------------------------------------------------- /src/Классы/ОбработчикЗапросов.os: -------------------------------------------------------------------------------- 1 | &Пластилин Перем Маршрутизатор; 2 | &Пластилин Перем ФабрикаОтветов; 3 | &Пластилин Перем МенеджерСессий; 4 | &Пластилин Перем МенеджерОтображений; 5 | &Пластилин Перем МенеджерДоступа; 6 | &Пластилин Перем Поделка; 7 | &Пластилин Перем КонструкторыПараметров; 8 | 9 | &ЛогВебСервера 10 | Перем Лог; 11 | 12 | Перем Рефлектор; 13 | 14 | &Желудь 15 | Процедура ПриСозданииОбъекта() 16 | Рефлектор = Новый Рефлектор(); 17 | КонецПроцедуры 18 | 19 | Функция СформироватьОтвет(Запрос) Экспорт 20 | 21 | ОбработчикИПараметры = Маршрутизатор.НайтиОбработчикИПараметрыПоПолномуПути(Запрос.Путь); 22 | 23 | Запрос.ПараметрыПорядковые = ОбработчикИПараметры.Параметры; 24 | 25 | Если ЗначениеЗаполнено(ОбработчикИПараметры.Действие) Тогда 26 | 27 | Сессия = Запрос.Сессия; 28 | 29 | ДействиеДоступно = Ложь; 30 | ЗапроситьТокен = Ложь; 31 | 32 | Если МенеджерДоступа.ТочкаМаршрутаИмеетРоли(ОбработчикИПараметры.Действие) Тогда 33 | Если ЗначениеЗаполнено(Сессия.Логин) и МенеджерДоступа.ТочкаМаршрутаДоступна(Сессия.Логин, ОбработчикИПараметры.Действие) Тогда 34 | ДействиеДоступно = Истина; 35 | 36 | ИначеЕсли ЗначениеЗаполнено(Сессия.Логин) и НЕ МенеджерДоступа.ТочкаМаршрутаДоступна(Сессия.Логин, ОбработчикИПараметры.Действие) Тогда 37 | ДействиеДоступно = Ложь; 38 | 39 | ИначеЕсли НЕ ЗначениеЗаполнено(Сессия.Логин) И Запрос.Заголовки["Authorization"] = Неопределено Тогда 40 | ДействиеДоступно = Ложь; 41 | ЗапроситьТокен = Истина; 42 | 43 | ИначеЕсли НЕ ЗначениеЗаполнено(Сессия.Логин) И НЕ Запрос.Заголовки["Authorization"] = Неопределено Тогда 44 | ДанныеАвторизации = РазобратьАвторизационныеДанные(Запрос.Заголовки["Authorization"]); 45 | 46 | Если ЗначениеЗаполнено(ДанныеАвторизации.Логин) И 47 | ЗначениеЗаполнено(ДанныеАвторизации.Токен) Тогда 48 | 49 | Если МенеджерДоступа.ТокенВалидный(ДанныеАвторизации.Логин, ДанныеАвторизации.Токен) Тогда 50 | Сессия.Логин = ДанныеАвторизации.Логин; 51 | ДействиеДоступно = МенеджерДоступа.ТочкаМаршрутаДоступна(Сессия.Логин, ОбработчикИПараметры.Действие); 52 | Иначе 53 | ДействиеДоступно = Ложь; 54 | ЗапроситьТокен = Истина; 55 | КонецЕсли; 56 | Иначе 57 | ДействиеДоступно = Ложь; 58 | ЗапроситьТокен = Истина; 59 | 60 | КонецЕсли 61 | 62 | КонецЕсли; 63 | Иначе 64 | ДействиеДоступно = Истина; 65 | КонецЕсли; 66 | 67 | Если ДействиеДоступно Тогда 68 | Ответ = АвторизованныйОтвет(Запрос, Сессия, ОбработчикИПараметры); 69 | ИначеЕсли Не ДействиеДоступно и ЗапроситьТокен Тогда 70 | Ответ = ФабрикаОтветов.НовыйОтвет401(); 71 | Ответ.Заголовки["WWW-Authenticate"] = "Basic"; 72 | Иначе 73 | Ответ = ФабрикаОтветов.НовыйОтвет403(); 74 | КонецЕсли; 75 | 76 | Иначе 77 | 78 | Ответ = ФабрикаОтветов.НовыйОтвет404(); 79 | Ответ.Модель = Новый Структура(); 80 | Ответ.Модель.Вставить("КодСостояния", 404); 81 | Ответ.Модель.Вставить("ТекстСообщения", "Страница не найдена"); 82 | Ответ.Модель.Вставить("Запрос", Запрос); 83 | Ответ.ОбработатьМодель(); 84 | 85 | КонецЕсли; 86 | 87 | Возврат Ответ; 88 | 89 | КонецФункции 90 | 91 | Функция РазобратьАвторизационныеДанные(знач СтрокаЗаголовкаАвторизациии) 92 | Возврат МенеджерДоступа.ПолучитьАвторизационныеДанныеПоСтрокеЗаголовка(СтрокаЗаголовкаАвторизациии); 93 | КонецФункции 94 | 95 | Функция АвторизованныйОтвет(Запрос, Сессия, ОбработчикИПараметры) 96 | 97 | Ответ = ФабрикаОтветов.НовыйОтвет(); 98 | Ответ.Куки.Добавить(МенеджерСессий.ИмяКукаСессии(), Сессия.Идентификатор()); 99 | 100 | Отображене = МенеджерОтображений.ПолучитьОтображениеДействия(ОбработчикИПараметры.Действие); 101 | Если ЗначениеЗаполнено(Отображене) Тогда 102 | Ответ.УстановитьТекстШаблона(Отображене); 103 | КонецЕсли; 104 | 105 | Попытка 106 | ПараметрыТочкиМаршрута = КонструкторыПараметров.СформироватьПараметрыТочкиМаршрута( 107 | ОбработчикИПараметры.Действие, 108 | ОбработчикИПараметры.Действие.Параметры, 109 | Запрос, 110 | Ответ, 111 | Сессия); 112 | 113 | Рефлектор.ВызватьМетод( ОбработчикИПараметры.Действие.Желудь, 114 | ОбработчикИПараметры.Действие.ИмяМетода, 115 | ПараметрыТочкиМаршрута); 116 | Ответ.ОбработатьМодель(); 117 | ОбработатьШаблонКонтрола(Ответ, ОбработчикИПараметры.Действие, Запрос, Сессия); 118 | Исключение 119 | ТекстОшибки = ОписаниеОшибки(); 120 | Лог.Ошибка(ТекстОшибки); 121 | Ответ = ФабрикаОтветов.НовыйОтвет500(); 122 | Ответ.Модель = Новый Структура(); 123 | Ответ.Модель.Вставить("КодСостояния", 500); 124 | Ответ.Модель.Вставить("ТекстСообщения", ТекстОшибки); 125 | Ответ.Модель.Вставить("Запрос", Запрос); 126 | Ответ.ОбработатьМодель(); 127 | КонецПопытки; 128 | 129 | Возврат Ответ; 130 | 131 | КонецФункции 132 | 133 | Процедура ОбработатьШаблонКонтрола(Ответ, Действие, Запрос, Сессия) 134 | Если Не ЗначениеЗаполнено(Действие.Шаблон) ИЛИ Действие.ВыводитьШаблонКонтрола = Ложь Тогда 135 | Возврат; 136 | КонецЕсли; 137 | Массив = Новый Массив(); 138 | Массив.Добавить(МенеджерОтображений.ПолучитьОтображение(Действие.Шаблон)); 139 | Шаблон = Поделка.НайтиЖелудь("Шаблон", Массив); 140 | 141 | Если ЗначениеЗаполнено(Действие.МетодШаблона) Тогда 142 | 143 | ПараметрыМетода = КонструкторыПараметров.СформироватьПараметрыТочкиМаршрута( 144 | Действие, 145 | Действие.ПараметрыШаблона, 146 | Запрос, 147 | Ответ, 148 | Сессия); 149 | 150 | Модель = Рефлектор.ВызватьМетод(Действие.Желудь, 151 | Действие.МетодШаблона, 152 | ПараметрыМетода); 153 | Иначе 154 | Модель = Неопределено; 155 | КонецЕсли; 156 | 157 | ТекстКонтрола = Шаблон.СформироватьТекст(Модель); 158 | 159 | Ответ.ТелоТекст = СтрЗаменить(ТекстКонтрола, "@Контент", Ответ.ТелоТекст); 160 | 161 | КонецПроцедуры 162 | -------------------------------------------------------------------------------- /src/Классы/ОбработчикСоединений.os: -------------------------------------------------------------------------------- 1 | &Пластилин Перем Настройки; 2 | &Пластилин Перем МенеджерВходящихСоединений; 3 | 4 | Перем ТаймаутЧтения; 5 | 6 | &ЛогВебСервера 7 | Перем Лог; 8 | 9 | &Желудь 10 | Процедура ПриСозданииОбъекта() 11 | ТаймаутЧтения = 10; 12 | КонецПроцедуры 13 | 14 | Процедура Обработать(Соединение) Экспорт 15 | 16 | Попытка 17 | ДанныеЗапроса = ПрочитатьДвоичныеДанныеИзСоединения(Соединение); 18 | Исключение 19 | ЗакрытьСоединениеВПопытке(Соединение); 20 | ТекстОшибки = ОписаниеОшибки(); 21 | Лог.Ошибка("Не удалось обработать входящее соединение: " + ТекстОшибки); 22 | Возврат; 23 | КонецПопытки; 24 | 25 | Результат = МенеджерВходящихСоединений.ПринятьСоединение(Соединение, ДанныеЗапроса); 26 | 27 | ОтправитьВПопытке(Соединение, Результат.Ответ); 28 | 29 | Если Результат.ЗакрыватьСоединение Тогда 30 | 31 | ЗакрытьСоединениеВПопытке(Соединение); 32 | 33 | КонецЕсли; 34 | 35 | КонецПроцедуры 36 | 37 | Функция ПрочитатьДвоичныеДанныеИзСоединения(Соединение) 38 | Если Настройки.ЗадержкаПередЧтениемСокета > 0 Тогда 39 | Приостановить(Настройки.ЗадержкаПередЧтениемСокета); 40 | КонецЕсли; 41 | 42 | ДанныеЗапроса = ВычитатьВПопыткеДвоичныеДанные(Соединение); 43 | 44 | Возврат ДанныеЗапроса; 45 | КонецФункции 46 | 47 | Функция ВычитатьВПопыткеДвоичныеДанные(Соединение) 48 | 49 | Данные = Новый Массив(); 50 | 51 | Попытка 52 | Пока Истина Цикл 53 | Соединение.ТаймаутЧтения = ТаймаутЧтения; 54 | ДанныеСоединения = Соединение.ПрочитатьДвоичныеДанные(Настройки.РазмерБуфера); 55 | Данные.Добавить(ДанныеСоединения); 56 | КонецЦикла; 57 | Исключение 58 | 59 | КонецПопытки; 60 | 61 | Возврат СоединитьДвоичныеДанные(Данные); 62 | 63 | КонецФункции 64 | 65 | Процедура ОтправитьВПопытке(Соединение, ДвоичныеДанныеОтвета) Экспорт 66 | Попытка 67 | Соединение.ОтправитьДвоичныеДанные(ДвоичныеДанныеОтвета); 68 | Исключение 69 | ТекстОшибки = ОписаниеОшибки(); 70 | Лог.Ошибка("Не удалось отправить ответ: " + ТекстОшибки); 71 | КонецПопытки; 72 | КонецПроцедуры 73 | 74 | Процедура ЗакрытьСоединениеВПопытке(Соединение) Экспорт 75 | Попытка 76 | // Некоторые клиенты ломаются, когда после отправки 77 | // в сокет данных сразу закрываемся. Ждем. 78 | Если Настройки.ЗадержкаПередЗакрытиемСокета > 0 Тогда 79 | Приостановить(Настройки.ЗадержкаПередЗакрытиемСокета); 80 | КонецЕсли; 81 | Соединение.Закрыть(); 82 | Исключение 83 | ТекстОшибки = ОписаниеОшибки(); 84 | Лог.Ошибка("Не удалось закрыть входящее соединение: " + ТекстОшибки); 85 | КонецПопытки; 86 | КонецПроцедуры -------------------------------------------------------------------------------- /src/Классы/Ответ.os: -------------------------------------------------------------------------------- 1 | Перем Перечисления; 2 | Перем Шаблон; 3 | 4 | Перем СостояниеКод Экспорт; 5 | Перем СостояниеТекст Экспорт; 6 | Перем Заголовки Экспорт; 7 | Перем ТелоТекст Экспорт; 8 | Перем ТелоДвоичныеДанные Экспорт; 9 | Перем Модель Экспорт; 10 | 11 | Перем Куки Экспорт; 12 | Перем Поделка; 13 | 14 | &Желудь 15 | &Характер("Компанейский") 16 | &ОсобоеОбращение(ОтключитьВсеНапильники = Истина) 17 | Процедура ПриСозданииОбъекта( 18 | &Пластилин("Перечисления") _Перечисления, 19 | &Пластилин("Куки") _Куки, 20 | &Пластилин("Поделка") _Поделка 21 | ) 22 | Перечисления = _Перечисления; 23 | Куки = _Куки; 24 | Поделка = _Поделка; 25 | СостояниеТекст = ""; 26 | СостояниеКод = ""; 27 | Заголовки = Новый Соответствие(); 28 | ТелоТекст = ""; 29 | КонецПроцедуры 30 | 31 | Функция ЗначенияПараметровДляТочкиМаршрута() Экспорт 32 | Результат = Новый Соответствие(); 33 | Результат.Вставить("Ответ", ЭтотОбъект); 34 | 35 | Возврат Результат; 36 | КонецФункции 37 | 38 | Процедура УстановитьТекстШаблона(ТекстШаблона) Экспорт 39 | Параметры = Новый Массив(); 40 | Параметры.Добавить(ТекстШаблона); 41 | Шаблон = Поделка.НайтиЖелудь("Шаблон", Параметры); 42 | КонецПроцедуры 43 | 44 | Процедура ОбработатьМодель() Экспорт 45 | 46 | Если ЗначениеЗаполнено(Шаблон) и ЗначениеЗаполнено(Шаблон.ТекстШаблона) Тогда 47 | ТелоТекст = Шаблон.СформироватьТекст(Модель); 48 | КонецЕсли; 49 | 50 | КонецПроцедуры 51 | 52 | Процедура УстановитьСостояние(КодСостояния) Экспорт 53 | СостояниеКод = КодСостояния; 54 | СостояниеТекст = Перечисления.СостоянияОтветов[КодСостояния]; 55 | КонецПроцедуры 56 | 57 | Процедура УстановитьСостояниеОК() Экспорт 58 | УстановитьСостояние(200); 59 | КонецПроцедуры 60 | 61 | Процедура УстановитьСостояниеНеАвторизован() Экспорт 62 | УстановитьСостояние(401); 63 | КонецПроцедуры 64 | 65 | Процедура УстановитьСостояниеДоступЗакрыт() Экспорт 66 | УстановитьСостояние(403); 67 | КонецПроцедуры 68 | 69 | Процедура УстановитьСостояниеНеНайдено() Экспорт 70 | УстановитьСостояние(404); 71 | КонецПроцедуры 72 | 73 | Процедура УстановитьСостояниеОшибка() Экспорт 74 | УстановитьСостояние(500); 75 | КонецПроцедуры 76 | 77 | Процедура УстановитьТипКонтента(ТипКонтента) Экспорт 78 | ОписаниеКонтента = Перечисления.ОписанияТиповРасширенийФайлов[ТипКонтента]; 79 | Если ОписаниеКонтента = Неопределено Тогда 80 | ВызватьИсключение СтрШаблон("Тип контента %1 не определен", ТипКонтента); 81 | КонецЕсли; 82 | 83 | Заголовки["Content-Type"] = ОписаниеКонтента; 84 | КонецПроцедуры 85 | 86 | Процедура Перенаправить(НовыйАдрес) Экспорт 87 | УстановитьСостояние(302); 88 | Заголовки["Location"] = НовыйАдрес; 89 | КонецПроцедуры -------------------------------------------------------------------------------- /src/Классы/ПарсерЗапросов.os: -------------------------------------------------------------------------------- 1 | Перем Поделка; 2 | Перем Перечисления; 3 | Перем Парсеры; 4 | Перем Настройки; 5 | 6 | &Пластилин Перем ОбработчикЗапросов; 7 | &Пластилин Перем ПодготовительОтветов; 8 | &Пластилин Перем МенеджерСессий; 9 | &Пластилин Перем ФабрикаОтветов; 10 | &Пластилин Перем ТопикиСерверныхСобытий; 11 | 12 | &Желудь 13 | Процедура ПриСозданииОбъекта( 14 | &Пластилин("Поделка") _Поделка, 15 | &Пластилин("Перечисления") _Перечисления, 16 | &Пластилин("Парсеры") _Парсеры, 17 | &Пластилин("Настройки") _Настройки 18 | ) 19 | Поделка = _Поделка; 20 | Перечисления = _Перечисления; 21 | Парсеры = _Парсеры; 22 | Настройки = _Настройки; 23 | КонецПроцедуры 24 | 25 | Функция ОбработатьДвоичныеДанные(ДвоичныеДанныеЗапроса, УдаленныйУзел) Экспорт 26 | 27 | Запрос = ПолучитьЗапросИзДвоичныхДанных(ДвоичныеДанныеЗапроса); 28 | 29 | УстановитьСессиюПоКукам(Запрос); 30 | УстановитьАдресИПортУдаленногоУзла(Запрос, УдаленныйУзел); 31 | 32 | Результат = СтруктураРезультатаПарсинга(); 33 | 34 | Если Запрос.ЭтоЗапросНаВебСокет() Тогда 35 | 36 | Результат.ТипСоединения = "ВС"; 37 | 38 | Ответ = ФабрикаОтветов.ОтветРукопожатияВебСокета(Запрос); 39 | 40 | Результат.Идентификатор = Запрос.Сессия.Идентификатор(); 41 | Результат.ЗакрыватьСоединение = Ложь; 42 | Результат.Топик = Запрос.Путь; 43 | 44 | ИначеЕсли Запрос.ЭтоЗапросНаСерверныеСобытия() Тогда 45 | 46 | Результат.ТипСоединения = "СС"; 47 | Если ТопикиСерверныхСобытий.Существует(Запрос.Путь) = Ложь Тогда 48 | Ответ = ФабрикаОтветов.НовыйОтвет404(); 49 | Иначе 50 | Результат.Идентификатор = Запрос.Сессия.Идентификатор(); 51 | Результат.ЗакрыватьСоединение = Ложь; 52 | Результат.Топик = Запрос.Путь; 53 | Ответ = ФабрикаОтветов.ПустойОтвет(); 54 | Ответ.УстановитьСостояниеОК(); 55 | Ответ.Заголовки["Content-Type"] = "text/event-stream; charset=utf-8"; 56 | КонецЕсли; 57 | 58 | Иначе 59 | Ответ = ОбработчикЗапросов.СформироватьОтвет(Запрос); 60 | КонецЕсли; 61 | 62 | Результат.Ответ = ПодготовительОтветов.ДвоичныеДанныеОтвета(Ответ); 63 | 64 | Возврат Результат; 65 | 66 | КонецФункции 67 | 68 | Функция ПолучитьЗапросИзДвоичныхДанных(ДвоичныеДанныеЗапроса) Экспорт 69 | 70 | Запрос = Поделка.НайтиЖелудь("ВходящийЗапрос"); 71 | 72 | ДанныеЗапроса = ДвоичныеДанныеЗапроса; 73 | 74 | РазделенныйЗапрос = Парсеры.РазделитьДвоичныеДанныеРазделителем(ДанныеЗапроса, 75 | Перечисления.ДвойнойРазделительДвоичнымиДанными); 76 | 77 | ТекстЗапроса = ПолучитьСтрокуИзДвоичныхДанных(РазделенныйЗапрос.Лево, "utf-8"); 78 | 79 | СтруктураЗапроса = РазобратьТексЗапроса(ТекстЗапроса); 80 | 81 | Запрос.ТекстЗапроса = ТекстЗапроса; 82 | Запрос.ДвоичныеДанные = ДанныеЗапроса; 83 | Запрос.ТелоДвоичныеДанные = РазделенныйЗапрос.Право; 84 | Если Не Запрос.ТелоДвоичныеДанные = Неопределено Тогда 85 | Запрос.Тело = ПолучитьСтрокуИзДвоичныхДанных(Запрос.ТелоДвоичныеДанные); 86 | КонецЕсли; 87 | 88 | ЗаполнитьЗначенияСвойств(Запрос, СтруктураЗапроса); 89 | 90 | Возврат Запрос; 91 | 92 | КонецФункции 93 | 94 | Функция РазобратьТексЗапроса(ТекстЗапроса) 95 | Результат = Новый Структура(); 96 | 97 | МассивСтрок = СтрРазделить(ТекстЗапроса, Символы.ПС, Ложь); 98 | 99 | Если МассивСтрок.Количество() > 0 Тогда 100 | ПерваяСтрока = СтрРазделить(МассивСтрок[0], " "); 101 | Результат.Вставить("Метод", ПерваяСтрока[0]); 102 | Результат.Вставить("ПолныйПуть", РаскодироватьСтроку(ПерваяСтрока[1],СпособКодированияСтроки.КодировкаURL)); 103 | 104 | ПутьИПараметры = Парсеры.РазделитьСтроку(ПерваяСтрока[1], "?"); 105 | 106 | Результат.Вставить("ПараметрыИменные", Парсеры.ПараметрыИзТекста(ПутьИПараметры.Право)); 107 | Результат.Вставить("Путь", РаскодироватьСтроку(ПутьИПараметры.Лево, СпособКодированияСтроки.КодировкаURL)); 108 | 109 | Заголовки = Новый Соответствие(); 110 | Результат.Вставить("Заголовки", Заголовки); 111 | 112 | Результат.Вставить("Куки", Поделка.НайтиЖелудь("Куки")); 113 | 114 | Для Сч = 1 По МассивСтрок.ВГраница() Цикл 115 | Если ПустаяСтрока(МассивСтрок[Сч]) Тогда 116 | Продолжить; 117 | КонецЕсли; 118 | 119 | ДанныеСтроки = РаспарситьСтрокуЗаголовка(МассивСтрок[Сч]); 120 | Имя = СокрЛП(ДанныеСтроки.Имя); 121 | Значение = СокрЛП(ДанныеСтроки.Значение); 122 | Если Имя = "Cookie" Тогда 123 | Для Каждого КукаСтрокой Из СтрРазделить(Значение, ";") Цикл 124 | Кука = Парсеры.РазделитьСтроку(КукаСтрокой, "="); 125 | Результат.Куки.Добавить(СокрЛП(Кука.Лево), СокрЛП(Кука.Право)); 126 | КонецЦикла 127 | Иначе 128 | Заголовки.Вставить(Имя, Значение); 129 | КонецЕсли; 130 | КонецЦикла; 131 | 132 | КонецЕсли; 133 | 134 | Возврат Результат; 135 | КонецФункции 136 | 137 | Функция РаспарситьСтрокуЗаголовка(СтрокаЗаголовка) 138 | РазделеннаяСтрока = Парсеры.РазделитьСтроку(СтрокаЗаголовка, ":"); 139 | Возврат Новый Структура("Имя, Значение", РазделеннаяСтрока.Лево, РазделеннаяСтрока.Право); 140 | КонецФункции 141 | 142 | Процедура УстановитьСессиюПоКукам(Запрос) 143 | Запрос.Сессия = МенеджерСессий.ПолучитьСессиюПоКукам(Запрос.Куки); 144 | КонецПроцедуры 145 | 146 | Процедура УстановитьАдресИПортУдаленногоУзла(Запрос, УдаленныйУзел) 147 | 148 | Структура = Парсеры.СтруктураУзла(УдаленныйУзел); 149 | 150 | Запрос.АдресУдаленногоУзла = Структура.Адрес; 151 | Запрос.ПортУдаленногоУзла = Структура.Порт; 152 | 153 | КонецПроцедуры 154 | 155 | Функция СтруктураРезультатаПарсинга() 156 | Возврат Новый Структура("ЗакрыватьСоединение, Ответ, Идентификатор, Топик, ТипСоединения", Истина); 157 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/Парсеры.os: -------------------------------------------------------------------------------- 1 | Перем Перечисления; 2 | 3 | &Желудь 4 | Процедура ПриСозданииОбъекта( 5 | &Пластилин("Перечисления") _Перечисления 6 | ) 7 | Перечисления = _Перечисления; 8 | КонецПроцедуры 9 | 10 | Функция ПараметрыИзТекста(ПараметрыТекстом, РазделительПараметров = "&") Экспорт 11 | 12 | Результат = Новый Соответствие(); 13 | 14 | Если ЗначениеЗаполнено(ПараметрыТекстом) Тогда 15 | МассивПараметров = СтрРазделить(ПараметрыТекстом, РазделительПараметров, Ложь); 16 | Для Каждого ТекПараметрСтрокой из МассивПараметров Цикл 17 | ТекПараметр = РазделитьСтроку(ТекПараметрСтрокой, "="); 18 | Имя = РаскодироватьСтроку(ТекПараметр.Лево, СпособКодированияСтроки.КодировкаURL); 19 | Значение = РаскодироватьСтроку(ТекПараметр.Право, СпособКодированияСтроки.КодировкаURL); 20 | Результат.Вставить(Имя, Значение); 21 | КонецЦикла; 22 | КонецЕсли; 23 | 24 | Возврат Результат; 25 | 26 | КонецФункции 27 | 28 | Функция РазделитьСтроку(Строка, Разделитель) Экспорт 29 | Результат = Новый Структура("Лево, Право","",""); 30 | ПозицияРазделителя = СтрНайти(Строка, Разделитель); 31 | 32 | Если ПозицияРазделителя = 0 Тогда 33 | Результат.Лево = Строка; 34 | Иначе 35 | Результат.Лево = Лев(Строка, ПозицияРазделителя - 1); 36 | Результат.Право = Сред(Строка, ПозицияРазделителя + СтрДлина(Разделитель)); 37 | КонецЕсли; 38 | 39 | Возврат Результат; 40 | КонецФункции 41 | 42 | Функция РазделитьДвоичныеДанныеРазделителем(ДвоичныеДанные, Разделитель) Экспорт 43 | БуферДвоичныхДанных = ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(ДвоичныеДанные); 44 | 45 | Лево = Неопределено; 46 | Право = Неопределено; 47 | 48 | Массив = БуферДвоичныхДанных.Разделить(ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(Разделитель)); 49 | 50 | Если Массив.Количество() > 0 Тогда 51 | 52 | Лево = ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(Массив[0]); 53 | 54 | Если Массив.Количество() > 1 Тогда 55 | 56 | МассивПраво = Новый Массив(); 57 | 58 | Для Счетчик = 1 По Массив.Количество() - 1 Цикл 59 | Если Счетчик > 1 Тогда 60 | МассивПраво.Добавить(Разделитель); 61 | КонецЕсли; 62 | МассивПраво.Добавить(ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(Массив[Счетчик])); 63 | КонецЦикла; 64 | 65 | Право = СоединитьДвоичныеДанные(МассивПраво); 66 | 67 | КонецЕсли; 68 | 69 | КонецЕсли; 70 | 71 | Возврат Новый Структура("Лево, Право", Лево, Право); 72 | 73 | КонецФункции 74 | 75 | Функция РазделитьДвоичныеДанныеРазделителемВМассив(Знач ДвоичныеДанные, Разделитель, ВКлючатьПустые = Ложь) Экспорт 76 | 77 | БуферДвоичныхДанных = ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(ДвоичныеДанные); 78 | 79 | Массив = БуферДвоичныхДанных.Разделить(ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(Разделитель)); 80 | 81 | Результат = Новый Массив(); 82 | 83 | Для Каждого Элемент Из Массив Цикл 84 | Результат.Добавить(ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(Элемент)); 85 | КонецЦикла; 86 | 87 | Возврат Результат; 88 | 89 | КонецФункции 90 | 91 | Функция МассивыРавны(Массив1, Массив2) Экспорт 92 | 93 | Если не Массив1.Количество() = Массив2.Количество() Тогда 94 | Возврат Ложь; 95 | Иначе 96 | Для сч = 0 По Массив1.ВГраница() Цикл 97 | Если Не Массив1[сч] = Массив2[сч] Тогда 98 | Возврат Ложь; 99 | КонецЕсли; 100 | КонецЦикла; 101 | КонецЕсли; 102 | 103 | Возврат Истина; 104 | 105 | КонецФункции 106 | 107 | Процедура ДобавитьВМассивСоСмещением(Массив, ДобавляемыйЭлемент) Экспорт 108 | 109 | Если Массив.Количество() = 1 Тогда 110 | Массив[0] = ДобавляемыйЭлемент; 111 | Возврат; 112 | ИначеЕсли Массив.Количество() = 0 Тогда 113 | ВызватьИсключение "Пустой массив для смещения"; 114 | КонецЕсли; 115 | 116 | Для сч = 0 по Массив.ВГраница() - 1 Цикл 117 | Массив[сч] = Массив[сч + 1]; 118 | КонецЦикла; 119 | 120 | Массив[Массив.ВГраница()] = ДобавляемыйЭлемент; 121 | 122 | КонецПроцедуры 123 | 124 | Функция ПолучитьМассивБайт(ДвоичныеДанные) Экспорт 125 | 126 | Возврат РазделитьДвоичныеДанные(ДвоичныеДанные, 1); 127 | 128 | КонецФункции 129 | 130 | Функция СтруктураУзла(АдресУзла) Экспорт 131 | 132 | Результат = Новый Структура("Адрес, Порт", "", 0); 133 | 134 | Адрес = АдресУзла; 135 | ДлинаАдреса = СтрДлина(Адрес); 136 | 137 | ПозицияДвоеточия = СтрНайти(Адрес, ":", НаправлениеПоиска.СКонца); 138 | Если ПозицияДвоеточия > 0 Тогда 139 | ЭтоIPv6 = Сред(Адрес, ПозицияДвоеточия - 1, 1) = "]"; 140 | ЭтоIPv4 = Не ЭтоIPv6 И СтрНайти(Сред(Адрес, 1, ПозицияДвоеточия - 1), ":") = 0; 141 | 142 | Если ЭтоIPv6 Или ЭтоIPv4 Тогда 143 | ДлинаАдреса = ПозицияДвоеточия - 1; 144 | Адрес = Сред(АдресУзла, 1, ДлинаАдреса); 145 | 146 | Результат.Порт = Новый ОписаниеТипов("Число").ПривестиЗначение(Сред(АдресУзла, ПозицияДвоеточия + 1)); 147 | КонецЕсли; 148 | КонецЕсли; 149 | 150 | Если Лев(Адрес, 1) = "[" И Прав(Адрес, 1) = "]" Тогда 151 | Адрес = Сред(Адрес, 2, ДлинаАдреса - 2); 152 | КонецЕсли; 153 | 154 | Результат.Адрес = Адрес; 155 | 156 | Возврат Результат; 157 | 158 | КонецФункции 159 | 160 | Функция ПолучитьИзПотокаДД(Поток, Позиция, Количество) 161 | Поток.Перейти(Позиция); 162 | БуферДвоичныхДанных = Новый БуферДвоичныхДанных(Количество); 163 | Поток.Прочитать(БуферДвоичныхДанных, 0, Количество); 164 | 165 | Возврат ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(БуферДвоичныхДанных); 166 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/Перечисления.os: -------------------------------------------------------------------------------- 1 | Перем СостоянияОтветов Экспорт; 2 | Перем ОписанияТиповРасширенийФайлов Экспорт; 3 | Перем Разделитель Экспорт; 4 | Перем РазделительДвоичнымиДанными Экспорт; 5 | Перем ДвойнойРазделительДвоичнымиДанными Экспорт; 6 | Перем ВидыПодписокВебСокета Экспорт; 7 | 8 | &Желудь 9 | Процедура ПриСозданииОбъекта() 10 | СостоянияОтветов = СостоянияОтветов(); 11 | ОписанияТиповРасширенийФайлов = ОписанияТиповРасширенийФайлов(); 12 | Разделитель = Разделитель(); 13 | РазделительДвоичнымиДанными = ПолучитьДвоичныеДанныеИзСтроки(Разделитель); 14 | ДвойнойРазделительДвоичнымиДанными = ПолучитьДвоичныеДанныеИзСтроки(Разделитель + Разделитель); 15 | ВидыПодписокВебСокета = ВидыПодписокВебСокета(); 16 | КонецПроцедуры 17 | 18 | Функция ВидыПодписокВебСокета() 19 | Возврат Новый Структура("ПриОтключенииВебСокета, ПриПодключенииВебСокета", "ПриОтключенииВебСокета", "ПриПодключенииВебСокета"); 20 | КонецФункции 21 | 22 | Функция Разделитель() 23 | 24 | Возврат Символы.ВК+Символы.ПС; 25 | 26 | КонецФункции 27 | 28 | Функция СостоянияОтветов() 29 | 30 | Состояния = Новый Соответствие(); 31 | 32 | Состояния.Вставить(200, "OK"); 33 | Состояния.Вставить(302, "Found"); 34 | Состояния.Вставить(401, "Unauthorized"); 35 | Состояния.Вставить(403, "Forbidden"); 36 | Состояния.Вставить(404, "Not Found"); 37 | Состояния.Вставить(500, "Internal Server Error"); 38 | 39 | Возврат Состояния; 40 | 41 | КонецФункции 42 | 43 | Функция ОписанияТиповРасширенийФайлов() 44 | 45 | ОписанияТиповРасширений = Новый Соответствие(); 46 | ОписанияТиповРасширений.Вставить("htm","text/html; charset=utf-8"); 47 | ОписанияТиповРасширений.Вставить("html","text/html; charset=utf-8"); 48 | ОписанияТиповРасширений.Вставить("css","text/css"); 49 | ОписанияТиповРасширений.Вставить("js","text/javascript"); 50 | ОписанияТиповРасширений.Вставить("map","application/json"); 51 | ОписанияТиповРасширений.Вставить("jpg","image/jpeg"); 52 | ОписанияТиповРасширений.Вставить("jpeg","image/jpeg"); 53 | ОписанияТиповРасширений.Вставить("png","image/png"); 54 | ОписанияТиповРасширений.Вставить("gif","image/gif"); 55 | ОписанияТиповРасширений.Вставить("ico","image/x-icon"); 56 | ОписанияТиповРасширений.Вставить("zip","application/x-compressed"); 57 | ОписанияТиповРасширений.Вставить("rar","application/x-compressed"); 58 | ОписанияТиповРасширений.Вставить("json","application/json"); 59 | ОписанияТиповРасширений.Вставить("txt","text/plain; charset=utf-8"); 60 | ОписанияТиповРасширений.Вставить("swf","application/x-shockwave-flash"); 61 | ОписанияТиповРасширений.Вставить("svg","image/svg+xml"); 62 | ОписанияТиповРасширений.Вставить("ttf","font/ttf"); 63 | ОписанияТиповРасширений.Вставить("woff","font/woff"); 64 | ОписанияТиповРасширений.Вставить("woff2","font/woff2"); 65 | ОписанияТиповРасширений.Вставить("eot","application/vnd.ms-fontobject"); 66 | 67 | Возврат ОписанияТиповРасширений; 68 | 69 | КонецФункции 70 | 71 | -------------------------------------------------------------------------------- /src/Классы/ПодготовительОтветов.os: -------------------------------------------------------------------------------- 1 | &Пластилин Перем Перечисления; 2 | 3 | &Желудь 4 | Процедура ПриСозданииОбъекта() 5 | КонецПроцедуры 6 | 7 | Функция ДвоичныеДанныеОтвета(Ответ) Экспорт 8 | 9 | МассивОтвета = Новый Массив(); 10 | 11 | МассивОтвета.Добавить(ПолучитьШапкуОтвета(Ответ)); 12 | 13 | ДобавитьВМассивСоответствиеКакСтроки(МассивОтвета, Ответ.Заголовки); 14 | 15 | Для Каждого Кука из Ответ.Куки.ПолучитьМассивСтрокКук() Цикл 16 | МассивОтвета.Добавить(Кука); 17 | КонецЦикла; 18 | 19 | МассивОтвета.Добавить(Перечисления.Разделитель); 20 | 21 | ТекстСтатусИЗаголовки = СтрСоединить(МассивОтвета, Перечисления.Разделитель); 22 | 23 | ДвоичныеДанныеТекстСтатусИЗаголовки = ПолучитьДвоичныеДанныеИзСтроки(ТекстСтатусИЗаголовки, "utf-8"); 24 | 25 | МассивДвоичныхДанных = Новый Массив(); 26 | 27 | МассивДвоичныхДанных.Добавить(ДвоичныеДанныеТекстСтатусИЗаголовки); 28 | 29 | Если ЗначениеЗаполнено(Ответ.ТелоДвоичныеДанные) Тогда 30 | МассивДвоичныхДанных.Добавить(Ответ.ТелоДвоичныеДанные); 31 | 32 | ИначеЕсли ЗначениеЗаполнено(Ответ.ТелоТекст) Тогда 33 | МассивДвоичныхДанных.Добавить(ПолучитьДвоичныеДанныеИзСтроки(Ответ.ТелоТекст, "utf-8")); 34 | 35 | КонецЕсли; 36 | 37 | ДвоичныеДанныеОтвета = СоединитьДвоичныеДанные(МассивДвоичныхДанных); 38 | 39 | Возврат ДвоичныеДанныеОтвета; 40 | 41 | КонецФункции 42 | 43 | Процедура ДобавитьВМассивСоответствиеКакСтроки(Массив, Соответствие) 44 | Для Каждого КиЗ Из Соответствие Цикл 45 | Массив.Добавить(СтрШаблон("%1: %2", КиЗ.Ключ, КиЗ.Значение)); 46 | КонецЦикла 47 | КонецПроцедуры 48 | 49 | Функция ПолучитьШапкуОтвета(Ответ) 50 | Возврат СтрШаблон("HTTP/1.1 %1 %2", Ответ.СостояниеКод, Ответ.СостояниеТекст); 51 | КонецФункции 52 | -------------------------------------------------------------------------------- /src/Классы/ПодпискаНаВебСокет.os: -------------------------------------------------------------------------------- 1 | Перем _БрокерСообщенийВебСокетов; 2 | Перем _СоединенияВебСокетов; 3 | 4 | Перем _Идентификатор; 5 | Перем _Соединение; 6 | Перем _Топик; 7 | Перем _Включена; 8 | 9 | &Желудь 10 | &Характер("Компанейский") 11 | &ОсобоеОбращение(ОтключитьВсеНапильники = Истина) 12 | Процедура ПриСозданииОбъекта(&Пластилин БрокерСообщенийВебСокетов, 13 | &Пластилин СоединенияВебСокетов) 14 | _СоединенияВебСокетов = СоединенияВебСокетов; 15 | _БрокерСообщенийВебСокетов = БрокерСообщенийВебСокетов; 16 | _Включена = Ложь; 17 | КонецПроцедуры 18 | 19 | Процедура Подписатся(Соединение, Идентификатор, Топик) Экспорт 20 | _Идентификатор = Идентификатор; 21 | _Соединение = Соединение; 22 | _Топик = Топик; 23 | _Включена = Истина; 24 | 25 | ФоновыеЗадания.Выполнить(ЭтотОбъект, "ЗапуститьОбработкуСообщений"); 26 | КонецПроцедуры 27 | 28 | Процедура Отписаться() Экспорт 29 | _Включена = Ложь; 30 | КонецПроцедуры 31 | 32 | Процедура ЗапуститьОбработкуСообщений() Экспорт 33 | Если НЕ _Соединение = Неопределено Тогда 34 | _БрокерСообщенийВебСокетов.ПриПодключении(_Топик, _Идентификатор); 35 | ОбработкаСообщений(); 36 | Иначе 37 | ВызватьИсключение "Не инициализировано соединение, невозможно запустить обработку сообщений" 38 | КонецЕсли; 39 | КонецПроцедуры 40 | 41 | Процедура ОбработкаСообщений() 42 | Попытка 43 | Пока _Включена = Истина И _Соединение.Активно = Истина Цикл 44 | ДвоичныеДанные = _Соединение.ПрочитатьДвоичныеДанные(); 45 | _БрокерСообщенийВебСокетов.ВходящееСообщение(_Идентификатор, _Топик, ДвоичныеДанные); 46 | КонецЦикла; 47 | Исключение 48 | КонецПопытки; 49 | Отключить(); 50 | КонецПроцедуры 51 | 52 | Процедура Отключить() 53 | _СоединенияВебСокетов.УдалитьСоединение(_Соединение); 54 | _БрокерСообщенийВебСокетов.ПриОтключении(_Топик, _Идентификатор); 55 | КонецПроцедуры -------------------------------------------------------------------------------- /src/Классы/ПодпискиСерверныхСобытий.os: -------------------------------------------------------------------------------- 1 | 2 | Перем ПодписчикиОткрытия; 3 | Перем ПодписчикиЗакрытия; 4 | 5 | &Желудь 6 | Процедура ПриСозданииОбъекта() 7 | Инициализация(); 8 | КонецПроцедуры 9 | 10 | Процедура СобытиеОткрытия(Топик, Идентификатор, ИдСоединения) Экспорт 11 | Для Каждого Подписчики из ПодписчикиОткрытия.НайтиСтроки(Новый Структура("Топик", Топик)) Цикл 12 | ВыполнитьОбработчикФоном(Подписчики.Обработчик, Идентификатор, ИдСоединения); 13 | КонецЦикла; 14 | КонецПроцедуры 15 | 16 | Процедура СобытиеЗакрытия(Топик, Идентификатор, ИдСоединения) Экспорт 17 | Для Каждого Подписчики из ПодписчикиЗакрытия.НайтиСтроки(Новый Структура("Топик", Топик)) Цикл 18 | ВыполнитьОбработчикФоном(Подписчики.Обработчик, Идентификатор, ИдСоединения); 19 | КонецЦикла; 20 | КонецПроцедуры 21 | 22 | Процедура ВыполнитьОбработчикФоном(Обработчик, Идентификатор, ИдСоединения) 23 | Параметры = Новый Массив(); 24 | Параметры.Добавить(Обработчик); 25 | Параметры.Добавить(Идентификатор); 26 | Параметры.Добавить(ИдСоединения); 27 | ФоновыеЗадания.Выполнить(ЭтотОбъект, "ЗапуститьФоновоеЗаданиеОбработчика", Параметры); 28 | КонецПроцедуры 29 | 30 | Процедура ЗапуститьФоновоеЗаданиеОбработчика(Обработчик, Идентификатор, ИдСоединения) Экспорт 31 | Приостановить(50); 32 | Обработчик.Выполнить(Идентификатор, ИдСоединения); 33 | КонецПроцедуры 34 | 35 | Процедура ПодпискаНаОткрытие(Топик, Обработчик) Экспорт 36 | НоваяПодписка = ПодписчикиОткрытия.Добавить(); 37 | НоваяПодписка.Топик = Топик; 38 | НоваяПодписка.Обработчик = Обработчик; 39 | КонецПроцедуры 40 | 41 | Процедура ПодпискаНаЗакрытие(Топик, Обработчик) Экспорт 42 | НоваяПодписка = ПодписчикиЗакрытия.Добавить(); 43 | НоваяПодписка.Топик = Топик; 44 | НоваяПодписка.Обработчик = Обработчик; 45 | КонецПроцедуры 46 | 47 | Процедура Инициализация() 48 | ПодписчикиОткрытия = Новый ТаблицаЗначений(); 49 | ПодписчикиОткрытия.Колонки.Добавить("Топик"); 50 | ПодписчикиОткрытия.Колонки.Добавить("Обработчик"); 51 | 52 | ПодписчикиЗакрытия = Новый ТаблицаЗначений(); 53 | ПодписчикиЗакрытия.Колонки.Добавить("Топик"); 54 | ПодписчикиЗакрытия.Колонки.Добавить("Обработчик"); 55 | КонецПроцедуры 56 | 57 | -------------------------------------------------------------------------------- /src/Классы/ПрикладнойВебСервер.os: -------------------------------------------------------------------------------- 1 | 2 | &Пластилин Перем ОбработчикСоединений; 3 | &Пластилин Перем СлушательПорта; 4 | &Пластилин Перем КонтрольСоединенийСерверныхСобытий; 5 | 6 | &Желудь 7 | Процедура ПриСозданииОбъекта() 8 | 9 | КонецПроцедуры 10 | 11 | Процедура Старт() Экспорт 12 | 13 | КонтрольСоединенийСерверныхСобытий.Старт(); 14 | 15 | СлушательПорта.Запустить(); 16 | 17 | Пока СлушательПорта.Активен() Цикл 18 | 19 | Соединение = СлушательПорта.ОжидатьСоединения(); 20 | 21 | МассивПараметров = Новый Массив(); 22 | МассивПараметров.Добавить(Соединение); 23 | 24 | ФоновыеЗадания.Выполнить(ОбработчикСоединений, "Обработать", МассивПараметров); 25 | 26 | КонецЦикла; 27 | 28 | КонтрольСоединенийСерверныхСобытий.Стоп(); 29 | 30 | КонецПроцедуры 31 | 32 | Процедура Стоп() Экспорт 33 | СлушательПорта.Остановить(); 34 | КонецПроцедуры -------------------------------------------------------------------------------- /src/Классы/РегистраторКаталогаФайлов.os: -------------------------------------------------------------------------------- 1 | &Пластилин Перем Перечисления; 2 | &Пластилин Перем ФабрикаОтветов; 3 | &Пластилин Перем Маршрутизатор; 4 | 5 | &Деталька("winow.КаталогиСФайлами") 6 | Перем КаталогиСФайлами; 7 | 8 | Перем СоответствиеПутей; 9 | Перем ЗарегистрированныеФайлы; 10 | 11 | &Желудь 12 | Процедура ПриСозданииОбъекта() 13 | СоответствиеПутей = Новый Соответствие(); 14 | ЗарегистрированныеФайлы = Новый Массив; 15 | КонецПроцедуры 16 | 17 | Процедура ОбновтитьСтатичныеФайлы() Экспорт 18 | Если ТипЗнч(КаталогиСФайлами) = Тип("Соответствие") Тогда 19 | Для Каждого КиЗ из КаталогиСФайлами Цикл 20 | ДобавитьКаталогСтатичныхФайлов(КиЗ.Значение, КиЗ.Ключ); 21 | КонецЦикла; 22 | КонецЕсли; 23 | КонецПроцедуры 24 | 25 | Процедура ДобавитьКаталогСтатичныхФайлов(КаталогФайлов, ПутьНаСайте = "/") Экспорт 26 | Для Каждого ТипФайла из Перечисления.ОписанияТиповРасширенийФайлов Цикл 27 | Файлы = НайтиФайлы(КаталогФайлов, "*." + ТипФайла.Ключ, Истина); 28 | Для каждого Файл Из Файлы Цикл 29 | ДобавитьМаршрутДоФайла(Файл, КаталогФайлов, ПутьНаСайте, ТипФайла.Значение); 30 | КонецЦикла; 31 | КонецЦикла; 32 | КонецПроцедуры 33 | 34 | Процедура ОтдатьФайл(Запрос, Ответ) Экспорт 35 | 36 | ОписаниеФайла = СоответствиеПутей[Запрос.Путь]; 37 | 38 | Если ОписаниеФайла = Неопределено Тогда 39 | Ответ = ФабрикаОтветов.НовыйОтвет404(); 40 | Иначе 41 | Ответ.Заголовки["Content-Type"] = ОписаниеФайла.ТипКонтента; 42 | Ответ.ТелоДвоичныеДанные = Новый ДвоичныеДанные(ОписаниеФайла.ПутьНаДиске); 43 | КонецЕсли; 44 | 45 | КонецПроцедуры 46 | 47 | Процедура ДобавитьМаршрутДоФайла(Файл, знач КаталогФайлов, знач ПутьНаСайте, знач ТипКонтента) 48 | 49 | Если Не СтрЗаканчиваетсяНа(КаталогФайлов, "/") Тогда 50 | КаталогФайлов = КаталогФайлов + "/"; 51 | КонецЕсли; 52 | 53 | ПутьЮниксСлешами = СтрЗаменить(Файл.ПолноеИмя, "\", "/"); 54 | 55 | Если ЗарегистрированныеФайлы.Найти(ПутьЮниксСлешами) = Неопределено Тогда 56 | ЗарегистрированныеФайлы.Добавить(ПутьЮниксСлешами); 57 | Иначе 58 | Возврат; 59 | КонецЕсли; 60 | 61 | ПутьВПодкаталоге = ПутьВПодкаталоге(ПутьЮниксСлешами, КаталогФайлов); 62 | 63 | РасположениеНаСайте = СтрЗаменить(ОбъединитьПути(ПутьНаСайте, ПутьВПодкаталоге), "\", "/"); 64 | 65 | СоответствиеПутей.Вставить(РасположениеНаСайте, Новый Структура("ПутьНаДиске, ТипКонтента", ПутьЮниксСлешами, ТипКонтента)); 66 | 67 | Массив = Новый Массив(); 68 | Массив.Добавить("Запрос"); 69 | Массив.Добавить("Ответ"); 70 | 71 | Действие = Маршрутизатор.ОписаниеТочкиМаршрута(); 72 | Действие.Желудь = ЭтотОбъект; 73 | Действие.ИмяМетода = "ОтдатьФайл"; 74 | Действие.Параметры = Массив; 75 | 76 | Маршрутизатор.ДобавитьМаршрут(РасположениеНаСайте, Действие); 77 | 78 | КонецПроцедуры 79 | 80 | Функция ПутьВПодкаталоге(знач ПолныйПуть, знач КаталогФайлов) 81 | 82 | Если СтрНачинаетсяС(КаталогФайлов, ".") Тогда 83 | КаталогФайлов = Сред(КаталогФайлов, 2); 84 | КонецЕсли; 85 | 86 | Вхождение = СтрНайти(ПолныйПуть, КаталогФайлов, НаправлениеПоиска.СКонца); 87 | 88 | Результат = Сред(ПолныйПуть, Вхождение + СтрДлина(КаталогФайлов)); 89 | 90 | Возврат Результат; 91 | 92 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/СборщикМаршрутов.os: -------------------------------------------------------------------------------- 1 | #Использовать autumn 2 | #Использовать autumn-logos 3 | 4 | &Лог("winow.router") 5 | Перем Лог; 6 | 7 | &Пластилин Перем Маршрутизатор; 8 | &Пластилин Перем МенеджерОтображений; 9 | &Пластилин Перем МенеджерДоступа; 10 | &Пластилин Перем Перечисления; 11 | &Пластилин Перем Поделка; 12 | 13 | &Желудь 14 | Процедура ПриСозданииОбъекта() 15 | 16 | КонецПроцедуры 17 | 18 | Процедура НайтиИЗарегистрироватьМаршруты(Желудь) Экспорт 19 | 20 | РефлекторОбъекта = РефлекторЖелудя(Желудь); 21 | 22 | МетодыМаршрут = РефлекторОбъекта.ПолучитьТаблицуМетодов("Контроллер", Ложь); 23 | 24 | Если МетодыМаршрут.Количество() > 1 Тогда 25 | 26 | ВызватьИсключение "Не может быть больше одного определения контроллера в классе " + Желудь; 27 | 28 | ИначеЕсли МетодыМаршрут.Количество() = 0 Тогда 29 | 30 | Возврат; 31 | 32 | КонецЕсли; 33 | 34 | Аннотация = РаботаСАннотациями.ПолучитьАннотацию(МетодыМаршрут[0], "Контроллер"); 35 | 36 | АдресКонтроллера = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(Аннотация); 37 | 38 | МетодыТочекМаршрутов = РефлекторОбъекта.ПолучитьТаблицуМетодов("ТочкаМаршрута"); 39 | 40 | Если МетодыТочекМаршрутов.Количество() = 0 Тогда 41 | ВызватьИсключение "Не определено ниодной точки маршрута в контроллере " + Желудь; 42 | КонецЕсли; 43 | 44 | Лог.Отладка(СтрШаблон("Регистрация контрола %1 по адресу %2", Желудь, АдресКонтроллера)); 45 | 46 | Для Каждого ТочкаМаршрута из МетодыТочекМаршрутов Цикл 47 | ЗарегистрироватьМаршрутКОбъекту(АдресКонтроллера, ТочкаМаршрута, Желудь); 48 | КонецЦикла; 49 | 50 | НайтиПодпискиВебСокета(Желудь, РефлекторОбъекта); 51 | 52 | КонецПроцедуры 53 | 54 | Процедура НайтиПодпискиВебСокета(Желудь, РефлекторОбъекта) 55 | 56 | Для каждого ВидПодписки Из Перечисления.ВидыПодписокВебСокета Цикл 57 | ЗаполнитьПодпискиЖелудя(Желудь, РефлекторОбъекта, ВидПодписки.Ключ); 58 | КонецЦикла; 59 | 60 | КонецПроцедуры 61 | 62 | Процедура ЗаполнитьПодпискиЖелудя(Желудь, РефлекторОбъекта, Подписка) 63 | МетодыПодписки = РефлекторОбъекта.ПолучитьТаблицуМетодов(Подписка); 64 | Для Каждого Метод из МетодыПодписки Цикл 65 | Аннотация = РаботаСАннотациями.ПолучитьАннотацию(Метод, Подписка); 66 | Топик = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(Аннотация); 67 | Если НЕ ЗначениеЗаполнено(Топик) Тогда 68 | ВызватьИсключение СтрШаблон("Для контроллера %1 не заполнено топик в подписке %2", Желудь, Метод.Имя); 69 | КонецЕсли; 70 | 71 | Маршрутизатор.ДобавитьПодписку(Подписка, Топик, Желудь, Метод.Имя, Метод.Параметры.ВыгрузитьКолонку("Имя")); 72 | 73 | КонецЦикла; 74 | КонецПроцедуры 75 | 76 | Процедура ЗарегистрироватьОтображениеКонтрола(Действие) 77 | 78 | РефлекторОбъекта = РефлекторЖелудя(Действие.Желудь); 79 | КонструкторЖелудя = РефлекторОбъекта.ПолучитьТаблицуМетодов("Контроллер", Ложь)[0]; 80 | Аннотация = РаботаСАннотациями.ПолучитьАннотацию(КонструкторЖелудя, "Отображение"); 81 | Если Аннотация = Неопределено Тогда 82 | Возврат; 83 | КонецЕсли; 84 | 85 | Если Аннотация.Параметры.Количество() = 2 Тогда 86 | ПутьДоШаблона = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(Аннотация, "Шаблон"); 87 | Метод = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(Аннотация, "Метод"); 88 | ПараметрыШаблона = НайтиПараметрыМетодаВТаблице(РефлекторОбъекта.ПолучитьТаблицуМетодов(), Метод); 89 | Иначе 90 | ПутьДоШаблона = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(Аннотация, "Шаблон"); 91 | Метод = Неопределено; 92 | ПараметрыШаблона = Новый Массив(); 93 | КонецЕсли; 94 | 95 | Действие.Шаблон = ПутьДоШаблона; 96 | Действие.МетодШаблона = Метод; 97 | Действие.ПараметрыШаблона = ПараметрыШаблона; 98 | 99 | КонецПроцедуры 100 | 101 | Функция НайтиПараметрыМетодаВТаблице(ТаблицаМетодов, ИмяМетода) 102 | Для Каждого ТекМетод Из ТаблицаМетодов Цикл 103 | Если ВРег(ИмяМетода) = ВРег(ТекМетод.Имя) Тогда 104 | Возврат ТекМетод.Параметры.ВыгрузитьКолонку("Имя"); 105 | КонецЕсли; 106 | КонецЦикла; 107 | ВызватьИсключение "Метод не найден " + ИмяМетода; 108 | КонецФункции 109 | 110 | Функция НайтиИЗаменитьПараметрыУРЛ(Урл) 111 | Урл = СтрЗаменить(Урл, "\", "/"); 112 | МассивВсехПараметров = СтрРазделить(Урл, "/"); 113 | ОчищенныйУРЛ = Новый Массив; 114 | ПараметрыУРЛ = Новый Соответствие; 115 | 116 | СчетчикПараметров = 0; 117 | 118 | Для каждого ТекущийПараметр Из МассивВсехПараметров Цикл 119 | 120 | Если ЭтоШаблонПараметраУрл(ТекущийПараметр) Тогда 121 | ПараметрыУРЛ.Вставить(СчетчикПараметров, Сред(ТекущийПараметр,2, СтрДлина(ТекущийПараметр) - 2)); 122 | ОчищенныйУРЛ.Добавить(Маршрутизатор.СимволПараметраТочкиМаршрута()); 123 | Иначе 124 | ОчищенныйУРЛ.Добавить(ТекущийПараметр); 125 | КонецЕсли; 126 | СчетчикПараметров = СчетчикПараметров + 1; 127 | КонецЦикла; 128 | Урл = СтрСоединить(ОчищенныйУРЛ, "/"); 129 | Возврат ПараметрыУРЛ; 130 | КонецФункции 131 | 132 | Функция ЭтоШаблонПараметраУрл(ЧастьУрла) 133 | Возврат СтрНачинаетсяС(ЧастьУрла, "{") И СтрЗаканчиваетсяНа(ЧастьУрла, "}"); 134 | КонецФункции 135 | 136 | Процедура ЗарегистрироватьМаршрутКОбъекту(АдресКонтроллера, ТочкаМаршрута, Желудь) 137 | 138 | Действие = Маршрутизатор.ОписаниеТочкиМаршрута(); 139 | Действие.АдресКонтроллера = АдресКонтроллера; 140 | Действие.Желудь = Желудь; 141 | Действие.ИмяМетода = ТочкаМаршрута.Имя; 142 | Действие.Параметры = ТочкаМаршрута.Параметры.ВыгрузитьКолонку("Имя"); 143 | Действие.ВыводитьШаблонКонтрола = РаботаСАннотациями.ПолучитьАннотацию(ТочкаМаршрута, "НеВыводитОтображениеКонтроллера") = Неопределено; 144 | 145 | Аннотация = РаботаСАннотациями.ПолучитьАннотацию(ТочкаМаршрута, "ТочкаМаршрута"); 146 | ИмяТочкиМаршута = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(Аннотация); 147 | 148 | Если СтрНайти(ИмяТочкиМаршута, "{") > 0 149 | ИЛИ СтрНайти(ИмяТочкиМаршута, "}") > 0 Тогда 150 | Действие.ПараметрыУРЛ = НайтиИЗаменитьПараметрыУРЛ(ИмяТочкиМаршута); 151 | Действие.УрлСодержитШаблон = Истина; 152 | КонецЕсли; 153 | 154 | ПутьКМетоду = СтрЗаменить(ОбъединитьПути(АдресКонтроллера, ИмяТочкиМаршута), "\", "/"); 155 | 156 | Лог.Отладка(СтрШаблон("Регистрация точки маршрута контрола %1 по адресу %2", Желудь, ПутьКМетоду)); 157 | 158 | Маршрутизатор.ДобавитьМаршрут(ПутьКМетоду, Действие); 159 | 160 | ЗарегистрироватьОтображение(ТочкаМаршрута, Действие); 161 | 162 | ЗарегистрироватьРолиТочкиМаршрута(ТочкаМаршрута, Действие); 163 | 164 | ЗарегистрироватьОтображениеКонтрола(Действие); 165 | 166 | КонецПроцедуры 167 | 168 | Процедура ЗарегистрироватьОтображение(ТочкаМаршрута, Действие) 169 | Аннотация = РаботаСАннотациями.ПолучитьАннотацию(ТочкаМаршрута, "Отображение"); 170 | Если НЕ Аннотация = Неопределено Тогда 171 | РасположениеОтображения = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(Аннотация); 172 | МенеджерОтображений.ДобавитьОтображениеДействия(Действие, РасположениеОтображения); 173 | КонецЕсли; 174 | КонецПроцедуры 175 | 176 | Процедура ЗарегистрироватьРолиТочкиМаршрута(ТочкаМаршрута, Действие) 177 | Аннотация = РаботаСАннотациями.ПолучитьАннотацию(ТочкаМаршрута, "Роли"); 178 | Если НЕ Аннотация = Неопределено Тогда 179 | СписокРолей = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(Аннотация); 180 | МенеджерДоступа.ДобавитьРолиТочкиДоступаСписком(Действие, СписокРолей); 181 | КонецЕсли; 182 | КонецПроцедуры 183 | 184 | Функция РефлекторЖелудя(Желудь) 185 | Возврат Новый РефлекторОбъекта(ТипЗнч(Желудь)); 186 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/СерверноеСобытие.os: -------------------------------------------------------------------------------- 1 | Перем ТипСобытия; 2 | Перем Идентификатор; 3 | Перем Данные; 4 | 5 | Процедура ПриСозданииОбъекта() 6 | ТипСобытия = ""; 7 | Идентификатор = ""; 8 | Данные = Новый Массив(); 9 | КонецПроцедуры 10 | 11 | Функция ТипСобытия(ТипПередаваемогоСобытия) Экспорт 12 | ТипСобытия = ТипПередаваемогоСобытия; 13 | Возврат ЭтотОбъект; 14 | КонецФункции 15 | 16 | Функция Идентификатор(Ид) Экспорт 17 | Идентификатор = Ид; 18 | Возврат ЭтотОбъект; 19 | КонецФункции 20 | 21 | Функция ДобавитьСтроку(Строка) Экспорт 22 | 23 | Для Каждого ТекСтрока из СтрРазделить(Строка, Символы.ПС) Цикл 24 | Данные.Добавить("data: " + ТекСтрока); 25 | КонецЦикла; 26 | 27 | Возврат ЭтотОбъект; 28 | КонецФункции 29 | 30 | Функция Сформировать() Экспорт 31 | 32 | Результат = Новый Массив(); 33 | 34 | Если ЗначениеЗаполнено(ТипСобытия) Тогда 35 | Результат.Добавить("event: " + ТипСобытия); 36 | КонецЕсли; 37 | 38 | Для Каждого СтрокаДанных Из Данные Цикл 39 | Результат.Добавить(СтрокаДанных); 40 | КонецЦикла; 41 | 42 | Если ЗначениеЗаполнено(Идентификатор) Тогда 43 | Результат.Добавить("id: " + Идентификатор); 44 | КонецЕсли; 45 | 46 | Результат.Добавить(Символы.ПС); 47 | 48 | Возврат СтрСоединить(Результат, Символы.ПС); 49 | 50 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/СессияПользователя.os: -------------------------------------------------------------------------------- 1 | Перем ДатаСоздания; 2 | Перем Идентификатор; 3 | Перем Данные Экспорт; 4 | Перем Логин Экспорт; 5 | 6 | &Желудь 7 | &Характер("Компанейский") 8 | &ОсобоеОбращение(ОтключитьВсеНапильники = Истина) 9 | Процедура ПриСозданииОбъекта() 10 | Данные = Новый Соответствие(); 11 | ДатаСоздания = ТекущаяДата(); 12 | Идентификатор = СтрЗаменить(Новый УникальныйИдентификатор(), "-", ""); 13 | Логин = ""; 14 | КонецПроцедуры 15 | 16 | Функция ДатаСоздания() Экспорт 17 | Возврат ДатаСоздания; 18 | КонецФункции 19 | 20 | Функция Идентификатор() Экспорт 21 | Возврат Идентификатор; 22 | КонецФункции 23 | 24 | Функция ЗначенияПараметровДляТочкиМаршрута() Экспорт 25 | Результат = Новый Соответствие(); 26 | Результат.Вставить("Сессия", ЭтотОбъект); 27 | Результат.Вставить("Логин", Логин); 28 | Результат.Вставить("ДанныеСессии", Данные); 29 | 30 | Возврат Результат; 31 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/СлушательПорта.os: -------------------------------------------------------------------------------- 1 | #Использовать autumn-logos 2 | 3 | &Лог("winow.starter") 4 | Перем Лог; 5 | 6 | Перем Настройки; 7 | Перем ТСПСервер; 8 | Перем Активен; 9 | 10 | &Желудь 11 | Процедура ПриСозданииОбъекта( 12 | &Пластилин("Настройки") _Настройки 13 | ) 14 | 15 | Настройки = _Настройки; 16 | Активен = Ложь; 17 | КонецПроцедуры 18 | 19 | Процедура Запустить() Экспорт 20 | 21 | Если Не Активен() Тогда 22 | ТСПСервер = Новый TCPСервер(Настройки.Порт); 23 | ТСПСервер.Запустить(); 24 | Активен = Истина; 25 | Лог.Информация(СтрШаблон("Сервера запущен и доступен на http://%1:%2",Настройки.ИмяХоста, Настройки.Порт)); 26 | Иначе 27 | ВызватьИсключение "Серевер уже запущен"; 28 | КонецЕсли; 29 | 30 | КонецПроцедуры 31 | 32 | Функция Активен() Экспорт 33 | Возврат Активен; 34 | КонецФункции 35 | 36 | Процедура Остановить() Экспорт 37 | Если НЕ Активен() Тогда 38 | ВызватьИсключение "Серевер не запущен"; 39 | Иначе 40 | ТСПСервер.Остановить(); 41 | ТСПСервер = Неопределено; 42 | Активен = Ложь; 43 | КонецЕсли; 44 | КонецПроцедуры 45 | 46 | Функция ОжидатьСоединения() Экспорт 47 | Если НЕ Активен() Тогда 48 | ВызватьИсключение "Серевер не запущен"; 49 | Иначе 50 | Возврат ТСПСервер.ОжидатьСоединения(); 51 | КонецЕсли; 52 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/СоединенияВебСокетов.os: -------------------------------------------------------------------------------- 1 | &Пластилин Перем Поделка; 2 | 3 | &ЛогВебСервера 4 | Перем Лог; 5 | 6 | Перем ПулСоединений; 7 | 8 | &Желудь 9 | Процедура ПриСозданииОбъекта() 10 | Инициализация(); 11 | КонецПроцедуры 12 | 13 | Процедура Добавить(Соединение, Идентификатор, Топик) Экспорт 14 | НовоеСоединение = ПулСоединений.Добавить(); 15 | НовоеСоединение.Идентификатор = Идентификатор; 16 | НовоеСоединение.Топик = Топик; 17 | НовоеСоединение.Соединение = Соединение; 18 | НовоеСоединение.Подписка = НоваяПодписка(Соединение, Идентификатор, Топик); 19 | КонецПроцедуры 20 | 21 | Процедура Инициализация() 22 | ПулСоединений = Новый ТаблицаЗначений(); 23 | ПулСоединений.Колонки.Добавить("Идентификатор"); 24 | ПулСоединений.Колонки.Добавить("Топик"); 25 | ПулСоединений.Колонки.Добавить("Соединение"); 26 | ПулСоединений.Колонки.Добавить("Подписка"); 27 | КонецПроцедуры 28 | 29 | Функция НоваяПодписка(Соединение, Идентификатор, Топик) 30 | Подписка = Поделка.НайтиЖелудь("ПодпискаНаВебСокет"); 31 | Подписка.Подписатся(Соединение, Идентификатор, Топик); 32 | Возврат Подписка; 33 | КонецФункции 34 | 35 | Функция ПолучитьСоединенияПоТопику(Топик) Экспорт 36 | Возврат ПолучитьСоединенияСОтбором(Новый Структура("Топик", Топик)); 37 | КонецФункции 38 | 39 | Функция ПолучитьСоединенияПоТопикуСпискуИдентификаторов(Топик, СписокИдентификаторов) Экспорт 40 | Соединения = ПолучитьСоединенияПоТопику(Топик); 41 | Результат = Новый Массив(); 42 | Для Каждого ДанныеСоединения из Соединения Цикл 43 | Если НЕ СписокИдентификаторов.Найти(ДанныеСоединения.Идентификатор) = Неопределено Тогда 44 | Результат.Добавить(ДанныеСоединения); 45 | КонецЕсли; 46 | КонецЦикла; 47 | Возврат Результат; 48 | КонецФункции 49 | 50 | Функция ПолучитьСоединенияПоТопикуКромеСпискаИдентификаторов(Топик, СписокИсключенийИдентификаторов) Экспорт 51 | Соединения = ПолучитьСоединенияПоТопику(Топик); 52 | Результат = Новый Массив(); 53 | Для Каждого ДанныеСоединения из Соединения Цикл 54 | Если СписокИсключенийИдентификаторов.Найти(ДанныеСоединения.Идентификатор) = Неопределено Тогда 55 | Результат.Добавить(ДанныеСоединения); 56 | КонецЕсли; 57 | КонецЦикла; 58 | Возврат Результат; 59 | КонецФункции 60 | 61 | Функция ПолучитьСоединениеПоИдентификатору(Топик, Идентификатор) Экспорт 62 | 63 | Соединения = ПолучитьСоединенияСОтбором(Новый Структура("Топик, Идентификатор", Топик, Идентификатор)); 64 | 65 | Если Соединения.Количество() = 0 Тогда 66 | Возврат Неопределено; 67 | Иначе 68 | Возврат Соединения[0]; 69 | КонецЕсли; 70 | 71 | КонецФункции 72 | 73 | Функция ПолучитьСоединенияСОтбором(Отбор) Экспорт 74 | Возврат ПулСоединений.НайтиСтроки(Отбор); 75 | КонецФункции 76 | 77 | Процедура УдалитьСоединение(Соединение) Экспорт 78 | Для Каждого СтрокаСоединеия из ПолучитьСоединенияСОтбором(Новый Структура("Соединение", Соединение)) Цикл 79 | ПулСоединений.Удалить(СтрокаСоединеия); 80 | КонецЦикла; 81 | КонецПроцедуры 82 | 83 | Процедура НайтиИЗакрытьСоединениеПоИдентификаторуИТопику(Топик, Идентификатор) Экспорт 84 | ДанныеСоединения = ПолучитьСоединениеПоИдентификатору(Топик, Идентификатор); 85 | Если НЕ ДанныеСоединения = Неопределено Тогда 86 | ДанныеСоединения.Подписка.Отписаться(); 87 | Если ДанныеСоединения.Соединение.Активно = Истина Тогда 88 | ЗакрытьСоединение(ДанныеСоединения.Соединение); 89 | КонецЕсли; 90 | КонецЕсли; 91 | КонецПроцедуры 92 | 93 | Процедура ЗакрытьСоединение(Соединение) Экспорт 94 | Попытка 95 | Соединение.Закрыть(); 96 | Исключение 97 | ТекстОшибки = ОписаниеОшибки(); 98 | Лог.Ошибка("Не удалось закрыть WS соединение: " + ТекстОшибки); 99 | КонецПопытки; 100 | КонецПроцедуры -------------------------------------------------------------------------------- /src/Классы/СоединенияСерверныхСобытий.os: -------------------------------------------------------------------------------- 1 | #Использовать semaphore 2 | 3 | Перем ПулСоединений; 4 | Перем Подписки; 5 | Перем Семафор; 6 | 7 | &Желудь 8 | Процедура ПриСозданииОбъекта(&Пластилин ПодпискиСерверныхСобытий) 9 | Подписки = ПодпискиСерверныхСобытий; 10 | Инициализация(); 11 | КонецПроцедуры 12 | 13 | Функция Количество(Топик) Экспорт 14 | Возврат ПолучитьСоединенияПоТопику(Топик).Количество(); 15 | КонецФункции 16 | 17 | Функция ПулСоединений() Экспорт 18 | Возврат ПулСоединений.Скопировать(,"Соединение, ИдСоединения"); 19 | КонецФункции 20 | 21 | Процедура Добавить(Соединение, Идентификатор, Топик) Экспорт 22 | 23 | Семафор.Захватить(); 24 | 25 | НовоеСоединение = ПулСоединений.Добавить(); 26 | НовоеСоединение.Идентификатор = Идентификатор; 27 | НовоеСоединение.Топик = Топик; 28 | НовоеСоединение.Соединение = Соединение; 29 | НовоеСоединение.ИдСоединения = Строка(Новый УникальныйИдентификатор()); 30 | 31 | Семафор.Освободить(); 32 | 33 | ОповеститьОткрытиеСоединения(Идентификатор, Топик, НовоеСоединение.ИдСоединения); 34 | 35 | КонецПроцедуры 36 | 37 | Процедура Удалить(Идентификатор, Топик) Экспорт 38 | Содединения = ПолучитьСоединениеПоИдентификатору(Топик, Идентификатор); 39 | Для Каждого СтрокаСоединения из Содединения Цикл 40 | УдалитьСтрокуПула(СтрокаСоединения); 41 | КонецЦикла; 42 | КонецПроцедуры 43 | 44 | Процедура УдалитьСтрокуПулаПоИдСоединения(ИдСоединения) Экспорт 45 | Соединения = ПолучитьСоединениеПоИдСоединения(ИдСоединения); 46 | 47 | Если Соединения.Количество() > 0 Тогда 48 | УдалитьСтрокуПула(Соединения[0]); 49 | КонецЕсли; 50 | КонецПроцедуры 51 | 52 | Процедура УдалитьСтрокуПула(СтрокаСоединения) Экспорт 53 | 54 | Семафор.Захватить(); 55 | 56 | Идентификатор = СтрокаСоединения.Идентификатор; 57 | Топик = СтрокаСоединения.Топик; 58 | ИдСоединения = СтрокаСоединения.ИдСоединения; 59 | 60 | ЗакрытьСоединениеВПопытке(СтрокаСоединения.Соединение); 61 | ОсвободитьОбъект(СтрокаСоединения.Соединение); 62 | ПулСоединений.Удалить(СтрокаСоединения); 63 | 64 | Семафор.Освободить(); 65 | 66 | ОповеститьЗакрытиеСоединения(Идентификатор, Топик, ИдСоединения); 67 | КонецПроцедуры 68 | 69 | Функция ПолучитьСоединенияПоТопику(Топик) Экспорт 70 | Возврат ПолучитьСоединенияСОтбором(Новый Структура("Топик", Топик)); 71 | КонецФункции 72 | 73 | Функция ПолучитьСоединенияПоТопикуСпискуИдентификаторов(Топик, СписокИдентификаторов) Экспорт 74 | Соединения = ПолучитьСоединенияПоТопику(Топик); 75 | Результат = Новый Массив(); 76 | Для Каждого ДанныеСоединения из Соединения Цикл 77 | Если НЕ СписокИдентификаторов.Найти(ДанныеСоединения.ИдСоединения) = Неопределено Тогда 78 | Результат.Добавить(ДанныеСоединения); 79 | КонецЕсли; 80 | КонецЦикла; 81 | Возврат Результат; 82 | КонецФункции 83 | 84 | Функция ПолучитьСоединенияПоТопикуКромеСпискаИдентификаторов(Топик, СписокИсключенийИдентификаторов) Экспорт 85 | Соединения = ПолучитьСоединенияПоТопику(Топик); 86 | Результат = Новый Массив(); 87 | Для Каждого ДанныеСоединения из Соединения Цикл 88 | Если СписокИсключенийИдентификаторов.Найти(ДанныеСоединения.ИдСоединения) = Неопределено Тогда 89 | Результат.Добавить(ДанныеСоединения); 90 | КонецЕсли; 91 | КонецЦикла; 92 | Возврат Результат; 93 | КонецФункции 94 | 95 | Функция ПолучитьСоединениеПоИдентификатору(Топик, Идентификатор) Экспорт 96 | 97 | Возврат ПолучитьСоединенияСОтбором(Новый Структура("Топик, Идентификатор", Топик, Идентификатор)); 98 | 99 | КонецФункции 100 | 101 | Функция ПолучитьСоединениеПоИдСоединения(ИдСоединения) Экспорт 102 | 103 | Возврат ПолучитьСоединенияСОтбором(Новый Структура("ИдСоединения", ИдСоединения)); 104 | 105 | КонецФункции 106 | 107 | Функция ПолучитьСоединенияСОтбором(Отбор) Экспорт 108 | Возврат ПулСоединений.НайтиСтроки(Отбор); 109 | КонецФункции 110 | 111 | Процедура Инициализация() 112 | Семафор = Новый Семафор(); 113 | ПулСоединений = Новый ТаблицаЗначений(); 114 | ПулСоединений.Колонки.Добавить("Идентификатор"); 115 | ПулСоединений.Колонки.Добавить("Топик"); 116 | ПулСоединений.Колонки.Добавить("Соединение"); 117 | ПулСоединений.Колонки.Добавить("ИдСоединения"); 118 | 119 | // TODO: В 2.0 не работают индексы. Ждем фикса 120 | // ПулСоединений.Индексы.Добавить("Топик"); 121 | // ПулСоединений.Индексы.Добавить("ИдСоединения"); 122 | // ПулСоединений.Индексы.Добавить("Идентификатор"); 123 | // ПулСоединений.Индексы.Добавить("Топик, Идентификатор"); 124 | 125 | КонецПроцедуры 126 | 127 | Процедура ЗакрытьСоединениеВПопытке(Соединение) Экспорт 128 | Попытка 129 | Соединение.Закрыть(); 130 | Исключение 131 | КонецПопытки; 132 | КонецПроцедуры 133 | 134 | Процедура ОповеститьЗакрытиеСоединения(Идентификатор, Топик, ИдСоединения) 135 | Подписки.СобытиеЗакрытия(Топик, Идентификатор, ИдСоединения); 136 | КонецПроцедуры 137 | 138 | Процедура ОповеститьОткрытиеСоединения(Идентификатор, Топик, ИдСоединения) 139 | Подписки.СобытиеОткрытия(Топик, Идентификатор, ИдСоединения); 140 | КонецПроцедуры 141 | 142 | -------------------------------------------------------------------------------- /src/Классы/ТопикиСерверныхСобытий.os: -------------------------------------------------------------------------------- 1 | 2 | Перем Топики; 3 | 4 | &Пластилин 5 | Перем ПодпискиСерверныхСобытий; 6 | 7 | &Желудь 8 | Процедура ПриСозданииОбъекта() 9 | Топики = Новый Соответствие(); 10 | КонецПроцедуры 11 | 12 | Процедура Добавить(Топик, ОбработчикПодключения = Неопределено, ОбработчикОтключения = Неопределено) Экспорт 13 | 14 | Топики.Вставить(Топик, Истина); 15 | 16 | Если не ОбработчикПодключения = Неопределено Тогда 17 | ПодпискиСерверныхСобытий.ПодпискаНаОткрытие(Топик, ОбработчикПодключения); 18 | КонецЕсли; 19 | 20 | Если не ОбработчикОтключения = Неопределено Тогда 21 | ПодпискиСерверныхСобытий.ПодпискаНаЗакрытие(Топик, ОбработчикОтключения); 22 | КонецЕсли; 23 | 24 | КонецПроцедуры 25 | 26 | Функция Существует(Топик) Экспорт 27 | 28 | Возврат Топики.Получить(Топик) <> Неопределено; 29 | 30 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/ФабрикаВебСерверов.os: -------------------------------------------------------------------------------- 1 | 2 | &ЛогВебСервера 3 | Перем Лог; 4 | 5 | &Пластилин 6 | Перем ПрикладнойВебСервер; 7 | &Пластилин 8 | Перем НативныйВебСервер; 9 | 10 | Перем ИспользоватьНативныйСервер; 11 | 12 | 13 | &Дуб 14 | Процедура ПриСозданииОбъекта(&Пластилин Настройки) 15 | ИспользоватьНативныйСервер = Не Настройки.ИспользоватьПрикладнойСервер И Лев(Новый СистемнаяИнформация().Версия,1) = "2"; 16 | КонецПроцедуры 17 | 18 | 19 | &Завязь(Тип = "Строка") 20 | Функция ВебСервер() Экспорт 21 | 22 | Если ИспользоватьНативныйСервер Тогда 23 | 24 | Лог.Информация("Используется нативный веб-сервер"); 25 | Возврат НативныйВебСервер; 26 | 27 | Иначе 28 | Лог.Информация("Используется прикладной веб-сервер"); 29 | Возврат ПрикладнойВебСервер; 30 | КонецЕсли; 31 | КонецФункции 32 | 33 | -------------------------------------------------------------------------------- /src/Классы/ФабрикаОтветов.os: -------------------------------------------------------------------------------- 1 | Перем Поделка; 2 | Перем МенеджерОтображений; 3 | 4 | &Пластилин Перем ШифрованиеВебСокета; 5 | &Пластилин Перем МенеджерСессий; 6 | 7 | &Желудь 8 | Процедура ПриСозданииОбъекта( 9 | &Пластилин("Поделка") _Поделка, 10 | &Пластилин("МенеджерОтображений") _МенеджерОтображений 11 | ) 12 | Поделка = _Поделка; 13 | МенеджерОтображений = _МенеджерОтображений; 14 | КонецПроцедуры 15 | 16 | Функция СерверноеСобытие() Экспорт 17 | Возврат Новый СерверноеСобытие(); 18 | КонецФункции 19 | 20 | Функция ПустойОтвет() Экспорт 21 | Возврат Поделка.НайтиЖелудь("Ответ"); 22 | КонецФункции 23 | 24 | Функция НовыйОтвет(КодОшибки = Неопределено) Экспорт 25 | НовыйОтвет = ПустойОтвет(); 26 | Если ЗначениеЗаполнено(КодОшибки) Тогда 27 | НовыйОтвет.УстановитьТекстШаблона(ШаблонОшибки(КодОшибки)); 28 | КонецЕсли; 29 | ЗаполнитьОтветПредопределеннымиЗначениям(НовыйОтвет); 30 | Возврат НовыйОтвет; 31 | КонецФункции 32 | 33 | Функция ОтветРукопожатияВебСокета(Запрос) Экспорт 34 | Ответ = ПустойОтвет(); 35 | 36 | Ответ.СостояниеКод = 101; 37 | Ответ.СостояниеТекст = "Switching Protocol"; 38 | 39 | Ответ.Заголовки["Sec-WebSocket-Accept"] = ШифрованиеВебСокета.ХешОтветаРукопожатия(Запрос.КлючРукопожатия); 40 | Ответ.Заголовки["Upgrade"] = "websocket"; 41 | Ответ.Заголовки["Connection"] = "Upgrade"; 42 | Ответ.Заголовки[МенеджерСессий.ИмяКукаСессии()] = Запрос.Сессия.Идентификатор(); 43 | 44 | Возврат Ответ; 45 | КонецФункции 46 | 47 | Функция НовыйОтвет404() Экспорт 48 | НовыйОтвет = НовыйОтвет(404); 49 | НовыйОтвет.УстановитьСостояниеНеНайдено(); 50 | Возврат НовыйОтвет; 51 | КонецФункции 52 | 53 | Функция НовыйОтвет500() Экспорт 54 | НовыйОтвет = НовыйОтвет(500); 55 | НовыйОтвет.УстановитьСостояниеОшибка(); 56 | Возврат НовыйОтвет; 57 | КонецФункции 58 | 59 | Функция НовыйОтвет401() Экспорт 60 | НовыйОтвет = НовыйОтвет(401); 61 | НовыйОтвет.УстановитьСостояниеНеАвторизован(); 62 | Возврат НовыйОтвет; 63 | КонецФункции 64 | 65 | Функция НовыйОтвет403() Экспорт 66 | НовыйОтвет = НовыйОтвет(403); 67 | НовыйОтвет.УстановитьСостояниеДоступЗакрыт(); 68 | Возврат НовыйОтвет; 69 | КонецФункции 70 | 71 | Процедура ЗаполнитьОтветПредопределеннымиЗначениям(Ответ) 72 | Ответ.УстановитьСостояниеОК(); 73 | Ответ.Заголовки["Server"] = "WINOW"; 74 | Ответ.УстановитьТипКонтента("html"); 75 | КонецПроцедуры 76 | 77 | Функция ШаблонОшибки(КодОшибки) 78 | Возврат МенеджерОтображений.ПолучитьОтображение(КодОшибки); 79 | КонецФункции 80 | -------------------------------------------------------------------------------- /src/Классы/ХттпОтвет.os: -------------------------------------------------------------------------------- 1 | 2 | Перем _КодСостояния; 3 | Перем _Тело; 4 | Перем _Заголовки; 5 | Перем _Куки; 6 | 7 | &Желудь 8 | &Характер("Компанейский") 9 | Процедура ПриСозданииОбъекта() 10 | _КодСостояния = 200; 11 | _Тело = ПолучитьБуферДвоичныхДанныхИзСтроки(""); 12 | _Заголовки = Новый Соответствие; 13 | _Куки = Новый Соответствие(); 14 | КонецПроцедуры 15 | 16 | Функция Заголовки(Заголовки) Экспорт 17 | _Заголовки = Заголовки; 18 | Возврат ЭтотОбъект; 19 | КонецФункции 20 | 21 | Функция Кука(Имя, Значение, Параметры = Неопределено) Экспорт 22 | 23 | _Куки[Имя] = Новый Структура("Значение, Параметры", Значение, Параметры); 24 | Возврат ЭтотОбъект; 25 | 26 | КонецФункции 27 | 28 | Функция Заголовок(ИмяЗаголовка, Значение) Экспорт 29 | _Заголовки[ИмяЗаголовка] = Значение; 30 | Возврат ЭтотОбъект; 31 | КонецФункции 32 | 33 | Функция КодСостояния(КодСостояния) Экспорт 34 | _КодСостояния = КодСостояния; 35 | Возврат ЭтотОбъект; 36 | КонецФункции 37 | 38 | Функция ТелоИзСтроки(Строка) Экспорт 39 | _Тело = ПолучитьБуферДвоичныхДанныхИзСтроки(Строка); 40 | Возврат ЭтотОбъект; 41 | КонецФункции 42 | 43 | Функция ТелоИзДвоичныхДанных(ДвоичныеДанные) Экспорт 44 | _Тело = ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(ДвоичныеДанные); 45 | Возврат ЭтотОбъект; 46 | КонецФункции 47 | 48 | Функция ТелоИзФайла(ИмяФайла) Экспорт 49 | 50 | ЧтениеДанных = Новый ЧтениеДанных(ИмяФайла); 51 | 52 | Файл = Новый Файл(ИмяФайла); 53 | 54 | БуферДвоичныхДанных = Новый БуферДвоичныхДанных(Файл.Размер()); 55 | 56 | ЧтениеДанных.ПрочитатьВБуферДвоичныхДанных(БуферДвоичныхДанных); 57 | ЧтениеДанных.Закрыть(); 58 | 59 | _Тело = БуферДвоичныхДанных; 60 | 61 | Возврат ЭтотОбъект; 62 | КонецФункции 63 | 64 | Функция ПолучитьТело() Экспорт 65 | Возврат _Тело; 66 | КонецФункции 67 | 68 | Функция ПолучитьЗаголовки() Экспорт 69 | Возврат _Заголовки; 70 | КонецФункции 71 | 72 | Функция ПолучитьКодСостояния() Экспорт 73 | Возврат _КодСостояния; 74 | КонецФункции 75 | 76 | Функция ПолучитьКуки() Экспорт 77 | Возврат _Куки; 78 | КонецФункции 79 | -------------------------------------------------------------------------------- /src/Классы/Шаблон.os: -------------------------------------------------------------------------------- 1 | Перем КодВыполнения; 2 | Перем ЧастиШаблона; 3 | Перем РамкиБлоков; 4 | Перем СоответствияРамокБлоков; 5 | 6 | Перем ТекстШаблона Экспорт; 7 | 8 | &Пластилин Перем Парсеры; 9 | &Пластилин Перем МенеджерОтображений; 10 | &Пластилин Перем Поделка; 11 | 12 | &Пластилин(Значение = "ПередОбработкойОтображения", Тип = "Массив") Перем ОбработчикиПеред; 13 | &Пластилин(Значение = "ПослеОбработкиОтображения", Тип = "Массив") Перем ОбработчикиПосле; 14 | 15 | &Желудь 16 | &Характер("Компанейский") 17 | Процедура ПриСозданииОбъекта( 18 | &Блестяшка Текст 19 | ) 20 | 21 | ТекстШаблона = Текст; 22 | 23 | РамкиБлоков = Новый Структура(); 24 | РамкиБлоков.Вставить("НачалоВыражения", МассивИзДвухСимволов("{", "{")); 25 | РамкиБлоков.Вставить("ОкончаниеВыражения", МассивИзДвухСимволов("}", "}")); 26 | РамкиБлоков.Вставить("НачалоОператора", МассивИзДвухСимволов("{", "%")); 27 | РамкиБлоков.Вставить("ОкончаниеОператора", МассивИзДвухСимволов("%", "}")); 28 | 29 | СоответствияРамокБлоков = Новый Соответствие; 30 | СоответствияРамокБлоков.Вставить(СтрСоединить(РамкиБлоков.НачалоВыражения, ""), РамкиБлоков.ОкончаниеВыражения); 31 | СоответствияРамокБлоков.Вставить(СтрСоединить(РамкиБлоков.НачалоОператора, ""), РамкиБлоков.ОкончаниеОператора); 32 | 33 | 34 | КонецПроцедуры 35 | 36 | Процедура ИнициализацияПеременных() 37 | 38 | КодВыполнения = Новый Массив(); 39 | ЧастиШаблона = Новый Соответствие(); 40 | 41 | КонецПроцедуры 42 | 43 | Функция СформироватьТекст(Модель) Экспорт 44 | 45 | ВыполнитьОбработчикиПеред(); 46 | 47 | ИнициализацияПеременных(); 48 | 49 | БлокПоиска = Новый Массив(2); 50 | ТекущийПоток = Новый Массив; 51 | 52 | 53 | ИскомоеОкочание = Неопределено; 54 | 55 | Для Сч = 1 по СтрДлина(ТекстШаблона) Цикл 56 | ТекущийСимвол = Сред(ТекстШаблона, Сч, 1); 57 | Парсеры.ДобавитьВМассивСоСмещением(БлокПоиска, ТекущийСимвол); 58 | 59 | Если Парсеры.МассивыРавны(БлокПоиска, РамкиБлоков.НачалоВыражения) 60 | или Парсеры.МассивыРавны(БлокПоиска, РамкиБлоков.НачалоОператора) Тогда 61 | Ид = ДобавитьЧастьШаблона(ТекущийПоток); 62 | ТекущийПоток = Новый Массив; 63 | ИскомоеОкочание = ПолучитьЗакрывающийТег(БлокПоиска); 64 | ЧастьКодаВставкаЧастиШаблона(Ид); 65 | 66 | ИначеЕсли Не ИскомоеОкочание = Неопределено 67 | И Парсеры.МассивыРавны(БлокПоиска, ИскомоеОкочание) Тогда 68 | ЧастьКода = СтрокаИзМассива(ТекущийПоток); 69 | ТекущийПоток = Новый Массив; 70 | ДобавитьЧастьКодаОтОкочания(ЧастьКода, ИскомоеОкочание); 71 | ИскомоеОкочание = Неопределено; 72 | 73 | Иначе 74 | ТекущийПоток.Добавить(ТекущийСимвол); 75 | КонецЕсли; 76 | КонецЦикла; 77 | 78 | Если ТекущийПоток.Количество() > 0 Тогда 79 | ТекущийПоток.Добавить(" "); 80 | Ид = ДобавитьЧастьШаблона(ТекущийПоток); 81 | ЧастьКодаВставкаЧастиШаблона(Ид); 82 | КонецЕсли; 83 | 84 | Результат = Новый Массив; 85 | 86 | ЗаполнитьМассивКодом(Результат, Модель); 87 | 88 | ТекстОтображения = СтрСоединить(Результат, ""); 89 | 90 | ВыполнитьОбработчикиПосле(ТекстОтображения); 91 | 92 | Возврат ТекстОтображения; 93 | 94 | КонецФункции 95 | 96 | Процедура ВыполнитьОбработчикиПеред() 97 | Для Каждого Обработчик Из ОбработчикиПеред Цикл 98 | Обработчик.Преобразовать(ТекстШаблона); 99 | КонецЦикла; 100 | КонецПроцедуры 101 | 102 | Процедура ВыполнитьОбработчикиПосле(ТекстРезультата) 103 | Для Каждого Обработчик Из ОбработчикиПосле Цикл 104 | Обработчик.Преобразовать(ТекстРезультата); 105 | КонецЦикла; 106 | КонецПроцедуры 107 | 108 | Процедура ЗаполнитьМассивКодом(Результат, Модель) 109 | 110 | ВесьКод = СтрСоединить(КодВыполнения); 111 | Выполнить(ВесьКод); 112 | 113 | КонецПроцедуры 114 | 115 | Процедура ДобавитьЧастьКодаОтОкочания(ЧастьКода, Окончание) 116 | 117 | Если Окончание = РамкиБлоков.ОкончаниеВыражения Тогда 118 | КодКДобавлению = СтрШаблон("_Значение = Строка(%1); 119 | |Результат.Добавить(_Значение);", ЧастьКода); 120 | КодВыполнения.Добавить(КодКДобавлению + Символы.ПС); 121 | Иначе 122 | КодВыполнения.Добавить(ЧастьКода + Символы.ПС); 123 | КонецЕсли; 124 | 125 | КонецПроцедуры 126 | 127 | Процедура ЧастьКодаВставкаЧастиШаблона(Ид) 128 | 129 | Код = СтрШаблон("Результат.Добавить(ЧастиШаблона[""%1""]);", Ид); 130 | КодВыполнения.Добавить(Код + Символы.ПС); 131 | 132 | КонецПроцедуры 133 | 134 | Функция ДобавитьЧастьШаблона(МассивСимволов) 135 | 136 | Строка = СтрокаИзМассива(МассивСимволов); 137 | Ид = ХешироватьСтроку(Строка); 138 | 139 | ЧастиШаблона.Вставить(Ид, Строка); 140 | 141 | Возврат Ид; 142 | 143 | КонецФункции 144 | 145 | Функция СтрокаИзМассива(МассивСимволов) 146 | МассивСимволов.Удалить(МассивСимволов.ВГраница()); 147 | Строка = СтрСоединить(МассивСимволов, ""); 148 | Возврат Строка; 149 | КонецФункции 150 | 151 | Функция ХешироватьСтроку(Строка) 152 | 153 | Хеширование = Новый ХешированиеДанных(ХешФункция.MD5); 154 | 155 | Хеширование.Добавить(Строка); 156 | 157 | Возврат Base64Строка(Хеширование.ХешСумма); 158 | 159 | КонецФункции 160 | 161 | Функция МассивИзДвухСимволов(Символ1, Символ2) 162 | 163 | Массив = Новый Массив(2); 164 | Массив[0] = Символ1; 165 | Массив[1] = Символ2; 166 | 167 | Возврат Массив; 168 | 169 | КонецФункции 170 | 171 | Функция ПолучитьЗакрывающийТег(ОткрывающийТег) 172 | 173 | Возврат СоответствияРамокБлоков.Получить(СтрСоединить(ОткрывающийТег,"")); 174 | 175 | КонецФункции 176 | 177 | Функция ВывестиПоШаблону(_ПутьДоШаблона, _Модель) 178 | 179 | ВложенныйШаблон = НовыйЭкземплярШаблона(_ПутьДоШаблона); 180 | 181 | Возврат ВложенныйШаблон.СформироватьТекст(_Модель); 182 | 183 | КонецФункции 184 | 185 | Функция НовыйЭкземплярШаблона(_ПутьДоШаблона) 186 | 187 | Параметры = Новый Массив(); 188 | Параметры.Добавить(МенеджерОтображений.ПолучитьОтображениеИзФайла(_ПутьДоШаблона)); 189 | 190 | Возврат Поделка.НайтиЖелудь("Шаблон", Параметры); 191 | 192 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/ШифрованиеВебСокета.os: -------------------------------------------------------------------------------- 1 | 2 | &Желудь 3 | Процедура ПриСозданииОбъекта() 4 | 5 | КонецПроцедуры 6 | 7 | Функция МагическаяСтрока() Экспорт 8 | Возврат "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; 9 | КонецФункции 10 | 11 | Функция ХешОтветаРукопожатия(КлючРукопожатия) Экспорт 12 | Результат = СокрЛП(КлючРукопожатия) + МагическаяСтрока(); 13 | Провайдер = Новый ХешированиеДанных(ХешФункция.SHA1); 14 | Провайдер.Добавить(Результат); 15 | Результат = Base64Строка(Провайдер.ХешСумма); 16 | Возврат Результат; 17 | КонецФункции 18 | 19 | Функция ЗапаковатьСообщениеТекстовоеСообщение(Сообщение) Экспорт 20 | 21 | ДвоичныеДанныеСообщения = ПолучитьДвоичныеДанныеИзСтроки(Сообщение); 22 | РзамерСообщения = ДвоичныеДанныеСообщения.Размер(); 23 | 24 | Массив = Новый Массив(); 25 | Массив.Добавить(ЧислоВДвоичныеДанные(129)); 26 | 27 | Если РзамерСообщения <= 125 Тогда 28 | Массив.Добавить(ЧислоВДвоичныеДанные(РзамерСообщения)); 29 | 30 | ИначеЕсли РзамерСообщения >= 126 И РзамерСообщения <= 65535 Тогда 31 | Массив.Добавить(ЧислоВДвоичныеДанные(126)); 32 | Массив.Добавить(ЧислоВДвоичныеДанные(ПодготовитьРазмерФреймаДляКодированияОтвета(РзамерСообщения, 8))); 33 | Массив.Добавить(ЧислоВДвоичныеДанные(ПодготовитьРазмерФреймаДляКодированияОтвета(РзамерСообщения))); 34 | 35 | Иначе 36 | Массив.Добавить(127); 37 | Массив.Добавить(ЧислоВДвоичныеДанные(ПодготовитьРазмерФреймаДляКодированияОтвета(РзамерСообщения, 56))); 38 | Массив.Добавить(ЧислоВДвоичныеДанные(ПодготовитьРазмерФреймаДляКодированияОтвета(РзамерСообщения, 48))); 39 | Массив.Добавить(ЧислоВДвоичныеДанные(ПодготовитьРазмерФреймаДляКодированияОтвета(РзамерСообщения, 40))); 40 | Массив.Добавить(ЧислоВДвоичныеДанные(ПодготовитьРазмерФреймаДляКодированияОтвета(РзамерСообщения, 32))); 41 | Массив.Добавить(ЧислоВДвоичныеДанные(ПодготовитьРазмерФреймаДляКодированияОтвета(РзамерСообщения, 24))); 42 | Массив.Добавить(ЧислоВДвоичныеДанные(ПодготовитьРазмерФреймаДляКодированияОтвета(РзамерСообщения, 16))); 43 | Массив.Добавить(ЧислоВДвоичныеДанные(ПодготовитьРазмерФреймаДляКодированияОтвета(РзамерСообщения, 8))); 44 | Массив.Добавить(ЧислоВДвоичныеДанные(ПодготовитьРазмерФреймаДляКодированияОтвета(РзамерСообщения))); 45 | 46 | КонецЕсли; 47 | 48 | Массив.Добавить(ДвоичныеДанныеСообщения); 49 | 50 | Возврат СоединитьДвоичныеДанные(Массив); 51 | 52 | КонецФункции 53 | 54 | Функция РаспаковатьСообщение(ДвоичныеДанныеСообщения) Экспорт 55 | 56 | ДанныеСообщения = Новый Структура("ТипСообщения, Сообщение"); 57 | 58 | Массив = РазделитьДвоичныеДанные(ДвоичныеДанныеСообщения, 1); 59 | 60 | ДанныеСообщения.ТипСообщения = ПобитовоеИ(ДвоичныеДанныеВЧисло(Массив[0]), 15); 61 | 62 | ЗначениеРазмера = ДвоичныеДанныеВЧисло(Массив[1]); 63 | Размер = ПобитовоеИ(ЗначениеРазмера, 127); 64 | 65 | Если Размер = 126 Тогда 66 | ИндексНачалаМаски = 4 67 | ИначеЕсли Размер = 127 Тогда 68 | ИндексНачалаМаски = 10; 69 | Иначе 70 | ИндексНачалаМаски = 2; 71 | КонецЕсли; 72 | 73 | ИндексНачалаДанных = ИндексНачалаМаски + 4; 74 | 75 | Маска = МассивБайтВМассивЧисел(СрезМассива(Массив, ИндексНачалаМаски, ИндексНачалаДанных - 1)); 76 | 77 | Результат = Новый Массив(); 78 | 79 | СчетчикМаски = 0; 80 | 81 | Для _Сч = ИндексНачалаДанных По Массив.ВГраница() Цикл 82 | Код = ПобитовоеИсключительноеИли(ДвоичныеДанныеВЧисло(Массив[_Сч]), Маска[СчетчикМаски % 4]); 83 | Если НЕ Код = 0 Тогда 84 | Результат.Добавить(ЧислоВДвоичныеДанные(Код)); 85 | КонецЕсли; 86 | СчетчикМаски = СчетчикМаски + 1; 87 | КонецЦикла; 88 | 89 | ДанныеСообщения.Сообщение = СоединитьДвоичныеДанные(Результат); 90 | 91 | Если ДанныеСообщения.ТипСообщения = 1 Тогда // Текстовый фрейм 92 | ДанныеСообщения.Сообщение = ПолучитьСтрокуИзДвоичныхДанных(ДанныеСообщения.Сообщение); 93 | КонецЕсли; 94 | 95 | Возврат ДанныеСообщения; 96 | КонецФункции 97 | 98 | Функция ПодготовитьРазмерФреймаДляКодированияОтвета(РзамерСообщения, Сдвиг = 0) 99 | Если Сдвиг > 0 Тогда 100 | Возврат ПобитовоеИ(ПобитовыйСдвигВправо(РзамерСообщения, Сдвиг), 255); 101 | Иначе 102 | Возврат ПобитовоеИ(РзамерСообщения, 255); 103 | КонецЕсли; 104 | КонецФункции 105 | 106 | Функция СрезМассива(Массив, Знач Начало, Знач Конец) 107 | Результат = Новый Массив(); 108 | Для Индекс = Начало По Конец Цикл 109 | Результат.Добавить(Массив[Индекс]); 110 | КонецЦикла; 111 | Возврат Результат; 112 | КонецФункции 113 | 114 | Функция ДвоичныеДанныеВЧисло(ДвоичныеДанные) 115 | Возврат ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(ДвоичныеДанные).Получить(0); 116 | КонецФункции 117 | 118 | Функция МассивБайтВМассивЧисел(Массив) 119 | Результат = Новый Массив(); 120 | Для Каждого Элемент Из Массив Цикл 121 | Результат.Добавить(ДвоичныеДанныеВЧисло(Элемент)); 122 | КонецЦикла; 123 | Возврат Результат; 124 | КонецФункции 125 | 126 | Функция ЧислоВДвоичныеДанные(Число) 127 | Поток = Новый ПотокВПамяти(); 128 | ЗаписьДанных = Новый ЗаписьДанных(Поток); 129 | ЗаписьДанных.ЗаписатьЦелое16(Число); 130 | 131 | Результат = Поток.ЗакрытьИПолучитьДвоичныеДанные(); 132 | ЗаписьДанных.Закрыть(); 133 | 134 | Возврат РазделитьДвоичныеДанные(Результат, 1)[0]; 135 | // Возврат Результат; 136 | КонецФункции 137 | 138 | Функция ТекстВМассивДвоичныеДанныеДляСообщения(Текст) 139 | Результат = Новый Массив(); 140 | 141 | Для _Сч = 1 По СтрДлина(Текст) Цикл 142 | Результат.Добавить(ПолучитьДвоичныеДанныеИзСтроки(Сред(Текст, _Сч, 1))); 143 | КонецЦикла; 144 | 145 | Возврат Результат; 146 | КонецФункции -------------------------------------------------------------------------------- /tasks/coverage.os: -------------------------------------------------------------------------------- 1 | #Использовать 1commands 2 | #Использовать fs 3 | #Использовать coverage 4 | 5 | СистемнаяИнформация = Новый СистемнаяИнформация; 6 | ЭтоWindows = Найти(НРег(СистемнаяИнформация.ВерсияОС), "windows") > 0; 7 | 8 | ФС.ОбеспечитьПустойКаталог("out"); 9 | ПутьКСтат = "out/stat.json"; 10 | 11 | Команда = Новый Команда; 12 | Команда.УстановитьКоманду("oscript"); 13 | Если НЕ ЭтоWindows Тогда 14 | Команда.ДобавитьПараметр("-encoding=utf-8"); 15 | КонецЕсли; 16 | Команда.ДобавитьПараметр(СтрШаблон("-codestat=%1", ПутьКСтат)); 17 | Команда.ДобавитьПараметр("tasks/test.os"); // Файла запуска тестов 18 | Команда.ПоказыватьВыводНемедленно(Истина); 19 | 20 | КодВозврата = Команда.Исполнить(); 21 | 22 | ПроцессорГенерации = Новый ГенераторОтчетаПокрытия(); 23 | 24 | ПроцессорГенерации.ОтносительныеПути() 25 | .РабочийКаталог("out") 26 | .ИмяФайлаСтатистики() 27 | .GenericCoverage() 28 | .Cobertura() 29 | .Сформировать(); 30 | 31 | ЗавершитьРаботу(КодВозврата); 32 | -------------------------------------------------------------------------------- /tasks/oscript.cfg: -------------------------------------------------------------------------------- 1 | lib.system=../oscript_modules 2 | -------------------------------------------------------------------------------- /tasks/test.os: -------------------------------------------------------------------------------- 1 | #Использовать 1testrunner 2 | #Использовать fs 3 | 4 | Функция ПрогнатьТесты() 5 | 6 | Тестер = Новый Тестер; 7 | Тестер.УстановитьФорматЛогФайла(Тестер.ФорматыЛогФайла().GenericExec); 8 | 9 | ПутьКТестам = "tests"; 10 | ПутьКОтчетуJUnit = "out"; 11 | 12 | ФС.ОбеспечитьПустойКаталог(ПутьКОтчетуJUnit); 13 | 14 | РезультатТестирования = Тестер.ТестироватьКаталог( 15 | Новый Файл(ПутьКТестам), 16 | Новый Файл(ПутьКОтчетуJUnit) 17 | ); 18 | 19 | Успешно = РезультатТестирования = 0; 20 | 21 | Возврат Успешно; 22 | КонецФункции // ПрогнатьТесты() 23 | // основной код 24 | 25 | ТекКаталог = ТекущийКаталог(); 26 | 27 | Попытка 28 | ТестыПрошли = ПрогнатьТесты(); 29 | Исключение 30 | ТестыПрошли = Ложь; 31 | Сообщить(СтрШаблон("Тесты через 1testrunner выполнены неудачно 32 | |%1", ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()))); 33 | КонецПопытки; 34 | 35 | УстановитьТекущийКаталог(ТекКаталог); 36 | 37 | Если Не ТестыПрошли Тогда 38 | ВызватьИсключение "Тестирование завершилось неудачно!"; 39 | Иначе 40 | Сообщить(СтрШаблон("Результат прогона тестов <%1> 41 | |", ТестыПрошли)); 42 | КонецЕсли; 43 | -------------------------------------------------------------------------------- /tests/app/files/textfile.txt: -------------------------------------------------------------------------------- 1 | Содержимое текстового файла ! -------------------------------------------------------------------------------- /tests/app/view/1.html: -------------------------------------------------------------------------------- 1 | Текст {{Модель.Текст}}{{ ВывестиПоШаблону("./tests/app/view/2.html", Модель.Вложенный) }} -------------------------------------------------------------------------------- /tests/app/view/2.html: -------------------------------------------------------------------------------- 1 | Вложенный текст {{Модель.Текст}}{%Переменная = "4";%} {{Переменная}} -------------------------------------------------------------------------------- /tests/app/view/3.html: -------------------------------------------------------------------------------- 1 | ТекстБезЗаголовка {{Модель.Текст}} -------------------------------------------------------------------------------- /tests/app/view/main.html: -------------------------------------------------------------------------------- 1 | Заголовок {{Модель.ТекстЗаголовка}} @Контент конец -------------------------------------------------------------------------------- /tests/app/КонтролВебСокета.os: -------------------------------------------------------------------------------- 1 | &Пластилин Перем БрокерСообщенийВебСокетов; 2 | 3 | &Контроллер("/socket") 4 | Процедура ПриСозданииОбъекта() 5 | 6 | КонецПроцедуры 7 | 8 | 9 | &ТочкаМаршрута("ws") 10 | Процедура ДемонстрацияОтображения(Идентификатор, Топик, Сообщение) Экспорт 11 | 12 | БрокерСообщенийВебСокетов.ОтправитьСообщениеВсем(Топик, Сообщение + " 1"); 13 | 14 | КонецПроцедуры -------------------------------------------------------------------------------- /tests/app/КонтролССЕ.os: -------------------------------------------------------------------------------- 1 | 2 | &Пластилин Перем БрокерСообщенийСобытийСервера; 3 | &пластилин Перем ФабрикаОтветов; 4 | 5 | Перем ИмяТопика; 6 | Перем Лог; 7 | 8 | Перем ИдПодключений Экспорт; 9 | Перем КоличествоЗакрытыхСоединений Экспорт; 10 | 11 | &Контроллер("/sse") 12 | Процедура ПриСозданииОбъекта(&Пластилин ТопикиСерверныхСобытий) 13 | 14 | Лог = Логирование.ПолучитьЛог("oscript.app.winow.test.ssecontrol"); 15 | 16 | ИмяТопика = "/sse/test1"; 17 | ТопикиСерверныхСобытий.Добавить(ИмяТопика, Новый Действие(ЭтотОбъект, "НовоеПодключениеССЕ")); 18 | 19 | ТопикиСерверныхСобытий.Добавить("/sse/testsub", 20 | Новый Действие(ЭтотОбъект, "ПодключенияКУдалению"), 21 | Новый Действие(ЭтотОбъект, "ОтключениеССЕ")); 22 | 23 | ИнициализироватьСостояния(); 24 | КонецПроцедуры 25 | 26 | Процедура ИнициализироватьСостояния() Экспорт 27 | ИдПодключений = Новый Массив; 28 | КоличествоЗакрытыхСоединений = 0; 29 | КонецПроцедуры 30 | 31 | Процедура НовоеПодключениеССЕ(Сессия, ИД) Экспорт 32 | 33 | ИдПодключений.Добавить(ИД); 34 | 35 | КонецПроцедуры 36 | 37 | Процедура ПодключенияКУдалению(Сессия, ИД) Экспорт 38 | 39 | Лог.Отладка("Подключился " + Ид); 40 | 41 | КонецПроцедуры 42 | 43 | Процедура ОтключениеССЕ(Сессия, ИД) Экспорт 44 | 45 | Лог.Отладка("Отключился " + Ид); 46 | КоличествоЗакрытыхСоединений = КоличествоЗакрытыхСоединений + 1; 47 | КонецПроцедуры 48 | 49 | &ТочкаМаршрута("") 50 | Процедура Главная() Экспорт 51 | 52 | КонецПроцедуры 53 | 54 | &ТочкаМаршрута("sendall/{Текст}") 55 | Процедура ОтправитьВсем(Текст) Экспорт 56 | Событие = ФабрикаОтветов.СерверноеСобытие(); 57 | Событие.ДобавитьСтроку(Текст); 58 | БрокерСообщенийСобытийСервера.ОтправитьСообщениеВсем(ИмяТопика, Событие); 59 | КонецПроцедуры 60 | 61 | &ТочкаМаршрута("sendalltype/{Текст}") 62 | Процедура ОтправитьВсемКастомныйТип(Текст) Экспорт 63 | Событие = ФабрикаОтветов.СерверноеСобытие(); 64 | Событие.ТипСобытия("evnt").ДобавитьСтроку(Текст); 65 | БрокерСообщенийСобытийСервера.ОтправитьСообщениеВсем(ИмяТопика, Событие); 66 | КонецПроцедуры 67 | 68 | &ТочкаМаршрута("sendbyid/{ид}") 69 | Процедура ОтправитьПоИд(ид) Экспорт 70 | Событие = ФабрикаОтветов.СерверноеСобытие(); 71 | Событие.ДобавитьСтроку("привет"); 72 | БрокерСообщенийСобытийСервера.ОтправитьСообщениеПоИдСоединения(ид, Событие); 73 | КонецПроцедуры 74 | 75 | &ТочкаМаршрута("sendbut/{ид}") 76 | Процедура ОтправитьКроме(ид) Экспорт 77 | Событие = ФабрикаОтветов.СерверноеСобытие(); 78 | Событие.ДобавитьСтроку("привет"); 79 | 80 | Массив = Новый Массив; 81 | Массив.Добавить(ид); 82 | 83 | БрокерСообщенийСобытийСервера.ОтправитьСообщениеВсемКроме(ИмяТопика, Событие, Массив); 84 | КонецПроцедуры -------------------------------------------------------------------------------- /tests/app/КонтролТестирования.os: -------------------------------------------------------------------------------- 1 | &Пластилин 2 | Перем МенеджерОтображений Экспорт; 3 | 4 | &Пластилин 5 | Перем МенеджерДоступа Экспорт; 6 | 7 | &Пластилин 8 | Перем Парсеры Экспорт; 9 | 10 | &Контроллер("/tests") 11 | Процедура ПриСозданииОбъекта() 12 | 13 | КонецПроцедуры 14 | 15 | &ТочкаМаршрута("checkup") 16 | Процедура ПроверкаЗдоровья(Ответ) Экспорт 17 | Ответ.УстановитьТипКонтента("txt"); 18 | Ответ.ТелоТекст = "ок"; 19 | КонецПроцедуры 20 | 21 | &ТочкаМаршрута("getparams") 22 | Процедура ПроверкаГетПараметров(Ответ, ПараметрыЗапросаИменные) Экспорт 23 | Ответ.УстановитьТипКонтента("txt"); 24 | Ответ.ТелоТекст = СтрШаблон("%1 И %2", ПараметрыЗапросаИменные["animal1"], ПараметрыЗапросаИменные["animal2"]); 25 | КонецПроцедуры 26 | 27 | &ТочкаМаршрута("getorderedparams") 28 | Процедура ПроверкаУпорядоченныхГетПараметров(Ответ, ПараметрыЗапросаПорядковые) Экспорт 29 | Ответ.УстановитьТипКонтента("txt"); 30 | Ответ.ТелоТекст = СтрШаблон("%1 И %2", ПараметрыЗапросаПорядковые[0], ПараметрыЗапросаПорядковые[1]); 31 | КонецПроцедуры 32 | 33 | &ТочкаМаршрута("postparams") 34 | Процедура ПроверкаПостТекста(Ответ, ТелоЗапроса) Экспорт 35 | Ответ.УстановитьТипКонтента("txt"); 36 | ПостПараметры = Парсеры.ПараметрыИзТекста(ТелоЗапроса); 37 | Ответ.ТелоТекст = СтрШаблон("%1 И %2", ПостПараметры["animal1"], ПостПараметры["animal2"]); 38 | КонецПроцедуры 39 | 40 | &ТочкаМаршрута("setcookie") 41 | Процедура УстановитьКуку(Ответ, ПараметрыЗапросаИменные) Экспорт 42 | ИмяКуки = "pechenka"; 43 | ЗначениеКуки = ПараметрыЗапросаИменные["pechenka"]; 44 | ДатаИстечения = XMLЗначение(Тип("Дата"), ПараметрыЗапросаИменные["expires"]); 45 | НоваяКука = Ответ.Куки.Добавить(ИмяКуки, ЗначениеКуки); 46 | НоваяКука.ДатаИстечения = ДатаИстечения; 47 | КонецПроцедуры 48 | 49 | &ТочкаМаршрута("setsessiondata") 50 | Процедура УстановитьДанныеСессии(Ответ, ДанныеСессии, ПараметрыЗапросаИменные) Экспорт 51 | ДанныеПользователя = ПараметрыЗапросаИменные["userdata"]; 52 | ИмяПараметраСессии = "ДанныеПользователя"; 53 | ДанныеСессии[ИмяПараметраСессии] = ДанныеПользователя; 54 | КонецПроцедуры 55 | 56 | &ТочкаМаршрута("readsessiondata") 57 | Процедура ПрочитатьДанныеСессии(Ответ, ДанныеСессии) Экспорт 58 | ИмяПараметраСессии = "ДанныеПользователя"; 59 | ЗначениеПараметраСессии = ДанныеСессии[ИмяПараметраСессии]; 60 | Ответ.ТелоТекст = ЗначениеПараметраСессии; 61 | КонецПроцедуры 62 | 63 | &ФинальныйШтрих 64 | Процедура ПроинициализироватьРоли() Экспорт 65 | МенеджерДоступа.ДобавитьТокен("Пользователь", "111"); 66 | МенеджерДоступа.ДобавитьРольЛогина("Пользователь", "Пользователи"); 67 | КонецПроцедуры 68 | 69 | &ТочкаМаршрута("user") 70 | &Роли("Пользователи") 71 | Процедура Пользователь(Ответ) Экспорт 72 | 73 | Ответ.ТелоТекст = "Ок"; 74 | 75 | КонецПроцедуры 76 | 77 | &ТочкаМаршрута("templateuri/{Ягода}/{Фрукт}/{Овощь}") 78 | Процедура ШаблонныеПараметрыПути(Ответ, Фрукт, Овощь, Ягода) Экспорт 79 | Ответ.УстановитьТипКонтента("txt"); 80 | Ответ.ТелоТекст = СтрШаблон("%1 %2 %3", Ягода, Фрукт, Овощь); 81 | КонецПроцедуры 82 | 83 | &ТочкаМаршрута("calc/plus/{Число1}/{Число2}") 84 | Процедура ШаблонныеПараметрыСложение(Ответ, Число1, Число2) Экспорт 85 | Ответ.УстановитьТипКонтента("txt"); 86 | Ответ.ТелоТекст = Число(Число1) + Число(Число2); 87 | КонецПроцедуры 88 | 89 | &ТочкаМаршрута("calc/minus/{Число1}/{Число2}") 90 | Процедура ШаблонныеПараметрыВычитание(Ответ, Число1, Число2) Экспорт 91 | Ответ.УстановитьТипКонтента("txt"); 92 | Ответ.ТелоТекст = Число(Число1) - Число(Число2); 93 | КонецПроцедуры 94 | 95 | &ТочкаМаршрута("calc/{Число1}/multiply/{Число2}") 96 | Процедура ШаблонныеПараметрыУмножение(Ответ, Число1, Число2) Экспорт 97 | Ответ.УстановитьТипКонтента("txt"); 98 | Ответ.ТелоТекст = Число(Число1) * Число(Число2); 99 | КонецПроцедуры 100 | 101 | &ТочкаМаршрута("calc/{Число1}/devide/{Число2}") 102 | Процедура ШаблонныеПараметрыДеление(Ответ, Число1, Число2) Экспорт 103 | Ответ.УстановитьТипКонтента("txt"); 104 | Ответ.ТелоТекст = Число(Число1) / Число(Число2); 105 | КонецПроцедуры 106 | 107 | &ТочкаМаршрута("getparamsbyname") 108 | Процедура ПроверкаГетПараметровПоИмени(Ответ, ИмяКошки, ИмяСобаки) Экспорт 109 | Ответ.УстановитьТипКонтента("txt"); 110 | Ответ.ТелоТекст = СтрШаблон("%1 И %2", "ИмяКошки=" + ИмяКошки, "ИмяСобаки=" + ИмяСобаки); 111 | КонецПроцедуры 112 | 113 | &ТочкаМаршрута("postjsonbody") 114 | Процедура ПроверкаПостЗапросаКакОбъект(Ответ, ТелоЗапросОбъект, ЗаголовкиЗапроса) Экспорт 115 | Ответ.УстановитьТипКонтента("txt"); 116 | Ответ.ТелоТекст = СтрШаблон("%1 %2", ТелоЗапросОбъект.Имя, ТелоЗапросОбъект.Фамилия); 117 | КонецПроцедуры 118 | 119 | &ТочкаМаршрута("postformbody") 120 | Процедура ПроверкаПостЗапросаКакФорма(Ответ, Имя, Фамилия) Экспорт 121 | Ответ.УстановитьТипКонтента("txt"); 122 | Ответ.ТелоТекст = СтрШаблон("%1 %2", Имя, Фамилия); 123 | КонецПроцедуры -------------------------------------------------------------------------------- /tests/app/КонтролТестированияОтображений.os: -------------------------------------------------------------------------------- 1 | &Пластилин 2 | Перем МенеджерОтображений Экспорт; 3 | 4 | 5 | &Контроллер("/tests/view") 6 | &Отображение(Шаблон = "./tests/app/view/main.html", Метод = "ПолучитьМодельКонтрола") 7 | Процедура ПриСозданииОбъекта() 8 | 9 | КонецПроцедуры 10 | 11 | Функция ПолучитьМодельКонтрола() Экспорт 12 | Модель = Новый Структура("ТекстЗаголовка", "1"); 13 | 14 | Возврат Модель; 15 | КонецФункции 16 | 17 | &Отображение("./tests/app/view/1.html") 18 | &ТочкаМаршрута("1") 19 | Процедура ДемонстрацияОтображения(Ответ) Экспорт 20 | Ответ.Модель = Новый Структура("Текст", "2"); 21 | Ответ.Модель.Вставить("Вложенный", Новый Структура("Текст", "3")); 22 | КонецПроцедуры 23 | 24 | &Отображение("./tests/app/view/3.html") 25 | &НеВыводитОтображениеКонтроллера 26 | &ТочкаМаршрута("2") 27 | Процедура ДемонстрацияОтображенияБезГлобальногоОтображения(Ответ) Экспорт 28 | Ответ.Модель = Новый Структура("Текст", "1"); 29 | КонецПроцедуры 30 | -------------------------------------------------------------------------------- /tests/app/КорневойКонтрол.os: -------------------------------------------------------------------------------- 1 | 2 | &Контроллер("/") 3 | Процедура ПриСозданииОбъекта() 4 | 5 | КонецПроцедуры 6 | 7 | &ТочкаМаршрута("api/{ИмяПараметра}") 8 | Процедура ПараметизированныйМаршрут(Запрос, Ответ, ЗаголовкиЗапроса, ИмяПараметра) Экспорт 9 | Ответ.ТелоТекст = ИмяПараметра; 10 | КонецПроцедуры -------------------------------------------------------------------------------- /tests/app/ССЕКлиент.os: -------------------------------------------------------------------------------- 1 | #Использовать logos 2 | 3 | Перем Сообщения; 4 | Перем Соединение; 5 | Перем ПервичныйОтвет; 6 | Перем Слушать; 7 | Перем Лог; 8 | 9 | Процедура ПриСозданииОбъекта(Хост, Порт, Топик) 10 | Лог = Логирование.ПолучитьЛог("oscript.app.winow.test.sseclient"); 11 | Сообщения = Новый Массив(); 12 | Соединение = Новый TCPСоединение(Хост, Порт); 13 | УстановитьПодключение(Топик); 14 | Слушать = Истина; 15 | НачатьПрослушку(); 16 | КонецПроцедуры 17 | 18 | Процедура Остановить() Экспорт 19 | Слушать = Ложь; 20 | КонецПроцедуры 21 | 22 | Процедура ЖдатьСообщения() Экспорт 23 | Пока Слушать Цикл 24 | Ответ = Соединение.ПрочитатьСтроку(); 25 | Если НЕ ПустаяСтрока(Ответ) Тогда 26 | Если СтрНайти(Ответ, "ping") = 0 Тогда 27 | Сообщения.Добавить(СокрЛП(Ответ)); 28 | Лог.Отладка("Принято сообщение: " + Ответ); 29 | КонецЕсли; 30 | КонецЕсли; 31 | Приостановить(100); 32 | КонецЦикла; 33 | Соединение.Закрыть(); 34 | Соединение = Неопределено; 35 | Лог.Отладка("Соединение закрыто"); 36 | КонецПроцедуры 37 | 38 | Процедура НачатьПрослушку() 39 | ФоновыеЗадания.Выполнить(ЭтотОбъект, "ЖдатьСообщения"); 40 | КонецПроцедуры 41 | 42 | Функция ПервичныйОтвет() Экспорт 43 | Возврат ПервичныйОтвет; 44 | КонецФункции 45 | 46 | Функция Сообщения() Экспорт 47 | Возврат Сообщения; 48 | КонецФункции 49 | 50 | Процедура УстановитьПодключение(Топик) 51 | Лог.Отладка("Установка соединения"); 52 | ТекстПодключения = ШаблонПодключения(); 53 | 54 | Соединение.ОтправитьСтроку(СтрШаблон(ТекстПодключения, Топик)); 55 | 56 | ПервичныйОтвет = Соединение.ПрочитатьСтроку(); 57 | 58 | Если Не СтрНачинаетсяС(ПервичныйОтвет, "HTTP/1.1 200 OK") Тогда 59 | ВызватьИсключение "Не удалось подключиться к топику " + Топик + " по причине: " + ПервичныйОтвет; 60 | КонецЕсли; 61 | Лог.Отладка("Соединение установлено"); 62 | КонецПроцедуры 63 | 64 | Функция ШаблонПодключения() 65 | 66 | Текст = 67 | "GET %1 HTTP/1.1 68 | |Accept: text/event-stream 69 | |Connection: keep-alive 70 | |"; 71 | 72 | Возврат Текст; 73 | 74 | КонецФункции 75 | -------------------------------------------------------------------------------- /tests/features/client1: -------------------------------------------------------------------------------- 1 | HTTP/1.1 101 Switching Protocols 2 | Upgrade: websocket 3 | Connection: Upgrade 4 | Sec-WebSocket-Accept: LEHPu4/qNukG+0hW+UjpnJTeoc8= 5 | 6 | -------------------------------------------------------------------------------- /tests/features/client2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/tests/features/client2 -------------------------------------------------------------------------------- /tests/features/img.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/tests/features/img.jpg -------------------------------------------------------------------------------- /tests/features/multipart-form-data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/tests/features/multipart-form-data -------------------------------------------------------------------------------- /tests/features/server1: -------------------------------------------------------------------------------- 1 | GET /socket/ws HTTP/1.1 2 | Host: localhost:3333 3 | User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/109.0 4 | Accept: */* 5 | Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3 6 | Accept-Encoding: gzip, deflate, br 7 | Sec-WebSocket-Version: 13 8 | Origin: null 9 | Sec-WebSocket-Extensions: permessage-deflate 10 | Sec-WebSocket-Key: Ve8z7rYjrE2GVl872O1ZEg== 11 | DNT: 1 12 | Connection: keep-alive, Upgrade 13 | Sec-Fetch-Dest: websocket 14 | Sec-Fetch-Mode: websocket 15 | Sec-Fetch-Site: cross-site 16 | Pragma: no-cache 17 | Cache-Control: no-cache 18 | Upgrade: websocket 19 | 20 | -------------------------------------------------------------------------------- /tests/features/server2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/winow/f8b4a20917265bd61c2744db05a194a9b3981c15/tests/features/server2 -------------------------------------------------------------------------------- /tests/mock/мокПередОбработкойОтображения.os: -------------------------------------------------------------------------------- 1 | 2 | &Желудь 3 | &Прозвище("ПередОбработкойОтображения") 4 | Процедура ПриСозданииОбъекта() 5 | 6 | КонецПроцедуры 7 | 8 | Процедура Преобразовать(ТекстШаблона) Экспорт 9 | ТекстШаблона = СтрЗаменить(ТекстШаблона, "@до", "1"); 10 | КонецПроцедуры -------------------------------------------------------------------------------- /tests/mock/мокПослеОбработкиОтображения.os: -------------------------------------------------------------------------------- 1 | 2 | &Желудь 3 | &Прозвище("ПослеОбработкиОтображения") 4 | Процедура ПриСозданииОбъекта() 5 | 6 | КонецПроцедуры 7 | 8 | Процедура Преобразовать(ТекстШаблона) Экспорт 9 | ТекстШаблона = СтрЗаменить(ТекстШаблона, "@после", "3"); 10 | КонецПроцедуры -------------------------------------------------------------------------------- /tests/mock/мокПослеОбработкиОтображения2.os: -------------------------------------------------------------------------------- 1 | 2 | &Желудь 3 | &Прозвище("ПослеОбработкиОтображения") 4 | Процедура ПриСозданииОбъекта() 5 | 6 | КонецПроцедуры 7 | 8 | Процедура Преобразовать(ТекстШаблона) Экспорт 9 | ТекстШаблона = СтрЗаменить(ТекстШаблона, "@конец", "!"); 10 | КонецПроцедуры -------------------------------------------------------------------------------- /tests/parser.os: -------------------------------------------------------------------------------- 1 | #Использовать autumn 2 | #Использовать ".." 3 | #Использовать asserts 4 | 5 | Функция ТестовыеДД() 6 | Возврат Новый ДвоичныеДанные("tests/features/multipart-form-data"); 7 | КонецФункции 8 | 9 | &Тест 10 | Процедура РазбиениеДДВМассивПростой() Экспорт 11 | 12 | // Дано 13 | Поделка = Новый Поделка(); 14 | Поделка.ПросканироватьКаталог("tests/mock/"); 15 | Поделка.ЗапуститьПриложение(); 16 | Парсеры = Поделка.НайтиЖелудь("Парсеры"); 17 | 18 | ДанныеФормыДД = ТестовыеДД(); 19 | 20 | // Когда 21 | Результат = Парсеры.РазделитьДвоичныеДанныеРазделителемВМассив(ДанныеФормыДД, ПолучитьДвоичныеДанныеИзСтроки("---------------------------186955378527859643922779568670")); 22 | 23 | //Тогда 24 | Ожидаем.Что(Результат).ИмеетТип("Массив"); 25 | Ожидаем.Что(Результат.Количество()).Равно(6); 26 | Ожидаем.Что(Результат[1]).Равно(ПолучитьДвоичныеДанныеИзСтроки(Символы.ВК + Символы.ПС + "Content-Disposition: form-data; name=""name""" + Символы.ВК + Символы.ПС + Символы.ВК + Символы.ПС + "nonamed" + Символы.ВК + Символы.ПС + "--")); 27 | Ожидаем.Что(Результат[2]).Равно(ПолучитьДвоичныеДанныеИзСтроки(Символы.ВК + Символы.ПС + "Content-Disposition: form-data; name=""text""" + Символы.ВК + Символы.ПС + Символы.ВК + Символы.ПС + "text1" + Символы.ВК + Символы.ПС + Символы.ВК + Символы.ПС + "text2" + Символы.ВК + Символы.ПС + "--")); 28 | Ожидаем.Что(ПолучитьСтрокуИзДвоичныхДанных(Результат[3])).Равно(Символы.ВК + Символы.ПС + "Content-Disposition: form-data; name=""age""" + Символы.ВК + Символы.ПС + Символы.ВК + Символы.ПС + "2023-09-13" + Символы.ВК + Символы.ПС + "--"); 29 | Ожидаем.Что((ПолучитьСтрокуИзДвоичныхДанных(Результат[0]))).Равно("--"); 30 | Ожидаем.Что((ПолучитьСтрокуИзДвоичныхДанных(Результат[5]))).Равно("--" + Символы.ВК + Символы.ПС); 31 | 32 | КонецПроцедуры 33 | 34 | &Тест 35 | Процедура ПолучениеДанныхФормы() Экспорт 36 | 37 | // Дано 38 | Поделка = Новый Поделка(); 39 | Поделка.ПросканироватьКаталог("tests/mock/"); 40 | Поделка.ЗапуститьПриложение(); 41 | Парсеры = Поделка.НайтиЖелудь("Парсеры"); 42 | ВходящийЗапрос = Поделка.НайтиЖелудь("ВходящийЗапрос"); 43 | 44 | ВходящийЗапрос.ТелоДвоичныеДанные = ТестовыеДД(); 45 | ВходящийЗапрос.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=---------------------------186955378527859643922779568670"); 46 | 47 | // Когда 48 | ДанныеФормы = ВходящийЗапрос.ЗначенияПараметровДляТочкиМаршрута()["ДанныеФормы"]; 49 | 50 | РабочийОтбор = Новый Соответствие(); 51 | РабочийОтбор.Вставить("name", "name"); 52 | 53 | НеРабочийОтбор = Новый Соответствие(); 54 | НеРабочийОтбор.Вставить("name", "unexist"); 55 | 56 | // Тогда 57 | Ожидаем.Что(ДанныеФормы).ИмеетТип("ДанныеСоставнойФормы"); 58 | Ожидаем.Что(ДанныеФормы.Количество()).Равно(4); 59 | 60 | Ожидаем.Что(ДанныеФормы.ПолучитьПоИндексу(0)).ИмеетТип("Структура"); 61 | Ожидаем.Что(ПолучитьСтрокуИзДвоичныхДанных(ДанныеФормы.ПолучитьПоИндексу(0).Значение)).Равно("nonamed"); 62 | Ожидаем.Что(ДанныеФормы.ПолучитьПоИндексу(0).Метаданные).ИмеетТип("Соответствие"); 63 | Ожидаем.Что(ДанныеФормы.ПолучитьПоИндексу(0).Метаданные["Content-Disposition"]).ИмеетТип("Соответствие"); 64 | Ожидаем.Что(ДанныеФормы.ПолучитьПоИндексу(0).Метаданные["Content-Disposition"].Количество()).Равно(2); 65 | Ожидаем.Что(ДанныеФормы.ПолучитьПоИндексу(0).Метаданные["Content-Disposition"]["name"]).Равно("name"); 66 | 67 | Ожидаем.Что(ДанныеФормы.ПолучитьПоИндексу(1)).ИмеетТип("Структура"); 68 | Ожидаем.Что(ПолучитьСтрокуИзДвоичныхДанных(ДанныеФормы.ПолучитьПоИндексу(1).Значение)).Равно("text1" + Символы.ВК + Символы.ПС + Символы.ВК + Символы.ПС + "text2"); 69 | Ожидаем.Что(ДанныеФормы.ПолучитьПоИндексу(1).Метаданные).ИмеетТип("Соответствие"); 70 | Ожидаем.Что(ДанныеФормы.ПолучитьПоИндексу(1).Метаданные["Content-Disposition"]).ИмеетТип("Соответствие"); 71 | Ожидаем.Что(ДанныеФормы.ПолучитьПоИндексу(1).Метаданные["Content-Disposition"].Количество()).Равно(2); 72 | Ожидаем.Что(ДанныеФормы.ПолучитьПоИндексу(1).Метаданные["Content-Disposition"]["name"]).Равно("text"); 73 | 74 | Ожидаем.Что(ДанныеФормы.ПолучитьПоИндексу(2)).ИмеетТип("Структура"); 75 | Ожидаем.Что(ПолучитьСтрокуИзДвоичныхДанных(ДанныеФормы.ПолучитьПоИндексу(2).Значение)).Равно("2023-09-13"); 76 | Ожидаем.Что(ДанныеФормы.ПолучитьПоИндексу(2).Метаданные).ИмеетТип("Соответствие"); 77 | Ожидаем.Что(ДанныеФормы.ПолучитьПоИндексу(2).Метаданные["Content-Disposition"]).ИмеетТип("Соответствие"); 78 | Ожидаем.Что(ДанныеФормы.ПолучитьПоИндексу(2).Метаданные["Content-Disposition"].Количество()).Равно(2); 79 | Ожидаем.Что(ДанныеФормы.ПолучитьПоИндексу(2).Метаданные["Content-Disposition"]["name"]).Равно("age"); 80 | 81 | Ожидаем.Что(ДанныеФормы.НайтиЗначениеСтрокойПоМетаданным(РабочийОтбор)).Равно("nonamed"); 82 | Ожидаем.Что(ДанныеФормы.НайтиЗначениеПоМетаданным(РабочийОтбор)).Равно(ПолучитьДвоичныеДанныеИзСтроки("nonamed")); 83 | Ожидаем.Что(ДанныеФормы.НайтиДанныеПоМетаданным(НеРабочийОтбор)).Равно(Неопределено); 84 | 85 | Ожидаем.Что(ДанныеФормы.НайтиЗначениеПоМетаданным(Новый Структура("name", "file"))).Равно(Новый ДвоичныеДанные("tests/features/img.jpg")); 86 | 87 | КонецПроцедуры 88 | 89 | &Тест 90 | Процедура ПолучениеСтруктурыУзла() Экспорт 91 | 92 | // Дано 93 | Поделка = Новый Поделка(); 94 | Поделка.ЗапуститьПриложение(); 95 | Парсеры = Поделка.НайтиЖелудь("Парсеры"); 96 | 97 | ВалидныеТестовыеЗначения = СтрРазделить(" 98 | |||0 99 | |127.0.0.1|127.0.0.1|0 100 | |127.0.0.1:80|127.0.0.1|80 101 | |3ffe:38e1::0100:1:0001|3ffe:38e1::0100:1:0001|0 102 | |[2001:0db8::0001]|2001:0db8::0001|0 103 | |[11:22:33:44:55:66:77:8]:3333|11:22:33:44:55:66:77:8|3333 104 | |", Символы.ПС, Ложь); 105 | 106 | // Когда 107 | Для Каждого Строка Из ВалидныеТестовыеЗначения Цикл 108 | 109 | Подстроки = СтрРазделить(Строка, "|"); 110 | 111 | ТестовоеЗначение = Подстроки[0]; 112 | Адрес = Подстроки[1]; 113 | Порт = Число(Подстроки[2]); 114 | 115 | СтруктураУзла = Парсеры.СтруктураУзла(ТестовоеЗначение); 116 | 117 | Ожидаем.Что(СтруктураУзла.Адрес).Равно(Адрес); 118 | Ожидаем.Что(СтруктураУзла.Порт).Равно(Порт); 119 | 120 | КонецЦикла; 121 | 122 | КонецПроцедуры -------------------------------------------------------------------------------- /tests/templateProcessor.os: -------------------------------------------------------------------------------- 1 | #Использовать autumn 2 | #Использовать ".." 3 | #Использовать asserts 4 | 5 | &Тест 6 | Процедура ПроверкаОбработчиковШаблона() Экспорт 7 | 8 | // Дано 9 | ПодключитьСценарий("tests/mock/мокПередОбработкойОтображения.os", "мокПередОбработкойОтображения"); 10 | ПодключитьСценарий("tests/mock/мокПослеОбработкиОтображения.os", "мокПослеОбработкиОтображения"); 11 | ПодключитьСценарий("tests/mock/мокПослеОбработкиОтображения2.os", "мокПослеОбработкиОтображения2"); 12 | Поделка = Новый Поделка(); 13 | Поделка.ПросканироватьКаталог("tests/mock/"); 14 | Поделка.ЗапуститьПриложение(); 15 | ТекстШаблона = "@до{{Модель}}@после@конец"; 16 | Параметры = Новый Массив(); 17 | Параметры.Добавить(ТекстШаблона); 18 | Шаблон = Поделка.НайтиЖелудь("Шаблон", Параметры); 19 | 20 | // Когда 21 | Результат = Шаблон.СформироватьТекст("2"); 22 | 23 | //Тогда 24 | Ожидаем.Что(Результат).Равно("123!"); 25 | 26 | КонецПроцедуры 27 | -------------------------------------------------------------------------------- /tools/proxy.os: -------------------------------------------------------------------------------- 1 | 2 | ТСПСервер = Новый TCPСервер(3333); 3 | ПортЦели = 3331; 4 | ХостЦели = "localhost"; 5 | 6 | ТСПСервер.Запустить(); 7 | 8 | Счетчик = 0; 9 | ВсегоЗапросов = 5; 10 | 11 | Пока Счетчик <= ВсегоЗапросов Цикл 12 | 13 | СоединениеВХ = ТСПСервер.ОжидатьСоединения(); 14 | 15 | Сообщить(Счетчик); 16 | 17 | Сообщить(ТекущаяДата()); 18 | 19 | ТекстЗапроса = СоединениеВХ.ПрочитатьДвоичныеДанные(); 20 | 21 | Сообщить("--zapros"); 22 | 23 | Сообщить(ПолучитьСтрокуИзДвоичныхДанных(ТекстЗапроса)); 24 | 25 | СоединениеИСХ = Новый TCPСоединение(ХостЦели, ПортЦели); 26 | 27 | СоединениеИСХ.ОтправитьДвоичныеДанные(ТекстЗапроса); 28 | 29 | Сообщить("--otvet"); 30 | 31 | Ответ = СоединениеИСХ.ПрочитатьДвоичныеДанные(); 32 | 33 | Сообщить(ПолучитьСтрокуИзДвоичныхДанных(Ответ)); 34 | 35 | СоединениеИСХ.Закрыть(); 36 | 37 | СоединениеВХ.ОтправитьДвоичныеДанные(Ответ); 38 | 39 | СоединениеВХ.Закрыть(); 40 | 41 | Счетчик = Счетчик + 1; 42 | 43 | КонецЦикла; 44 | 45 | ТСПСервер.Остановить(); 46 | --------------------------------------------------------------------------------