Systemprogrammering i C++
URL-statistikserver
Teksten er skrevet med proportional skrift i skriftfamilien Garamond med en skriftstørrelse på 11 punkter.
Overskrifter står med sans-serif skriftfamilien Arial og kode står med den nonproportionale serif skriftfamilien Courier New i en skriftstørrelse på 8 punkter.
Alle skriftfamilier er anvendt i en TrueType® implementering.
Indhold
Vi skal lave URL-statistikserver der både skal kunne lave statistik for besøgte URL’er og cache de mest anvendte HTML-dokumenter.
Systemet skal kunne servicere flere forbindelser samt internt arbejde parallelt.
Vi har valgt at koncentrerer os om rene HTML-dokumenter – vi forudsætter korrekt HTML.
Med hensyn til håndtering af HTTP henviser vi til foranalysen.
Vi anvender den objektorienteret metode vi har lært tidligere i uddannelsen. Det vil sige blandt andet sige at vi arbejder med UML.
Vi er en stor gruppe, så der arbejdes oftest individuelt med delopgaver ud fra aftalte rammer.
Det fælles ansvar for projektet støttes løbende af rapporten og indgåede aftaler for delopgaver:
- Lexer/parser
- Databaser
- Internetforbindelse (socket)
- Statistik- og cachestyring
- dokumentation
Vi har specielt set på caching af HTTP, og mener i den sammenhæng at disse felter i headeren er interessante:
-
Expires. Det anbefales [RFC2068] at tiden på servere vedligeholdes automatisk, for eksempel ved hjælp af NTP.
Tidspunkter kan angives i de tre forskellige formater rfc1123, rfc850 eller asctime [RFC2068],
men skal under alle omstændigheder være GMT. Hvis det aktuelle tidspunkt er nyere end den HTTP-dato
der er angivet i feltet skal det cachede dokument anses for at være ugyldigt (og slettes).
-
Cache-Control. Der må ikke caches hvis værdien er "max-age=0", "no-store" eller "no-cache".
Hvis værdien er "private" er det mest korrekte ikke at cache i vores system, da det er en delt cache.
- Pragma. Hvis værdien er "no-cache" skal der handles som ved "Cache-Control:no-cache".
Med hensyn til forskellene på HTTP/1.0 og HTTP/1.1 kan oplysningen om version findes i feltet HTTP-Version,
hvor vi helst ser at værdien er "HTTP/1.1". Hvis ikke den fremmed server er HTTP/1.1
og ikke kan håndtere en Host request-header og absolutte URI’er, skal enten den fremmede server eller USS-systemet
svare med fejl 400 (Bad Request).
Det som er interessant, er links i HTML-dokumenter. Vi har kigget HTML igennem, og mener at i et rent HTML-dokument
er der kun links ved "HREF="-tags, så det er det som vores HTML-parser behandler.
Ved at parse på "HREF=" dækker vi egentlig to muligheder for links:
- location.(punktum)href=" "...
- <a href=" "...
Figur 1. Skitse af dataflow.
Vores URL-statistik-server (USS) ligger som en gateway mellem ISP’ens browserklienter og web-servere på internettet.
Figur 2. Internt og eksternt dataflow.
En browser sender en forespørgsel (request) om en URL. URL’en starter med IP-adresse og portnummer for USS-systemet.
Forespørgslen modtages af USS-systemet, hvor web-komponenten tager IP-adresse og portnummer for USS-systemet ud af URL’en
og sender en forespørgsel på URL’en til Statistik-komponenten.
Hvis Statistik-komponenten kan finde URL’en i URL-databasekomponenten, og URL’en er på top-n,
vil en forespørgsel på URL’en blive sendt til Cache-komponenten. Hvis ikke URL’en findes i URL-databasekomponenten,
vil svaret (response) til web-komponenten være negativt.
Cache-komponenten tjekker om URL’en er cachet og om de cachet data er valide ud fra HTTP-headeren.
Hvis data er valide vil data blive sendt til Web-komponenten, som så vil sende svar (response) til Statistik-komponenten,
der opdaterer tælleren og sender svaret videre til Web-komponenten. Hvis data ikke er valide,
vil Cache-komponenten bede Web-komponenten om at gå på internettet og finde friske data.
Web-komponenten vil kun sende en forespørgsel ud på internettet, hvis Statistik-komponenten svarer negativt
på en forespørgsel eller Cache-komponenten vil have friske data. Web-komponenten sender så en forespørgsel ud
og hvis svaret er negativt sendes det negative svar videre til browseren – det vil sige der bliver ikke oprettet et nyt element
eller redigeret i eksisterende elementer i nogle databasekomponenter.
Hvis Web-komponenten modtager et positivt svar vil det blive sendt videre til Oversætter-komponenten,
hvor protokol (HTTP) – eventuelt URL - IP-adresse og portnummer vil blive sat ind i alle links i HTML-dokumentet.
Oversætter-komponenten sender det parsede svar videre til Statistik-komponenten, der enten opretter et nyt element
i URL-databasekomponenten hvis det er en ny URL, eller opdaterer tælleren.
Hvis URL’en er eller kommer på top-n, vil svaret blive sendt både til Cache-komponenten og til Web-komponenten.
Cache-komponenten opdaterer HTML- og HTTP-databasekomponenterne og Web-komponenten sender svaret videre til browseren.
Systemet lave statistik over URL-anvendelsen og cacher de mest anvendte HTML-dokumenter.
Flere samtidige forbindelser til browsere og web-servere skal kunne håndteres parallelt.
Samtidig skal systemets komponenter kunne arbejde parallelt med hinanden og resten af systemet.
3.1.2 Systemdefinition
Vi arbejder hen mod et system hvor der gælder:
Betingelser |
Systemet skal fungere uden anden brugeraktivitet end at sørge for korrekt gateway med IP-adresse og portnummer.
Brugerne kan have ingen eller ringe erfaring med EDB.
|
Anvendelsesområde |
Brugere der har vores kunde som ISP og som vil benytte webdelen af internettet. |
Teknologi |
Standardkomponenter; pc-hardware, Linux og C++. |
Objektsystem |
URLer som brugerne vil anvende. |
Funktionalitet |
Kunden kan udskrive en statistik over URL’er og deres anvendelse og brugernes mest anvendte HTML-dokumenter caches.
|
Filosofi |
Primært et statistikværktøj for kunden, sekundært en HTML-cache for brugerne.
|
3.1.3 Omgivelser
Figur 3. Rigt billede af systemets omgivelser.
Systemet er gateway for web-brugeres adgang til internettet, samtidig med at det opsamler og præsenterer statistik
om brugernes anvendelser af URLer. Cachefunktionaliteten er ikke illustreret – den vil egentlig ikke ændre tegningen,
kun bør brugerne opleve en meget kort svartid på de generelt mest anvendte URL’er.
3.1.3.1 Problemområde
Anvendte URL’er registreres og indholdet sendes til brugeren. De mest anvendte HTML-dokumenter caches.
3.1.3.2 Anvendelsesområde
Statistik for anvendte URL’er, og cache af HTML-dokumenter. Generelt en cachende gateway for brugerne.
3.2.1 Klynger
Vi har fundet frem til disse kandidater til overordnede strukturer:
- Oversætter (HTML)
- Statistik (URL)
- Cache (HTML)
3.2.2 Struktur
Vi har i diskussionerne taget udgangspunkt i disse kandidater til klasser:
- URL
- HTML-dokument
- HTML-kommandoer, specielt "HREF="
- Andre kommandoer fra for eksempel VBS eller JavaScript.
- HTTP-header
- Felter og feltværdier til cachekontrol.
3.2.3 Klasser
Den endelige definition af klasserne og deres adfærdsmønstre findes i designdokumentet.
Figur 4. Illustration af vejene gennem systemen for en bruger forespørgsel
Vi går ud fra at hver pil i Figur 4 er en hændelse. Vi har på dette tidspunkt ikke navngivet hændelserne,
men lader det være op til situationen når vi arbejder mere detaljeret senere.
Beskrivelsen af hændelserne svarer til beskrivelsen af dataflowet i Figur 2.
3.3.1 Brug
3.3.1.1 Oversigt
|
Operatør |
Bruger |
www-server (?) |
URL-statitik |
X |
|
|
Web-browsing |
|
X |
X |
Drift |
X |
|
|
Figur 5. Aktørtabel. Egentlig regner vi med at www-servere er en autonom aktør i forhold til systemet, men leverer alligevel data hertil.
3.3.1.2 Aktører
|
Operatør |
Bruger |
Formål |
En person der udfører administrativt arbejde på og af systemet. |
En person der benytter vores kunde som ISP og dermed USS-systemet som web-gateway. |
Karakteristik |
Egentlig behøver personen ikke den store tekniske for at kunne udføre almindelige opgaver,
men hvis for eksempel system skal opgraderes eller flyttes (driftopgaver) er en vis faglig ballast nødvendig.
|
Personen behøver ikke have specielle EDB-færdigheder eller –kundskaber.
På den anden side kan de være til stede i overordentlig høj grad...
|
Eksempel |
En ufaglært medarbejder med den nødvendige oplæring i USS-systemet.
Det kan også være en rutineret medarbejder der ud fra en skrevet vejledning nemt kan gennemfører
systemspecifikke operationer
|
En hr./fru Hvem-som-helst med vidt forskellige motivationer og anvendelsesmønstre.
|
Figur 6. Definition af aktører.
3.3.1.3 Brugsmønstre
3.3.1.3.1 URL-statistik
En operatør udtager med regelmæssige mellemrum en statistik over anvendte URL’er fra USS-systemet ved at vælge et menupunkt.
3.3.1.3.2 Web-browsing
Brugeren indtaster en URL og enten angiver brugeren selv IP-adresse og portnummer på USS-systemet som gateway eller også
er disse værdier på et tidligere tidspunkt og eventuelt af en anden person indtastet i brugerens system.
3.3.1.3.3 Drift
En operatør ser til at systemet er kørende og at der ikke er væsentlige eller tendentiøse forringelser i systemet.
Her tænkes for eksempel på øgede svartider eller hukommelsesforbrug. Eventuelle rettelser eller opgraderinger af systemet,
operativsystemet eller selve USS-systemet, udføres efter gældende interne regler.
3.3.2 Funktioner
3.3.2.1 Funktionsliste
Funktion |
Kompleksitet |
Type |
1 |
middel |
aflæsning |
2 |
simpel |
aflæsning |
3 |
simpel |
aflæsning |
4 |
simpel |
aflæsning |
5 |
middel |
opdatering |
6 |
kompleks |
opdatering |
7 |
simpel |
aflæsning |
8 |
simpel |
signalering |
9 |
simpel |
signalering |
10 |
kompleks |
opdatering |
11 |
simpel |
signalering |
12 |
simpel |
signalering |
Figur 7. Funktionsliste i oversigtform for USS-systemet.
Funktionslisten er lavet ud fra hændelserne, og vi har endnu ikke givet funktionerne navne.
Listen er en oversigt, så en del af funktionerne vil blive implementeret som flere metoder eller frie funktioner.
3.3.2.2 Specifikation af funktioner
Som det er kutyme vil vi kun specificere de komplekse funktioner.
3.3.2.2.1 Funktion 6
Hvis den URL brugeren søger findes i cachen giver cachen et svar tilbage i form af HTTP-header og HTML-dokument.
Undervejs opdateres tælleren for antal anvendelser af URL’en.
3.3.2.2.2 Funktion 10
Når den modtagne URL med data er oversat, opdateres URL-statistikken med URL og antal anvendelser.
Cachen undersøger også lige om antallet af anvendelser berettiger en optagelse i cachen.
Endelige sendes HTTP-header og HTML-dokument til web-"serveren".
3.3.3 Brugergrænseflade
3.3.3.1 Dialogform
Enkle menuvalg i tekstbaseret menusystem.
3.3.3.2 Eksempler
Hovedmenu
1) Vis statistik
2) Afslut hovedmenu
9) Luk system
Indtast menuvalg: _
|
Figur 8. Skitse til brugegrænsefladens menusystem.
3.3.4 Den tekniske platform
Systemet udvikles på pc-platformen til Linux operativsystemet med C++.
Til håndtering af persistente objekter anvendes et almindeligt databasesystem.
3.4.1 Edb-systemets nytte og realisérbarhed
Dette er et undervisningsprojekt… Alligevel mener vi at kunne lave et anvendeligt system der vil kunne tilfredsstille en kunde
som den beskrevet i opgaven.
3.4.2 Strategi
Projektgruppen er internt enig om opgavens art i kraft af arbejdet med analysedokumentet. Vi tilstræber at anvende
lettilgængelige og almindeligt kendte værktøjer så en eventuel udvidelse eller tilretning
af systemet kan ske nemmest muligt.
3.4.3 Udviklingsøkonomi
Systemet skal jo være færdigt 22. maj, så de nødvendige aftner og weekender vil blive anvendt.
Det vil sige der sikkert skal bruges omkring fire personmåneder – cirka.
4.1.1 Formål
Formålet med systemet er uændret i forhold til analysedokumentet.
4.1.2 Rettelser til analysen
Det endeligt objektsystem er opbygget i en komponentarkitektur.
Kriterium |
Meget vigtigt |
Vigtigt |
Mindre vigtigt |
Irrelevant |
Trivielt opfyldt |
Brugbart |
X |
|
|
|
|
Sikkert |
|
|
X |
|
|
Effektivt |
|
X |
|
|
|
Korrekt |
X |
|
|
|
|
Pålideligt |
X |
|
|
|
|
Vedligeholdbart |
|
|
X |
|
|
Testbart |
|
|
|
|
X |
Fleksibelt |
|
|
X |
|
|
Forståeligt |
|
|
X |
|
|
Genbrugbart |
|
|
|
X |
|
Flytbart |
|
|
|
X |
|
Integrerbart |
|
|
X |
|
|
Figur 9. Prioritering af designkriterier
4.2.1 Udstyr
PC-platformen; stationære og bærbare arbejdsstationer og printere samt kopimaskiner.
4.2.2 Basisprogrammel
Systemet er skrevet i C++ på forskellige Linux-installationer; Red Hat, SuSE eller Mandrake.
Generelt har vi oversat C++-koden med g++-oversætteren. Vi har undervejs bruge et rigt udbud af
(læs forhåndenværende) editorer og udviklingsmiljøer på forskellige platforme til at generere koden.
Rapporten er primært skrevet i Microsoft Word med illustrationer lavet i Visio på forskellige Windows-installationer.
Undervejs har vi kommunikeret med hinanden og underviserne ved hjælp af almindelige mail- eller groupwareprogrammer.
4.2.3 Systemer og apparater
Vi kommunikerer med klienter (web-browser) og webservere ved hjælp at TCP/IP v4.
Forbindelserne (fysiske og logiske) er ifølge gældende standarder og mest udbredte praksis.
4.2.4 Designsprog
Systemet er designet i UML.
Figur 10. Generelt diagram for systemets lagdelte komponent arkitektur.
4.3.1 Komponentarkitektur
4.3.1.1 Grænseflade
4.3.1.1.1 Statistik, brugergrænseflade
Meget simpel skærmudskrift af data. Forbedring mulig...
4.3.1.1.2 Web, systemgrænseflade
Styring af socket-forbindelser og HTTP kommunikation. Både til systemets server- og klientrolle.
4.3.1.2 Funktionnalitet
4.3.1.2.1 Statistik, styring
Holder styr på antallet af anvendelser samt top-x. Nye URL’er tilføjes databasen.
4.3.1.2.2 Cache, styring
Ud fra top-n caches – hvis HTTP-headeren tillader det. Når et cachet HTML-dokument ønskes tjekker
cachestyringen om dokumentet stadig er gyldigt ud fra HTTP-headerens oplysninger om levetid.
4.3.1.2.3 Parser
Syntaksanalyse af HTML.
4.3.1.3 Lexer
Lexikalsk analyse af HTML.
4.3.1.4 Data
Database bygget op med og styret af miniSQL. Data leveres til resten af systemet af fri funktioner.
4.3.1.4.1 URL
Anvendte URL’er og antallet af anvendelser af dem.
4.3.1.4.2 HTTP
HTTP-headeren for alle anvendte URL’er.
4.3.1.4.3 HTML
HTML-dokumenter der skal caches.
4.3.1.5 Symboltabel
Symboltabel knyttet til oversætteren (lexeren).
4.3.2 Procesarkitektur
Vores system skal kunne håndterer flere brugere, hvilket primært sker i web-komponenten.
Komponenten kloner sig selv i en ny proces ved hver ny brugerhenvendelse.
4.4.1 Struktur
Da USS-systemet er simpelt har vi kun én klasse i modelkomponenten.
Url |
- urlName: string
- amount: int
- cache: int
- time: date
- expires: date
- header: string
- html: string
|
+ url()
+~url()
+ *getHtml(in *url: char): char
- runQuery(in *myQuery: char): int
- insert_Url(in *url: char, cache: int, *expires: char): void
- checkFileStatus(in *url: char): void
- updateUrlAmount(in *url: char): void
- checkUrlExpires(): void
- findUrl(in *url: char): int
+ printTopTen(): void
+ printStat(): void
|
4.4.2 Klasser
4.4.2.1 Klassen ’Url’
4.4.2.1.1 Ansvar og formål
Klassen håndterer data til statistik og cache.
4.4.2.1.2 Adfærdsmønsterer
Klassen bliver implementeret som frie funktioner til et databasesystem. Den enkelte funktion er beskrevet i koden.
4.5.1 Struktur
Figur 11. Klassediagram for oversætter funktionaliteten.
4.5.2 Klasser
Selv om vi tidligere har placeres symboltabellen i data-komponenten, tager vi den med i denne modelbeskrivelse,
da symboltabellen er en integreret del af hele oversætteren.
Generelt henviser vi til kildekoden for beskrivelse af attributter og metoder.
4.5.2.1 Klassen ’Lexer’
4.5.2.1.1 Ansvar og formål
Finder tokens i dokumenter.
4.5.2.1.2 Adfærdsmønster
Se admønstrene for klassen ‘Token’.
4.5.2.2 Klassen ’Parser’
4.5.2.2.1 Ansvar og formål
Syntaksanalyse i oversætteren.
4.5.2.2.2 Adfærdsmønster
Grammatikken er en smule simplificeret i forhold til [RFC2068] afsnit 3.2.1:
<htmldocument> |
::= (<hyperlinkRef> | < javascriptlinkRef >) (<absURL> | relURL) | <tekst> |
<hyperlinkRef> |
::= <lesser> ( <A> | <IMG>)< HREF> |
<javascriptlinkRef> |
::= <LOC><HREF> |
<A> |
::= A <space>* |
<LOC> |
::= LOC<period> |
<HREF> |
::= HREF <equal> <qoute> |
<IMG> |
::= IMG <space>* <SRC> |
<SRC> |
::= SRC <equal><qoute><addProtokol><addServer><tekst> |
<BG> |
::= BG <equal> <qoute><addProtokol><addServer><tekst> |
<absURL> |
::= < protokol><relURL> |
<addProtokol> |
::= print { http:// | https:// } |
<addServer> |
::= print {(hostname-URL)} |
<protokol> |
::= (HTTP | HTTPS | FTP| GOPHER) <kolon> (<slash>)* |
<relURL> |
::= <server> <period> <network><period>
<domain><slash><path><slash><resource> | IPID
|
<server> |
::= <tekst>|epsilon |
<network> |
::= <tekst>|epsilon |
<domain> |
::= <tekst>|epsilon |
<path> |
::= (<tekst> <slash>)* <tekst><period><tekst>|epsilon |
<resource> |
::= <tekst> |epsilon |
<lesser> |
::= ' < ' |
<kolon> |
::= ' : ' |
<period> |
::= ' . ' |
<equal> |
::= ' = ' |
<quote> |
::= ' " ' | ' ’ ' (dobbeltgyf eller enkeltgyf) |
<space> |
:= ' ' (blanktegn) |
<slash> |
::= ' / ' |
<tekst> |
::= <BG> <char>* | <space> | <slash><kolon><period>
| <lesser> <period><equal>|HTTP| HTTPS |FTP|GOPHER|A|HREF|IP|IPID | Epsilon
|
<char> |
::= ID | # | ¤ | % | & | ( | ) | ? | + | Epsilon
......alle tegn undtagent <lesser> <kolon><qoute><space>
|
Alfabetet: Alle tegn som kan vrides ud af et standard 102-tasters tastatur.
ID og IPID repræsenterer alle andre navne- og nummertokens end keywords som kan sammensættes
af (0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c |...| z). Vi kunne desværre ikke få ø,æ og å,
og vi mener det hænger sammen med en typekonvertering i USS-systemet.
Grammatikken skal som overordnet mål sætte regler for hvordan vi finder et hyperlink,
så vi kan indsætte protokol, IP-adresse eller server.netværk.domæne.
Et hyperlink kan have flere forskellige udformninger, men fælles er at de alle står i mellem anførselstegn.
Nogle eksempler:
<a href=”www.jubii.dk”></a>
<a href=”/hent_et/billede_i/mit.bibliotek”>
<img src=”/dette/billede/er_et/logo.gif”>
<td background=”/baggrunds/billede/som/fylder/hele/siden.bmp”>
function javaScript(){ location.href=”inet.home19/min/hjemmeside/index.html”}
Vi har fra starten taget udgangspunkt i HTTP-protokollen, hvilket bevirker at vi ikke vil beskæftige os med andre protokoller,
såsom FTP og GOPHER, så den eneste grund til at de optræder i grammatikken er at vi skal bruge dem
til at frasortere de links som indeholder de nævnte protokoltyper i vores funktioner.
Til at starte med koncentrerede vi os om udtrykket ’href = " "’, men fandt siden hen ud af at for at kunne få billeder
med over måtte vi også indsætte protokol og IP-adresse i de relative links som peger på billedbiblioteker.
Som nævnt i afsnittet Afgrænsning har vi ikke tilstrækkelig erfaring med HTML-kodning
til at kunne gennemskue alle typer af links, hvorfor ikke alle hyperlinks kan forventes at virke.
4.5.2.3 Klassen ’Symboltabel’
4.5.2.3.1 Ansvar og formål
Klassen håndterer symboler i oversætteren
4.5.2.3.2 Adfærdsmønster
Se adfærdsmønstre i klassen ’Token’ og selve koden.
4.5.2.4 Klassen ’Token’
4.5.2.4.1 Ansvar og formål
Klassen håndterer tokens i oversætteren.
Figur 12. Tilstandsdiagram for klassen 'Token'
Ved tilstand 1 findes navnetokens:
Ved at bruge funktionerne isalpha() og isalnum() fra kataloget ctype.h findes navne-tokens.
Når et token er indlæst i lexbuf-feren, kaldes metoden lookup(),
som undersøger om det pågældende token står i symboltabellen.
Hvis det findes, returneres pladsnummeret og tokentypen for det pågældende token til parseren.
Hvis det ikke findes (–1) indsættes tokenet i tabellen og pladsnummeret returneres fra insert().
Herefter returneres pladsnummeret og tokentypen ID til parseren.
Ved tilstand 2 findes taltoken som for eksempel IP-forvalgsadresse eller IPID:
Hvis et lexeme genkendes som tal (digit) fortsættes indlæsningen i lexBuf-feren
indtil andet end tal, punktum eller kolon forekommer.
Så kaldes lookup() for at undersøge om det er vores IP-forvalgs-adresse
og token returneres med attributten IP.
Hvis det ikke findes (–1) indsættes tokenet i tabellen og pladsnummeret returneres fra insert().
Herefter returneres pladsnummeret og tokentypen IPID til parseren.
Af praktiske årsager har vi arbejdet med web-komponenten i klassisk struktureret stil med frie funktioner,
og har derfor ikke arbejdet med et klassediagram.
Hvordan komponenten er bygget op og fungerer fremgår af selve koden og dens kommentarer.
For at holde fast i den overordnede funktionalitet, har vi skrevet en kort pseudekode til modulet:
Intialize Socket
while(!close)
{
Socket.listen(54321)
if(Call(54321!=close)
spawn childprocess
{
if(CheckCache(request)=exist)
SendToUser(CachedDocument)
create new socket(RandomPort>1024)
SendToWebserver(request)
recieve(datachunk)
while(datachunk<1448)
write.ChunkToFile(datachunk)
parse(datafile)
SendToUser(parsedfile)
SendToCache(parsedfile)
Close(childprocess)
}
else exit
}
Der er kun brugergrænseflade til statistikken, og da der er tale om en meget simpel brugergrænseflade,
henviser vi til kildekodens kommentarer for beskrivelsen af komponenten.
4.8.1 Edb-systemets nytte
Vi mener at det er muligt ud fra dette design at lave et system der opfylder
kvalitetsmålene, primært med hensyn til brugbarhed, korrekthed og pålidelighed.
4.8.2 Ibrugtagningsplan
Installationen og dokumentationen af USS-systemet foretages af leverandøren.
Installationen af underliggende systemer som operativsystem og anden systemsoftware aftales med kunden i kontrakten.
4.8.3 Realiseringsplan
Efter kontraktunderskrivelsen bør en Proof-of-Concept session kunne afholdes inden for en måned.
Efter godkendelse kan versionen til endelig systemtest leveres efter højest en måned.
Brugertesten og driftstesten skal afvikles to uger efter systemgodkendelsen.
Installation og iværksættelse skal være afholdt højest to uger efter godkendt brugertest og driftstest.
Under hele forløbet forudsættes mindst to fulde personresurser afsat til udvikling, test, dokumentation og installation.
Til ledelse og kundekontakt afsættes 0,2 person i hele forløbet.
Lexeren, parseren og symboltabellen implementeres i ét modul kaldet Oversætter-modulet.
Statistik-styring, cache-styring, statistik-date, URL-data, HTTP-data og HTML-data implementeres i ét modul, Uri-modulet.
Vi er af vores underviser blevet rådet til ikke at implementerer max-age direktivet – så det har vi ikke gjort.
Web-komponenten implementeres i proxy-modulet, der også tager initiativ til anvendelse af de øvrige moduler.
Generelt returnerer alle funktioner og metoder en værdi, der fortæller om afviklingen.
Værdien 0 (nul) bruges hvis alt forløb uden problemer,
værdien –1 (minus-en) bruges hvis der har været en fejl uden at fortælle nærmere om fejlen
eller de forhold den opstod under.
Andre værdier forklares i de funktioner og metoder hvor de returneres fra.
5.2.1 Afgrænsning ved implementation af oversætteren.
Frem for at parse os frem til de tokens vi har brug for, har vi valgt at indlæse dem som nøgleord (keywords)
i symboltabellen før parsningen starter.
Venstre side af produktionsreglerne/grammatikken er implementeret som booleske funktioner, da det – sammen med de indlæste nøgleord – gør parsningen hurtigere.
Alternativt kunne vi have valgt at parse dokumentet for korrekt tag-sætning, men dels er det ikke en del af opgaven
dels kan et html-dokument vises korrekt selv om der mangler slut-tags ( eks. </P> ) dels risikerer vi at komme til
at sætte dem forkert i forhold til forfatterens hensigt.
En total parsning af et HTML-dokument for alle udtryk som indeholder ’href="...’ kræver et indgående kendskab
til HTML kodning (for ikke at tale om javascript og applet og hvad der nu måtte findes af sprog/metoder) som vi ikke besidder.
Derfor er der i vores test-dokument, en række udtryk som har fået indsat IP-adresse uden grund,
og udtryk som burde have haft indsat IP-adressen som ikke har fået indsat det.
Eksempel på ovennævnte udtryk som fik IP-adressen indsat forkert sted:
<a href="(IP)javascript:openURL
('http://(skulle have stået her)www.iconico.com');">Iconico.com</a><br>
Vores forudsætning er derfor at hver gang vi støder på href=" eller href=’,
er det et udtryk som skal have indsat vores IP-adresse.
5.2.2 Filer
Vi tilstræber at definitioner og frie funktioner findes i .h-filer, mens implementeringer findes i .cc-filer.
Klassen ’Url’ i modelkomponenten transformeres attributterne til felter i en tabel, og metoderne bliver til frie funktioner.
Konstruktøren url() og dekonstruktøren ~url() transformeres til henholdsvis myDBconnect() og myDBconClose().
Tabellen deles i praksis i to tabeller; tabellen "url" til statistik og tabellen "html" til cache.
5.3.1 Struktur
Figur 13. Diagram over tabelrelationer.
5.3.2 Tabeller
5.3.2.1 Tabellen ’url’
Navn |
Type |
Størrelse |
Beskrivelse |
url_name |
char |
50 |
Primær nøgle |
amount |
int |
|
Antal anvendelser af URL |
cache |
int |
|
Må siden caches? Se koden |
f_id |
int |
|
Fremmednøgle til tbl_filenames |
url_time |
date |
|
Timestamp for første indsættelse af URL |
url_expires |
date |
|
Udløbstidspunk fra HTTP-header |
5.3.2.2 Tabellen ’html’
Navn |
Type |
Størrelse |
Beskrivelse |
f_id |
int |
|
Primær nøgle |
f_header |
char |
255 |
HTTP-headeren |
f_html |
text |
2048 |
HTML-dokumentet |
5.3.2.3 Interproces håndtering
Vi har arbejdet med at styre flere processers tilgang til databasen med semaphorer.
Det lykkedes ikke at få styringen med i selve USS-systemet inden afleveringen,
men denne ufuldstændige kode er et udtryk for vores overvejelser og arbejde med problematikken:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
//Model til brug af semaforer
int main() {
//Definerer først semafor
key_t key;
int semset_id;
// Create unique key via call to ftok()
key = ftok(".", 's');
//Opret semaforen til kun een ad gangen/ ressource)
semset_id = semget( key, 1 , IPC_CREAT | 0660 );
if ( semset_id == -1) {
// udskriv fejltekst "Fejl ved semafor oprettelse";
exit (1);
}
//Skriv semaforen ned med 1 ( lock ) 2 parameter
struct sembuf sem_lock = { 0, -1, 0 };
if (semop(semset_id, &sem_lock,1 ) == -1) {
; //udskriv fejltekst "Fejl ved locking af semafor"
}
//Nu er der laast
//udfoer databasekaldet
//saet semaforen op med 1 ( unlock ) igen med 2 parameter
struct sembuf sem_unlock = { 0, 1, 0 };
if (semop(semset_id, &sem_lock,1 ) == -1) {
; //Udskriv fejltekst "Fejl ved unlocking af semafor"
}
return (0);
}
Vi har brugt rigtig megen tid på at få en kørende Linux med de nødvendige installationer
op at stå hos os alle, da ingen af os havde erfaring med Linux eller en anden UNIX-art.
Vi har også brugt en del tid på at installerer forskellige databasesystemer som for eksempel MySQL
for at finde et vi også kan bruge i eksamenssituationen.
Eksempler på teknikker og funktionaliteter har som regel været givet i C, hvor der til denne opgave er et krav
at der er programmeret i C++. Vi har brugt megen tid på at få C-eksempler til at køre i en C++-implementering,
tid der er gået fra arbejdet med selve projektet.
Alle disse opgaver ligger uden for pensum og undervisning, men har været en væsentligt del af gruppens arbejde.
Vi har fået en del råd og vejledning fra vores undervisere, som har gjort det muligt at komme et stykke vej
med disse for os alle helt nye fagområder – men alligevel mener vi der er et misforhold mellem undervisning/pensum og forventninger.
I et rigtigt produktionsmiljø hos en rigtig levende ISP'er ville vi meget gerne have inkluderet en syslog-funktionalitet,
både for vores egen og for kundens skyld.
Som systemet er nu, skal der logges på før det kan startes.
Vi mener et proxy-system skal være implementeret som services, der ikke kræver logon for at starte.
Vi har ikke implementeret dette, da vi ikke véd hvordan det skal gøres.
Vores cache er temmelig primitiv, og der er gode muligheder for forbedring...
Som USS-systemet kører nu bliver der dannet del zombier og midlertidige filer, hvis antal kun vokser uden at de anvendes.
Derfor bør systemet vendes cirka en gang i døgnet, dette kan sikket håndteres af cron.
Ellers henviser vi til vores afgrænsning,
som vi egentlig gerne ville have fjernet ved at inkludere elementerne i systemet.
Vi er ganske klart blevet mere vidende og erfarne inden for protokoller, sockets, oversættelse,
Linux og hvad projektet ellers har budt på.
Projektet har været spændende og har opfyldt vores generelle forventninger til kurset.
……………………………………. …………………………………….
Frank Bierlich Niels Grove-Rasmussen
……………………………………. …………………………………….
Mikkel Munksgaard Bente Nielsen
…………………………………….
Noel Nugent
[Main og Savitch] Michael Main og Walter Savitch:
Data Structures and other Objects Using C++
(2. udgave, 2001, Addison Wesley Longman, ISBN 0-201-70297-5)
[Tanenbaum] Andrew S. Tanenbaum:
Distributed Operating Systems
(1995, Prentice-Hall, ISBN 0-13-219908-4)
[Glass og Ables] Graham Glass og King Ables:
UNIX® for Programmers and Users
(2. udgave, 1999, Prentice-Hall, ISBN 0-13-681685-1)
[Harel] David Harel:
Algorithmics: The Spirit of Computing
(2. udgave, 1993, Addison-Wesley, ISBN 0-201-50401-4)
[RFC2068] R. Fielding, J. Gettys, J. Mogul, H. Frystyk og T. Berners-Lee:
Hypertext Transfer Protocol – HTTP/1.1
(1997, RFC 2068)
Vi har desuden benyttet disse tekster til opslag:
[RFC3143] I. Cooper og J. Dilley:
Known HTTP Proxy/Caching Problems
(2001, The Internet Society, RFC 3143)
[Ford og Topp] William H. Ford og William R. Topp
Introduction to computing using C++ and object technology
(1999, Prentice-Hall, ISBN 0-13-268152-8)
[Mathiasen et al] Lars Mathiassen, Andreas Munk-Madsen, Peter Axel Nielsen og Jan Stage:
Objektorienteret analyse og design
(1998, 2. udgave, Forlaget Marko, ISBN 87-7751-129-8)
8.1.1 Implementering proxy.cc
8.2.1 Definition og implementering lexer.h
8.2.2 Definition og implementering parser.h
8.2.3 Definition og implementering symbolTable.h
8.2.4 Definition og implementering token.h
8.3.1 Definition cache.h
8.3.2 Implementering cache.cc
8.3.3 Definition og implementering statbgf.h
8.4.2 Implementering dbCon.cc
9.1.1 Installation af miniSQL
- msql-biblioteker oprettes:
- mkdir msql_install
- mkdir msql
- Filen msql-2_0_11.tager overføres til /msql_install
- Installationen pakkes ud:
- cd msql_install
- tager –xvf msql-2_0_11.tager
- Biblioteker dannes:
- cd msql-2_0_11/scripts
- ./make-target
- cd targets
- ./setup
- I filen site.mm sættes INST_DIR=/home/<bruger>/msql
- Database-programmer dannes:
- make all
- make install
- cd .. (tre gange)
- I filen .bash_profile sættes PATH=$PATH:$HOME/msql/bin
- I filen msql/msql.conf sættes:
- mSQL_User=<bruger>
- Admin_User=<bruger>
- TCP_Port=4312
- Serveren startes med msql2d &
9.1.2 Installation af USS-applikationen
Kildekoden skal oversættes, og webmodulet startes. Vi ville gerne have samle hele oversættelsen i et batch-job,
men vi brugte tiden på at kode selve USS-systemet.
USS-systemet startes op i denne rækkefølge:
- Database
- Funktioner
- Web
Opstarten bør i en endelig udgave af systemet håndteres af et script,
der holder øje med om hver del starter korrekt og er oppe før næste del starter.
En kontrolleret nedlukning af systemet bør ske i denne rækkefølge:
- Web
- Funktioner
- Database
Igen tænker vi os at proceduren styres af et script, der kontrollerer at en del er nede før næste del lukkes ned.
10.1.1 Test af web-komponenten
Testen gik i al enkelthed ud på at browse en side via USS-systemets IP-adresse og portnummer,
og så se om der kom et brugbart svar tilbage. Der er sat lidt kode til udskrift af status inde i selve funktionerne.
Se eventuelt i koden.
10.1.2 Test af Oversætter-komponenten
Den første og mest banale test gik på om programkoden overhovedet kunne oversættes.
Derefter udførte vi to hovedtests:
- En Black-box test for om input generer det forventede output.
- En White-box test for programmodulets interne tilstandsændringer ved at køre programmet.
10.1.2.1 Black-box test
Dernæst testede vi de enkelte funktioner ved at indsætte en printf("Funktionsnavn").
Ved at køre programmet med et kendt input kunne vi se om de forskellige funktioner oversatte den del af inputtet som de skulle.
Eks. (de med fed markeret er printf-output)
Input: <a href=”www.test.dk”>
Output: isLesser < isA a isSpace isHref href isQoute " isEqual
= isServer www isPeriod . isNetwork test isPeriod . isDomain dk isChar< >
Ligeledes testede vi med et input som ikke indeholdt nogle af de keywords som vores oversætter skulle reagere på:
Eks:
Input: <html><meta><body bgcolor="#0062FA>...
Output: isLesser < isTekst html> isLesser < meta> isLesser <body isSpace bgcolor="#0062FA>
Dernæst testede vi for et manglende tegn:
Eks:
Input: <a href=www.test2.dk"> her mangler det første anførselstegn
Outout: isLesser < iaA a isSpace isHref href (her returneres ’false’ fra
isRelURl() fordi den ikke finder et anførselstegn og resten udføres af isTekst()
uden få indsat evt. Protokol og IP-adresse) isTekst www.test2.dk">
10.1.2.2 White-box test
Lakmustesten var et HTML-dokument som blev sammensat af diverse problematiske steder på internettet
og som indeholder alle de elementer som vores oversætter skulle kunne håndtere – samt nogle flere.
Se også afsnittet Afgrænsning.
10.1.3 Test af databasen-komponenten
Vi har brugt dette lille program til undervejs i forløbet at se om komponenten opførte sig ordentligt:
//test main
void main() {
//myDBconnect();
int cache = 0;
char* expires = "0";
char* chr = "www.frank.dk";
//insert_Url(chr,cache,expires);
//updateUrlAmount(chr);
//checkUrlExpires();
//findUrl(chr);
getHtml(chr);
//myDBconClose();
}
10.1.4 Test af Statistik-komponenten
Vi kalder en URL og ser efter at tabellerne bliver opdateret korrekt.
10.1.5 Test af Cache-komponenten
(cachetest.cc)
Dette lille program anvender den fri funktion til cachehåndtering, og det korrekte svar gives.
Testforløbet er ufuldstændigt, men alligevel har det hjulpet til at finde og rette en del fejl og mangler.
GMT |
Greenwich Mean Time. International referencetidszone. |
HTML |
HyperText Markup Language. Sprog til hypertekst dokumenter på internettets web-del.
|
HTTP |
Hypertext Transfer Protocol. Specificeret i [RFC2068]. |
IBM |
International Buisness Machines. Multinational edb-koncern. |
IP |
Internet Protocol. |
ISP |
Internet Service Provider. Internetudbyder. |
NTP |
Network Time Protokol. |
RAM |
Ramdom Access Memory. Flygtigt lager. |
TCP |
Transmission Control Protocol. |
URI |
Uniform Ressource Identifier. En streng, der identificerer en HTTP-resurse. |
URL |
Uniform Ressource Location. En uformel beskrivende sti til en internetresurse associeret med udbredte URI-systemer
som http, ftp, mailto og så videre. For eksempel http://www.w3.org/Addressing/.
Forkortelsen benyttes ikke længere i tekniske specifikationer.
|
UML |
Unified Modeling Language. Standadiseret notation til objektorienteret systemudvikling. |