This shows you the differences between two versions of the page.
sde:teme:tema_ro_5_python [2020/05/05 18:30] ioana_maria.culic [Trimiterea temei] |
— (current) | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Tema 5 - Server web ====== | ||
- | |||
- | Scopul acestei teme este realizarea unui server web care trebuie să servească fițiere și să execute scripturi. | ||
- | <note info> | ||
- | Această temă va fi rezolvată în mediul de programare Node.js, folosind JavaScript ca limbaj de programare. | ||
- | </note> | ||
- | |||
- | ===== Informații generale ===== | ||
- | |||
- | <note important> | ||
- | Deadline: **22 Mai, 23:55**\\ | ||
- | Punctaj: **2 puncte** din nota\\ | ||
- | Incarcarea temei: [[https://vmchecker.cs.pub.ro|vmchecker.cs.pub.ro]]\\ | ||
- | Incarcarea cu intarziere: **0.1 punct / zi** (maxim 4 zile)\\ | ||
- | </note> | ||
- | |||
- | ===== Cunoștințe evaluate ===== | ||
- | |||
- | * Folosirea operațiilor asincrone | ||
- | * Înțelegerea paradigmei client-server; | ||
- | * Ințelegerea protocolului HTTP. | ||
- | |||
- | ===== Reguli ===== | ||
- | |||
- | - Tema trebuie sa contina un fisier Readme in care sa explicati cum ati facut tema (-0.1p). | ||
- | - Aveti voie sa folositi doar limbajul JavaScript (Node.js). | ||
- | - O temă care trece toate testele automate va obține 10 puncte din 10 (daca nu trișează folosind API interzis, caz în care nu va fi punctată). | ||
- | - O tema care este implementata doar pentru a trece testele, va fi depunctată pentru acele teste. | ||
- | |||
- | ===== Copierea ===== | ||
- | |||
- | Tema se rezolva individual. Orice tentativă de copiere va rezulta în **0p** pentru tema respectiva. Vom utiliza și sisteme automate de detectare a copierii. Dacă avem dubii, vă vom adresa întrebări suplimentare legate de temă. | ||
- | |||
- | ===== Întrebări ===== | ||
- | |||
- | Daca aveți întrebări legate de temă, vă rugăm să scrieți un issue pe repository-ul de github [[https://github.com/upb-fils/sde.git|repository]] cu titlul de forma //[server] <titlul intrebarii voastre>//. Aveți nevoie de un cont de github pentru | ||
- | a scrie întrebări. | ||
- | |||
- | <note warning> | ||
- | **NU PUBLICAȚI COD SURSĂ**. Acesta va fi considerată copiere și se va penaliza cu 0p pe temă pentru voi. | ||
- | </note> | ||
- | |||
- | Daca doriti sa primiti un email cand se pun intrebari noi sau cand apar raspunsuri, accesati github [[https://github.com/upb-fils/sde|repository]] si faceti click pe //Watch//. | ||
- | |||
- | ===== Server ===== | ||
- | Serverul va fi implementat în fișierul ''index.js'' și va fi rulat astfel: | ||
- | |||
- | <code bash> | ||
- | node index.js | ||
- | </code> | ||
- | |||
- | În rezolvarea temei veți implementa un server HTTP, care poate procesa cereri prin operații asincrone. Serverul va primi pachete HTTP de la clienți, executa diferite operații și va răspunde cu pachete HTTP (un format simplificat al acestora). | ||
- | |||
- | ====Configurarea serverului==== | ||
- | La pornire, serverul va citi un fișier de configurare, aflat în același director cu ''index.js''. Numele fișierului este ''config.json'' și va conține următoarea structură de tip JSON: | ||
- | <code javascript> | ||
- | { | ||
- | "scripts" : "scripts_path", | ||
- | "www" : "root_path" | ||
- | } | ||
- | </code> | ||
- | |||
- | ''scripts_path'' este o cale abolută către un director în care se găsesc scripturile ce vor fi rulate de server. | ||
- | |||
- | ''root_path'' este o cale absolută către directorul rădăcină, relativ la care se vor face toate cererile. De exemplu, dacă o cerere are calea ''/images/sunny.png'' și ''root_path'' are valoarea ''/home/server/root'', se va returna fișierul având calea absolută ''/home/server/root/images/sunny.png''. | ||
- | |||
- | |||
- | ====Mesajele HTTP==== | ||
- | Mesajele HTTP primite de server vor avea următorul format generic: | ||
- | |||
- | <code bash> | ||
- | <request_type> <path> HTTP/1.1 | ||
- | <header_key>:<header_value> | ||
- | ... | ||
- | <header_key>:<header_value> | ||
- | |||
- | <message - optional> | ||
- | </code> | ||
- | |||
- | Mesajele HTTP trimise de server vor avea următorul format generic: | ||
- | |||
- | <code bash> | ||
- | HTTP/1.0 <status_code status> | ||
- | <header_key>:<header_value> | ||
- | ... | ||
- | Connection: close | ||
- | |||
- | <message> | ||
- | </code> | ||
- | |||
- | Următoarele variabile vor fi înlocuite astfel: | ||
- | * request_type - tipul cererii (GET sau POST); | ||
- | * path - calea către fișierul cerut (ex: /scripts/update); | ||
- | * header_key:header_value - perechi cheie valoare care fac parte din antet (ex: content-type:application/json); | ||
- | * message - corpul mesajului (pentru cerere, corpul mesajului există doar dacă cererea este de tip POST); | ||
- | * status_code status - codul de stare urmat de descrierea stării; vom defini mai jos valorile posibile (ex. 404 Not found). | ||
- | |||
- | ====Returnarea fișierelor cerute==== | ||
- | Prima funcționalitate a serverului este de a returna fișierele cerute de clienți. În acest caz, serverul va primi o cerere de tip GET către un fișier și va răspunde cu conținutul fișierului. | ||
- | |||
- | <note info> | ||
- | Serverul va întoarce doar fișiere care se găsesc în ''root_path''. | ||
- | </note> | ||
- | |||
- | ===Cererea HTTP=== | ||
- | |||
- | În acest caz, cererea primită de server va fi de forma: | ||
- | <code bash> | ||
- | GET <file_path_relative_to_root> HTTP/1.1 | ||
- | Host: localhost:8000 | ||
- | <other header lines> | ||
- | </code> | ||
- | |||
- | Prima linie din cerere specifică calea către fișierul cerut. Antetul poate conține și alte linii, pe lângă cele specificate mai sus. | ||
- | |||
- | ===Răspunsul HTTP=== | ||
- | Pentru a răspunde cererilor pentru fișiere, serverul va returna un mesaj de forma: | ||
- | <code bash> | ||
- | HTTP/1.1 <status_code status> | ||
- | Content-type: <file_type> | ||
- | Connection: close | ||
- | |||
- | <file_contents> | ||
- | </code> | ||
- | |||
- | În funcție de cererea primită și starea fișierului cerut, starea răspunsului poate fi: | ||
- | * 200 OK - fișierul a fost returnat; | ||
- | * 403 Forbidden - serverul nu are permisiunea de a citi fișierul; | ||
- | * 404 Not Found - fișierul nu există. | ||
- | |||
- | A treia linie din cerere specifică tipul de fișier returnat. În funcție de tipul fișierului,''file_type'' poate avea următoarele valori: | ||
- | * text/plain; charset=utf-8 - pentru fișiere text (extensia .txt); | ||
- | * text/html; charset=utf-8 - pentru fișiere html; | ||
- | * image/jpeg - pentru fișiere JPEG; | ||
- | * image/png - pentru fișiere PNG; | ||
- | * application/zip - pentru arhive ZIP. | ||
- | * application/octet-stream - pentru fisiere cu alte extensii sau fara extensie | ||
- | |||
- | ====Execuția unui script==== | ||
- | Unele din mesajele primite de la clienți vor cere rularea unor scripturi. Acest tip de cereri se identifică prin calea fișierului, în acest caz calea fiind un fișier din directorul ''scripts_path''. | ||
- | |||
- | În directorul ''scripts_path'' pot exista orice fel de fișiere executabile. Oricare din acele fișiere va fi rulat cu comanda ''./script_name''. După rulare, serverul va răspunde cu rezultatul execuției. | ||
- | |||
- | ===Cererea HTTP=== | ||
- | |||
- | În acest caz, cererea primită de server va fi de forma: | ||
- | <code bash> | ||
- | <request_type> <file_path_relative_to_root> HTTP/1.1 | ||
- | Host: localhost:8000 | ||
- | <other header lines> | ||
- | |||
- | <message - optional> | ||
- | </code> | ||
- | |||
- | În acest caz, cererile (''request_type'') pot să fie de două feluri: ''GET'' și ''POST''. | ||
- | |||
- | Pentru aceste cereri, liniile din header, exceptând primele două, sunt pasate ca variabile de mediu pentru fișierul care va fi executat. | ||
- | |||
- | Dacă cererea este de tip POST, va exista și un corp al mesajului. Acesta este pasat ca input pentru scriptul care va fi executat. | ||
- | |||
- | ===Răspunsul HTTP=== | ||
- | În acest caz, serverul va returna un mesaj de forma: | ||
- | <code bash> | ||
- | HTTP/1.1 <status_code status> | ||
- | Connection: close | ||
- | <other_headers> | ||
- | |||
- | <file_contents> | ||
- | </code> | ||
- | |||
- | Unele executabile vor returna corpul mesajului împreună cu antetul, în timp ce altele vor returna doar corpul mesajului. Dacă executabilul returnează și antetul, acesta va conține toate informațiile necesare, exceptând primele două linii din mesaj. Dacă executabilul nu returnează niciun antet, pe lângă primele două linii, serverul va genera și antetul ''Content-type: application/octet-stream''. | ||
- | |||
- | <note info> | ||
- | Antetul returnat de un executabil poate fi identificat ca prima succesiune de linii până la apariția unei linii goale. | ||
- | </note> | ||
- | |||
- | Statusul din răspuns va avea una din următoarele valori: | ||
- | * 200 OK - procesarea a fost efectuată cu succes, iar rezultatul se găsește în corpul mesajului; | ||
- | * 403 Forbidden - serverul nu are permisiunea de a citi sau executa fișierul; | ||
- | * 404 Not Found - executabilul cerut nu există; | ||
- | * 500 Internal Server Error - executabilul cerut nu a fost rulat cu succes; în acest caz, în corpul mesajului se va adăuga textul din stderr. | ||
- | |||
- | <note info> | ||
- | Serverul trebuie să se asigure că nu se pot executa fișiere aflate în alt director decât cel menționat în fișierul de configurare. | ||
- | </note> | ||
- | |||
- | ====Operații asincrone==== | ||
- | Tema va fi implementată în mediul de programare [[https://nodejs.org/en/|Node.js]] și veți folsi funcții asincrone pentru a procesa cererile primite de la clienți. | ||
- | |||
- | În rezolvarea temei este admisă doar folosirea de biblioteci native Node.js și se recomandă folosirea următoarelor module: | ||
- | * [[https://nodejs.org/api/net.html|net]] pentru acceptarea de conexiuni și primirea/trimiterea de mesaje HTTP; | ||
- | * [[https://nodejs.org/api/child_process.html|child_process]] pentru lansarea de procese copil. | ||
- | |||
- | <note warning> | ||
- | Pentru comunicarea pe rețea este admisă doar folosirea modulului ''net''. | ||
- | </note> | ||
- | <note warning> | ||
- | În implementarea temei puteți folosi doar biblioteci native Node.js și doar funcții asincrone. | ||
- | </note> | ||
- | |||
- | ===== Testarea temei ===== | ||
- | ===== Trimiterea temei ===== | ||
- | Tema se va incarca pe [[https://vmchecker.cs.pub.ro|vmchecker]]. Logati-va pe site cu utilizatorul de pe moodle, selectati cursul //Systemes d'Explotation (FILS)// si incarcati [[#arhiva-temei|arhiva temei]]. | ||
- | |||
- | ==== Readme ==== | ||
- | Fisierul readme are urmatorul format: | ||
- | |||
- | <code> | ||
- | Numele vostru intreg | ||
- | Grupa | ||
- | |||
- | Descrierea rezolvarii temei, de ce ati ales anumite solutii, etc. | ||
- | </code> | ||
- | |||
- | |||
- | ==== Arhiva temei ==== | ||
- | Pentru a incarca tema, urmariti pasii: | ||
- | |||
- | - Creati o arhiva zip (nu rar, ace, 7zip sau alt format) care sa contina: | ||
- | * toate fisierele JavaScript (*.js) | ||
- | * fisierul Readme | ||
- | - logati-va pe [[https://vmchecker.cs.pub.ro|vmchecker]] | ||
- | - selectati cursul //Systemes d'Explotation(FILS)// | ||
- | - selectati //5. Server// | ||
- | - incarcati arhiva | ||
- | |||
- | <note> | ||
- | Arhiva trebuie sa contina toate fisierele (principale) in radacina, nu in subdirectoare. NU arhivati directorul temei, arhivati DIRECT fisierele. | ||
- | </note> | ||
- | |||
- | Dupa ce incarcati arhiva, vmchecker va rula: | ||
- | |||
- | <code bash> | ||
- | unzip archive.zip homework | ||
- | cd homework | ||
- | make -f Makefile.check | ||
- | </code> | ||