WWW, HTTP servery

Dušan Baran, xbaran2@fi.muni.cz

Obsah

Úvod: Čo je HTTP a na čo je?

Z čoho sa skladá HTTP request?

Ako vyzerá?

GET / HTTP/1.1
Host: dudo.cool
User-Agent: curl/7.66.0
Accept: */*

Z čoho sa skladá HTTP response?

Ako vyzerá?

HTTP/1.1 301 Moved Permanently
Server: nginx/1.14.0 (Ubuntu)
Date: Mon, 14 Oct 2019 15:16:19 GMT
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
Location: https://dudo.cool/

{{BODY}}

Príklad hlavičiek

Príklad užitočných hlavičiek:

Hlavičky sa dajú zapisovať aj do HTML súboru do časti <head> ako meta tag http-equiv. Mal by tento súbor prečítať server a tieto hlavičky pridať do odpovede, ale málo implementácií http serverov to robí, a teda ostáva na klientovi aby ich prečítal. Príklad:

    HTML 4.01: <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    HTML5: <meta charset="UTF-8">

Zaujímavá hlavička je aj Accept-Ranges. Ak server podporuje range requesty tak sa dá vypítať iba časť dát. V prípade binárneho obsahu sa dá requestnúť časť dát pomocou hlavičky Range: bytes=0-1023.
Detailné info

HTTP servery

Najznámejšie sú asi HTTP servery Apache HTTP server a Nginx

Apache HTTP server je starší, vyšiel v roku 1995

Apache HTTP serveru je označovaný ako aplikačný server

Nginx

Novší ako Apache HTTP server, vyšiel v roku 2002

Má byť oproti Apache HTTP serveru rýchlejši

Nginx je označovaný ako web server

Inštalácia na Archlinuxe pacman -S nginx
Inštalácia na Ubuntu 18.04.2 apt install nginx

Konfigurácia

Konfiguračný súbor sa nachádza v /etc/nginx/nginx.conf

Zjednodušene vyzerá približne takto:

events { 
  worker_connections 1024; 
} 

http { 
  sendfile on; # Bude sa používať linuxovy sendfile call 
  
  server { 
    ... 
  } 
}

Poznámka:

Nginx master process beží pod uživateľom root a worker process pod uživateľom http. Worker proccess uživateľ sa dá zmeniť v konfiguračnom súbore pridaním user user [group];.

Server block

Je porovnatelné s Apache VirtualHost

Príklad server bloku ktorý servuje statický súbor:

server {
  listen 80;
  listen [::]:80;
  server_name proto01.pv090.fi.muni.cz;
  root /usr/share/nginx/proto01.pv090.fi.muni.cz/html;
  location / {
    index index.html;
  }
}

Config prevzatý a následne modifikovaný z: Archwiki

Poznámka:

Location blok môže byť zapísaný aj vo `wildcard` formáte, teda napríklad ~ \.php$ alebo ~ \.(jpg|png|gif)$.

Používanie hlavičiek

V niektorých prípadoch príde užitočné použiť hlavičky pri rozhodovaní čo s requestom. Napríklad ak by sme chceli vrátit iný súbor na základe Accept-Language headeru. V tomto prípade je jedno z riešení použiť funkciu map.

http {
  map $http_accept_language $lang {
    default en;
    ~*^cz cz;
    ~*^en en;
  }

  server {
    ...

    location = /jazyk.html {
      try_files /jazyk.$lang.html =404;
    }
  }
}

Hlavičky sa dajú pridávať napríklad pomocou add_header.

Basic Auth

Nginx podporuje aj basic auth. Na jeho spojazdnenie je potrebný súbor s uživateľským info vo formáte, kde heslo je hash:

name1:password1
name2:password2:comment
name3:password3

Tento súbor sa dá vygenerovať pomocou:
htpasswd -c location user
Alebo len zahashovať heslo:
openssl passwd password

Následne sa dá zapnúť `Basic Auth` pre server alebo location, napríklad:

...
server {
  ...
  location = /super_private {
    auth_basic "My safe space";
    auth_basic_user_file path_to_user_file;

    try_files playlist.html =404;
  }
}
...

Nginx a CGI skripty alebo dynamický obsah

Nginx nevie interpretovať nič. Čiže ani spúštať skripty. Vie ale komunikovať s inými procesmi pomocou napríklad http, fastCGI alebo uWSGI. Všeobecne je veľa spôsobov ako v Nginxe spúštať CGI skripty. Príklad použitia fastCGI:

Pre jednoduché spúštanie skriptov je potrebné stiahnuť a aj spustiť fcgiwrap. Spustiť treba fcgiwrap.service ale aj fcgiwrap.socket. Na Archlinuxe počúva na unix sockete /run/fcgiwrap.sock. Príklad Nginx server blocku pre CGI location:

server {
  ...
  location = /logged.cgi {
    include fastcgi_params;
    fastcgi_params SCRIPT_FILENAME /usr/share/nginx/logged.cgi;
    # fastcgi_params DOCUMENT_ROOT /usr/share/nginx/;
    # fastcgi_params SCRIPT_NAME logged.cgi;
    fastcgi_pass unix:/run/fcgiwrap.sock;
  }
}

Pozor! Výstup zo skriptov musí špecifikovať formát obsahu (Content-Type)

#Súbor logged.cgi
#!/bin/bash
echo "Content-Type: text/html"
echo ""

who

Konfigurácia bola inšpirovaná z Archwiki

Pozor! Súbor musí byť spustiteľný

SSL/TLS

SSL/TLS sa zapína na Nginxe tiež jednoducho. Ak už máme certifikát s kľúčom stači nám pridať pár riadkov.
Pre nastavenie šifier a verzií ssl_ciphers, ssl_protocols. A potom pre server blok špecifikovať cestu k certifikátu a kľúču: ssl_certificate, ssl_certificate_key.
V následujúcom príklade sa nachádza navyše presmerovanie HTTP endpointu na HTTPS endpoint.

http {
  ...
  ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ...

  server {
      listen 80;
      server_name localhost;
      return 301 https://$host$request_uri;
  }

  server {
      listen 443 ssl http2;
      server_name localhost;

      ssl_certificate ssl/server.crt;
      ssl_certificate_key ssl/server.key;

      root /usr/share/nginx/html;
      location / {
          index index.html index.htm;
      }
  }
}

Konfigurácia bola inšpirovaná z Archwiki

Literatura