Parametrise playbook for a Swedish deployment

- Domain, admin email and git sources are variables (vars.yml); site.yml asserts
  that placeholders have been replaced before running
- Remove DARC maintainers' SSH keys and the German URL-shortener redirects
- Track the sv branch by default
- README in Swedish

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-10 15:03:02 +02:00
co-authored by Claude Sonnet 5.5
parent eaebb488ff
commit 691d60f1cd
9 changed files with 83 additions and 160 deletions
+32 -11
View File
@@ -1,16 +1,37 @@
# Ansible Playbook zur Installation von 50ohm.de
# Ansible-playbook för att driftsätta den svenska 50ohm-sajten
- Installiert die Code Repositories für 50ohm.de und das Content-Repository
- Initialisiert die Python Build-Umgebung
- Baut die Webseite erstmalig
- Konfiguriert Certbot und Nginx
- Installiert einen Systemd-Timer zum regelmäßigen Refresh
Playbooken är en anpassning av [DARC e.V:s 50ohm-ansible](https://github.com/DARC-e-V/50ohm-ansible) (se `LICENSE`) för den svenska versionen av 50ohm.de (Instegscertifikat och HAREC). Den är inte kopplad till DARC, SSA eller PTS.
## Voraussetzungen
- Installerar kodrepot (generatorn) och innehållsrepot
- Initierar Python-byggmiljön (`uv`)
- Bygger webbplatsen första gången
- Konfigurerar Certbot (Let's Encrypt) och Nginx
- Installerar en systemd-timer som var 15:e minut hämtar nya ändringar och bygger om sajten
Wir verwenden ein Debian 12 System. Nur darauf ist der Code getestet.
## Förutsättningar
## TODO
- En server med Debian 12 (endast detta är testat) och SSH-åtkomst som root eller en användare med sudo.
- DNS-poster (A/AAAA) för domänen och `www.`-varianten som pekar på servern.
- Ansible på din egen dator, samt rollerna: `ansible-galaxy install -r requirements.yml`.
- Umbau auf Docker
- Verwendung von Webhooks statt eines Timers
## Konfiguration (görs innan första körningen)
1. `vars.yml`: sätt `site_domain`, `site_admin_email`, `fiftyohm_repo` och `fiftyohm_contents_dl_repo`
(dina egna repon/forkar; grenen är som standard `sv`). `site.yml` avbryter om platshållarna är kvar.
2. `inventory.yml`: byt `example.se` mot din server.
3. `users.yml`: lägg till de administratörer som ska få SSH-nyckel och sudo. Listan är tom som standard.
Obs: användare i gruppen `sudo` får lösenordsfri sudo.
## Körning
```console
$ ansible-playbook -i inventory.yml site.yml
```
Delmoment kan köras med taggarna `base`, `build`, `webserver` och `timer`.
## Att göra
- Byta till Docker
- Använda webhooks i stället för timer
- Egen domän-redirect/URL-förkortare behövs inte längre; det tyska förkortarsystemet (`/mw`, `/rzp`, …) har tagits bort tillsammans med länkarna i innehållet.
+2 -1
View File
@@ -1,3 +1,4 @@
# Byt ut mot din server (samma värde som site_domain i vars.yml, eller ett IP-nummer/alias)
webservers:
hosts:
50ohm.de:
50ohm.se:
@@ -1,91 +0,0 @@
rewrite ^/vn01/?$ https://www.youtube.com/watch?v=WnOBk1UogjM&t=0s permanent;
rewrite ^/mw/?$ https://antrag.darc.de/antrag/schritt-1 permanent;
rewrite ^/rzp/?$ https://www.bundesnetzagentur.de/DE/Fachthemen/Telekommunikation/Frequenzen/SpezielleAnwendungen/Amateurfunk/DL_Vfg_AFu/Rufzeichenplan_10_24_Auszug_aus_Vfg_15_2025.pdf?__blob=publicationFile&v=3 redirect;
rewrite ^/rzl/?$ https://data.bundesnetzagentur.de/Bundesnetzagentur/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Amateurfunk/Rufzeichenliste/rufzeichenliste_afu.pdf permanent;
rewrite ^/rza/?$ https://ans.bundesnetzagentur.de/Amateurfunk/Rufzeichen.aspx permanent;
rewrite ^/cll/?$ https://www.darc.de/der-club/referate/ausland/funken-im-ausland/cept-laenderliste/ permanent;
rewrite ^/ra/?$ https://www.darc.de/der-club/referate/ausland/ permanent;
rewrite ^/ww/?$ https://www.bundesnetzagentur.de/DE/Fachthemen/Telekommunikation/Technik/EMF/start.html#doc866800bodyText8 permanent;
rewrite ^/a1/?$ https://www.gesetze-im-internet.de/afuv_2005/anlage_1.html permanent;
rewrite ^/rnf/?$ https://www.darc.de/der-club/referate/notfunk/ permanent;
rewrite ^/vde-blitz/?$ https://www.vde.com/resource/blob/2001262/56f5576bbaf617b1e9e5195d1e8411d9/vde-information-blitzschutz-funkanlagen-download-data.pdf permanent;
rewrite ^/bfs/?$ https://www.bfs.de/DE/themen/emf/hff/wirkung/hff-nachgewiesen/hff-nachgewiesen.html permanent;
rewrite ^/hamnet/?$ https://hamnetdb.net/map.cgi permanent;
rewrite ^/sim/?$ https://afup.a36.de/pruefungen/pruefungen2.html permanent;
rewrite ^/dl-de/?$ http://www.govdata.de/dl-de/by-2-0 permanent;
rewrite ^/fs/?$ https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Amateurfunk/AntraegeFormulare/Hilfsmittel_12062024.pdf?__blob=publicationFile&v=3#page=13 redirect;
rewrite ^/bp/?$ https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Amateurfunk/AntraegeFormulare/Hilfsmittel_12062024.pdf?__blob=publicationFile&v=3#page=11 redirect;
rewrite ^/hm/?$ https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Amateurfunk/AntraegeFormulare/Hilfsmittel_12062024.pdf?__blob=publicationFile&v=3 redirect;
rewrite ^/tr/?$ https://dd3ah.de/wp-content/uploads/2019/01/rechnen.pdf permanent;
rewrite ^/rs/?$ https://www.rohde-schwarz.com/ausbildung permanent;
rewrite ^/ajw/?$ https://ajw.darc.de permanent;
rewrite ^/wl/?$ https://www.wavelog.org permanent;
rewrite ^/wlv/?$ https://www.youtube.com/watch?v=G5mJjrKLJvE permanent;
rewrite ^/log/?$ https://log.darc.de permanent;
rewrite ^/buch/?$ https://darcverlag.de/DARC-Amateurfunklehrgang-Klasse-N permanent;
rewrite ^/fk/?$ https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Amateurfunk/Fragenkatalog/Pruefungsfragen.pdf?__blob=publicationFile&v=2 redirect;
rewrite ^/geb/?$ https://www.bundesnetzagentur.de/DE/Beschlusskammern/BK02/BK2_01_Aktuell/Downloads/BK2_3_BMDVTKBGebV_download.pdf?__blob=publicationFile&v=4#page=12 redirect;
rewrite ^/wiki-dds/?$ https://de.wikipedia.org/wiki/Direct_Digital_Synthesis permanent;
rewrite ^/vfg33/?$ https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Amateurfunk/AmtsblattverfuegungenAFu/Vfg332007Ver246ffentlicId10701pdf.pdf?__blob=publicationFile&v=4 redirect;
rewrite ^/acw/?$ https://youtu.be/iJ2udTxn3SU?si=VolNcnQxOR1VXpuO permanent;
rewrite ^/assb/?$ https://www.youtube.com/watch?v=NMKZfJSjkbQ permanent;
rewrite ^/itu/?$ https://www.itu.int/en/ITU-R/terrestrial/fmd/Pages/call_sign_series.aspx permanent;
rewrite ^/bemfv/?$ https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Verbraucher/ElektromagnetischeFelder/Anzeige_Afu/Erlaeuterung_der_Bewertungsverfahren_nach_BEMFV.pdf?__blob=publicationFile&v=1 redirect;
rewrite ^/BImSchV/?$ https://www.gesetze-im-internet.de/bimschv_26/ permanent;
rewrite ^/so/?$ https://www.bundesnetzagentur.de/DE/Allgemeines/DieBundesnetzagentur/AufgabenStruktur/Standorte/start.html permanent;
rewrite ^/ov/?$ https://www.darc.de/home/#c153658 permanent;
rewrite ^/swl/?$ https://www.darc.de/funkbetrieb/kurzwellenhoerer-swl/ permanent;
rewrite ^/dld/?$ https://www.darc.de/der-club/referate/dx/diplome/dld-deutschland-diplom/ permanent;
rewrite ^/dld/?$ https://www.darc.de/geschaeftsstelle/qsl-buero/ permanent;
rewrite ^/df/?$ https://draussenfunker.de/ permanent;
rewrite ^/k01/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894027/Kochen permanent;
rewrite ^/k02/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894047/Fuchsjagd permanent;
rewrite ^/k03/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894050/Rei�~_nagel+Löten permanent;
rewrite ^/k04/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894055/Filmabend permanent;
#rewrite ^/k05/?$ # nicht vergeben
rewrite ^/k06/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894059/Technik+und+Natur permanent;
rewrite ^/k07/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894064/Schatzsuche permanent;
rewrite ^/k08/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894068/Astronomie permanent;
rewrite ^/k09/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894071/Experimentieren permanent;
rewrite ^/k10/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894074/Technikmuseum permanent;
rewrite ^/k11/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894077/Klasse+N+Kurs permanent;
rewrite ^/k12/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894085/Ausbildungsfunk permanent;
rewrite ^/t01/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894080/Escape+Room permanent;
rewrite ^/t02/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894089/Fieldday permanent;
rewrite ^/t03/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894092/HAMCAMP permanent;
rewrite ^/t04/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894097/3D+Druck permanent;
rewrite ^/t05/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894100/Klasse+E+Kurs permanent;
rewrite ^/t06/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894103/Programmieren permanent;
rewrite ^/t07/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894106/Contest permanent;
rewrite ^/t08/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894110/Planen permanent;
rewrite ^/t09/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894114/Elektronik+Projekt permanent;
rewrite ^/t10/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894117/Wandern permanent;
#rewrite ^/t11/?$ # nicht vergeben
rewrite ^/t12/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894120/Hackathon permanent;
rewrite ^/e01/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894125/Klasse+A+Kurs permanent;
#rewrite ^/e02/?$ # nicht vergeben
rewrite ^/e03/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894128/Vorträge permanent;
#rewrite ^/e04/?$ # nicht vergeben
#rewrite ^/e05/?$ # nicht vergeben
rewrite ^/e06/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894131/Raumfahrtprojekt permanent;
rewrite ^/e07/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894134/Wetterballon permanent;
rewrite ^/e08/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894137/App+Entwicklung permanent;
rewrite ^/e09/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894141/SDR+Projekt permanent;
rewrite ^/e10/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894145/DX-Pedition permanent;
rewrite ^/e11/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894148/Notfunk permanent;
rewrite ^/e12/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894151/Workshop permanent;
rewrite ^/e13/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894154/LORA permanent;
rewrite ^/aprs/?$ https://aprs.fi permanent;
rewrite ^/psk/?$ https://pskreporter.info/pskmap.html permanent;
rewrite ^/rbn/?$ https://www.reversebeacon.net permanent;
rewrite ^/wsprn/?$ https://www.wsprnet.org/drupal/wsprnet/map permanent;
rewrite ^/ebemfv/?$ https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Verbraucher/ElektromagnetischeFelder/Anzeige_Afu/Erlaeuterung_der_Bewertungsverfahren_nach_BEMFV.pdf?__blob=publicationFile&v=1 redirect;
rewrite ^/schwk/?$ https://de.wikipedia.org/wiki/Schwingkreis permanent;
rewrite ^/ant/?$ https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Amateurfunk/AntraegeFormulare/Formblatt_Zulassung_ab_24Juni2024.pdf?__blob=publicationFile&v=5 redirect;
rewrite ^/prf/?$ https://www.bundesnetzagentur.de/DE/Fachthemen/Telekommunikation/Frequenzen/SpezielleAnwendungen/Amateurfunk/start.html#FAQ648450 redirect;
rewrite ^/vfg29/?$ https://www.bundesnetzagentur.de/DE/Fachthemen/Telekommunikation/Frequenzen/SpezielleAnwendungen/Amateurfunk/DL_Vfg_AFu/Vfg29_2024.pdf?__blob=publicationFile&v=10 redirect;
rewrite ^/abemfv/?$ https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Verbraucher/ElektromagnetischeFelder/Anzeige_Afu/anleitung_anzeige20160616.pdf?__blob=publicationFile&v=1 redirect;
+4 -13
View File
@@ -6,9 +6,9 @@
group: "{{ fiftyohm_group }}"
mode: '0755'
- name: Checkout 50ohm source from https://github.com/DARC-e-V/50ohm to {{ destination_path }}/
- name: Checkout 50ohm source from {{ fiftyohm_repo }} to {{ destination_path }}/
ansible.builtin.git:
repo: https://github.com/DARC-e-V/50ohm.git
repo: "{{ fiftyohm_repo }}"
dest: "{{ destination_path }}/50ohm"
single_branch: true
version: "{{ fiftyohm_branch }}"
@@ -16,9 +16,9 @@
become: true
become_user: "{{ fiftyohm_user }}"
- name: Checkout 50ohm-contents-dl from https://github.com/DARC-e-V/50ohm-contents-dl to {{ destination_path }}
- name: Checkout 50ohm-contents-dl from {{ fiftyohm_contents_dl_repo }} to {{ destination_path }}
ansible.builtin.git:
repo: https://github.com/DARC-e-V/50ohm-contents-dl.git
repo: "{{ fiftyohm_contents_dl_repo }}"
dest: "{{ destination_path }}/50ohm-contents-dl"
single_branch: true
version: "{{ fiftyohm_contents_dl_branch }}"
@@ -36,12 +36,3 @@
owner: "{{ fiftyohm_user }}"
group: "{{ fiftyohm_group }}"
mode: '0444'
- name: Install url_shortener.conf in /srv/50ohm.de/url_shortener.conf
ansible.builtin.copy:
src: files/url_shortener.conf
dest: /srv/50ohm.de/url_shortener.conf
owner: "{{ fiftyohm_user }}"
group: "{{ fiftyohm_group }}"
mode: '0644'
notify: Reload nginx to apply new configuration
+1 -1
View File
@@ -1,5 +1,5 @@
[Unit]
Description=Refresh 50ohm.de with a timer
Description=Refresh {{ site_domain }} with a timer
[Service]
Type=oneshot
+1 -1
View File
@@ -1,5 +1,5 @@
[Unit]
Description=Timer for refreshing 50ohm.de
Description=Timer for refreshing {{ site_domain }}
[Timer]
OnBootSec=5min
+11 -2
View File
@@ -5,6 +5,15 @@
vars_files:
- vars.yml
- users.yml
pre_tasks:
- name: Kontrollera att platshållarvärden i vars.yml är utbytta
ansible.builtin.assert:
that:
- site_domain != "example.se"
- "'example.invalid' not in fiftyohm_repo"
- "'example.invalid' not in fiftyohm_contents_dl_repo"
- site_admin_email != "admin@example.se"
fail_msg: "Redigera vars.yml (site_domain, site_admin_email, fiftyohm_repo, fiftyohm_contents_dl_repo) och inventory.yml."
roles:
- base
- install-sources
@@ -13,8 +22,8 @@
- base
- build
# Obtain a TLS certificate for 50ohm.de using geerlingguy.certbot & configure nginx using geerlingguy.nginx
- name: Configure TLS for 50ohm.de
# Obtain a TLS certificate for {{ site_domain }} using geerlingguy.certbot & configure nginx using geerlingguy.nginx
- name: Configure TLS for {{ site_domain }}
hosts: webservers
become: true
vars_files:
+8 -11
View File
@@ -1,13 +1,10 @@
ex_users: []
users:
- {
name: "dc4lw",
sshkeys: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGJQ5A3Ea1vKUh63Gkv6CyK2pIHbEBe8ggs+kwHi3F3h",
state: "present",
}
- {
name: "dl9mj",
sshkeys: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9fle0ZeS+KOrC+sY+uUQhn+BObbUHbFyaMXvCotACTGt0IBxA8gDG0SSCU/TlW69B4SJA0vgVVVGmXlYpqBx4RbeaPzDn0Ui8AAR5msn+eYWmGREDyQam1ZhFAlKyfU3efwbv7Uu0VeWzamwmrdihhUnsw+kvokZOH5LZzA/if0Yw7SV/hkU/QeAahciYSVTzZLzCmJFK6kMwgR9Doix/gjm69s5lOGvXldfm2LcMdiXdBFdKxG//z1Xn+69fWUg2LLilsz/cy4sGinCxpt5UQs3/VpR/JQO8rGhTEJno5vcFRVnMSv1Cp2VMh+2UXCQKSRRjKfOpsHyz8boFrEjr",
state: "present",
}
# Administratörer som ska få SSH-nyckel och sudo på servern.
# Exempel:
# - {
# name: "anna",
# sshkeys: "ssh-ed25519 AAAA... anna@laptop",
# state: "present",
# }
users: []
+24 -29
View File
@@ -1,8 +1,16 @@
# ---- MÅSTE ändras innan första körning (site.yml avbryter annars) ----
site_domain: "50ohm.se"
site_admin_email: "admin@example.se" # används av Let's Encrypt
# Git-källor för den svenska versionen. Byt till dina egna repon/forkar.
fiftyohm_repo: "https://example.invalid/50ohm.git"
fiftyohm_contents_dl_repo: "https://example.invalid/50ohm-contents-dl.git"
# -----------------------------------------------------------------------
fiftyohm_user: fiftyohm
fiftyohm_group: fiftyohm
destination_path: /srv/50ohm.de
fiftyohm_branch: main
fiftyohm_contents_dl_branch: main
destination_path: "/srv/{{ site_domain }}"
fiftyohm_branch: sv
fiftyohm_contents_dl_branch: sv
certbot_install_method: package
certbot_auto_renew: true
@@ -11,11 +19,11 @@ certbot_auto_renew_hour: "5"
certbot_auto_renew_minute: "15"
certbot_create_if_missing: true
certbot_create_method: webroot
certbot_admin_email: 50ohm@darc.de
certbot_admin_email: "{{ site_admin_email }}"
certbot_certs:
- domains:
- 50ohm.de
- www.50ohm.de
- "{{ site_domain }}"
- "www.{{ site_domain }}"
webroot: "{{ destination_path }}/letsencrypt"
nginx_listen_ipv6: true
@@ -27,7 +35,7 @@ nginx_multi_accept: "off"
nginx_error_log: "/var/log/nginx/error.log warn"
nginx_accept_log: "/var/log/nginx/access.log main buffer=16k flush=2m"
nginx_vhosts:
- server_name: "50ohm.de"
- server_name: "{{ site_domain }}"
listen: "443 ssl http2"
filename: 50ohm-https.conf
root: "{{ destination_path }}/50ohm/build"
@@ -37,34 +45,21 @@ nginx_vhosts:
location "/" {
try_files $uri $uri/ =404;
}
# The old website from July 2025
location "/past" {
rewrite ^/past$ /past/ permanent;
alias /var/www/50ohm.de/;
try_files $uri $uri/ =404;
}
# Set to a different path for testing purposes
location "/future" {
rewrite ^/future$ /future/ permanent;
alias {{ destination_path }}/50ohm/build/;
try_files $uri $uri/ =404;
}
ssl_certificate /etc/letsencrypt/live/50ohm.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/50ohm.de/privkey.pem;
include /srv/50ohm.de/url_shortener.conf;
- server_name: "www.50ohm.de"
ssl_certificate /etc/letsencrypt/live/{{ site_domain }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ site_domain }}/privkey.pem;
- server_name: "www.{{ site_domain }}"
listen: "443 ssl http2"
filename: 50ohm-https-redirect.conf
state: "present"
extra_parameters: |
ssl_certificate /etc/letsencrypt/live/50ohm.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/50ohm.de/privkey.pem;
return 301 https://50ohm.de$request_uri;
- server_name: "50ohm.de"
ssl_certificate /etc/letsencrypt/live/{{ site_domain }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ site_domain }}/privkey.pem;
return 301 https://{{ site_domain }}$request_uri;
- server_name: "{{ site_domain }}"
listen: "80"
filename: 50ohm-http.conf
server_name_redirect: "www.50ohm.de"
server_name_redirect: "www.{{ site_domain }}"
root: "{{ destination_path }}/50ohm/build"
state: "present"
extra_parameters: |
@@ -73,5 +68,5 @@ nginx_vhosts:
root {{ destination_path }}/letsencrypt;
}
location "/" {
return 301 https://50ohm.de$request_uri;
return 301 https://{{ site_domain }}$request_uri;
}