Table Of ContentSocketsandPipes
byChrisMartinandJulieMoronuki
©2022ChrisMartinandJulieMoronuki.Allrightsreserved.
2020-02-25:Firstdraft
2020-05-14:Seconddraft
2020-09-21:Thirddraft
2021-02-19:Fourthdraft
2021-05-01:Fifthdraft
2022-09-01:Sixthdraft
Contents
Preface 7
Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
What’sinside . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Proximitytoreality . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1 Handles 15
1.1 Thenecessityofindirection . . . . . . . . . . . . . . . . . . . 15
1.2 Writingtoafile . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.3 Diligentcleanup . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.4 MonadIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2 Chunks 31
2.1 Packedcharacters . . . . . . . . . . . . . . . . . . . . . . . . 31
2.2 Readingfromafile,onechunkatatime . . . . . . . . . . . . 34
2.3 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3 Bytes 41
3.1 Packedoctets. . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.2 Copyingafile. . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.3 Characterencodings . . . . . . . . . . . . . . . . . . . . . . . 45
3
3.4 TheShowandIsStringclasses . . . . . . . . . . . . . . . . . 50
3.5 Avoidingsystemdefaults . . . . . . . . . . . . . . . . . . . . 56
3.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4 Sockets 62
4.1 Openupandconnect . . . . . . . . . . . . . . . . . . . . . . 63
4.2 Extradetails . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
4.3 Namesandaddresses . . . . . . . . . . . . . . . . . . . . . . 68
4.4 Addressinformation . . . . . . . . . . . . . . . . . . . . . . . 71
4.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
5 HTTP 78
5.1 Thespecification. . . . . . . . . . . . . . . . . . . . . . . . . 79
5.2 HTTPrequests . . . . . . . . . . . . . . . . . . . . . . . . . . 80
5.3 ASCIIstrings . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
5.4 HTTPresponses . . . . . . . . . . . . . . . . . . . . . . . . . 86
5.5 Servingothers . . . . . . . . . . . . . . . . . . . . . . . . . . 88
5.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
6 HTTPtypes 93
6.1 Requestandresponse . . . . . . . . . . . . . . . . . . . . . . 94
6.2 Requestline . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
6.3 Statusline . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
6.4 Headerfields . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
6.5 Messagebody . . . . . . . . . . . . . . . . . . . . . . . . . . 99
6.6 HTTPversion . . . . . . . . . . . . . . . . . . . . . . . . . . 101
6.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
7 Encoding 105
7.1 Stringbuilders . . . . . . . . . . . . . . . . . . . . . . . . . . 105
7.2 Measuringtime . . . . . . . . . . . . . . . . . . . . . . . . . 108
7.3 Requestandresponse . . . . . . . . . . . . . . . . . . . . . . 112
7.4 Higher-orderencodings. . . . . . . . . . . . . . . . . . . . . 116
4
7.5 Thestartline . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
7.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
8 Responding 124
8.1 Ameasureofsuccess . . . . . . . . . . . . . . . . . . . . . . 124
8.2 Response-buildingutilities . . . . . . . . . . . . . . . . . . . 127
8.3 Integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
8.4 Responsetransmission . . . . . . . . . . . . . . . . . . . . . 132
8.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
9 Contenttypes 137
9.1 Somecommontypes. . . . . . . . . . . . . . . . . . . . . . . 138
9.2 UTF-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
9.3 HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
9.4 JSON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
9.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
10 Change 152
10.1 STM. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
10.2 Increment . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
10.3 Atomically . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
10.4Thecountingserver . . . . . . . . . . . . . . . . . . . . . . . 159
10.5 OtherSTMtopics . . . . . . . . . . . . . . . . . . . . . . . . 160
10.6Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
11 Streaming 164
11.1 Chunkedhello . . . . . . . . . . . . . . . . . . . . . . . . . . 166
11.2 Chunktypes . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
11.3 Encodingachunk . . . . . . . . . . . . . . . . . . . . . . . . 171
11.4 Transfer-Encoding . . . . . . . . . . . . . . . . . . . . . . . 173
11.5 Servingthefile . . . . . . . . . . . . . . . . . . . . . . . . . . 174
11.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
12 ListTIO 179
5
12.1 Thenewresponsetype . . . . . . . . . . . . . . . . . . . . . 179
12.2 WhatisListT . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
12.3 Constructingaresponse . . . . . . . . . . . . . . . . . . . . . 187
12.4 Encodingaresponse . . . . . . . . . . . . . . . . . . . . . . . 189
12.5 Sendingaresponse . . . . . . . . . . . . . . . . . . . . . . . 193
12.6ListTinotherlibraries . . . . . . . . . . . . . . . . . . . . . . 194
12.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
13 Parsing 198
13.1 Encodingvsdecoding . . . . . . . . . . . . . . . . . . . . . . 200
13.2 Attoparsec . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
13.3 Requestline . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
13.4 Explainingwhat’swrong . . . . . . . . . . . . . . . . . . . . 216
13.5 Incrementalparsing . . . . . . . . . . . . . . . . . . . . . . . 218
13.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
14 Errors 226
14.1 Statuscodes . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
14.2 Constructingresponses . . . . . . . . . . . . . . . . . . . . . 229
14.3 Visibilityintwoplaces . . . . . . . . . . . . . . . . . . . . . . 230
14.4Thread-safelogging . . . . . . . . . . . . . . . . . . . . . . . 236
14.5 Either . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
14.6ExceptT. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
14.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
Comingup 249
15 Readingthehead 250
16Readingthebody 251
17 Connectionreuse 252
A Solutionstoexercises 253
6
Preface
Thecontentthateventuallygrewintothisbookbeganwiththequestion:
Whatexactlyisawebserver? Asatisfactoryanswerthatdoesnotassume
substantialbackgroundknowledgerequiresspanningquiteafewareasof
computing. Fortunately,theyallserveasfruitfulmotivationsforsimulta-
neouslylearningabouthowtouseHaskell,whichisthelargerobjectiveof
theJoyofHaskellcollection.
ThelanguageawebserverspeaksistheHypertextTransferProtocol
(HTTP),whichthisbookexploresingreatdetailwhilewalkingthroughthe
creationofaserverfrom“scratch”.Weencouragereaderstofollowalong
inreadingtheofficialdefinitionofHTTP(RFC7230publishedbytheInter-
netEngineeringTaskForce)asweimplementthespecificationinHaskell.
Whilehigh-levellibrariesmakeitpossibletocreatewebapplicationswith-
outdetailedknowledgeofHTTP,webelievethatafullunderstandingof
theunderlyinglayerswebuilduponhelpsususeaplatformmoreeffec-
tively. BystudyingHTTPwealsogainanappreciationforwhatitisand
isnotgoodfor,andforwhatapplicationswemightstandtobenefitfrom
choosingadifferentnetworkprotocolinstead.
7
Prerequisites
ThisbookisforHaskelllearnerswhohavesomebasicfacultywiththelan-
guageandarenowreadytoworkuptoasubstantialproject.Weexpectthat
youunderstandthebasicsyntaxandcandothingslike:
(cid:228) writeacaseexpressiontopatternmatchoverasumtype
(cid:228) sequenceIOactionsinadoblock
(cid:228) usequalifiedimports
(cid:228) definedatatypes
(cid:228) useGHCi
(cid:228) installHaskelllibraries
Fromthebasepackage,weassumesomefamiliaritywith:
(cid:228) typesMaybe,Either,and[]
(cid:228) classesEq,Show,Monoid,Foldable,Functor,andMonad
WedonotassumepriorknowledgeofanyadditionallibrariesorGHC
languageextensions.
What’sinside
Bytesandcharacters Thefirstseveralchaptersintroducethebytestring
andtextlibrariesandarelargelydedicatedtotearingapartatraditional
helloworldprogram,lookingunderneaththeabstractnotionof“printing
text”tostartgreetingtheworldintermsofwritingbytestoafilehandle.
Afterdiscussingbytes,weneedonlyashorthoptosockets,ourmeansof
writingbytesacrossgreatdistancesusingthenetworklibrary.
Encodingandparsers FirstweencodingHTTPmessagesasbytestrings.
That’stheeasypart;next,wegointheoppositedirectionandlearnhowto
interpretbytestringsusingtheattoparseclibrary. Thiswillacquaintus
evenmorecloselywiththeHTTPmessageformat.
8
Monadtransformers WeintroducethreeMonadtransformersthatarees-
peciallyapplicabletooursubjectmatter:ResourceT,ListT,andExceptT.
Nopriorexperiencewithtransformersisrequired.Wedonotlingeronthe
generalconcept,preferringinsteadtofocusoneachofthethreeexamples
andtocreatefamiliaritywithtransformersandliftingchieflybydemon-
stration.
Resource safety Use of ResourceT begins in chapter 1, and we use it
throughoutthebook. Thismakesitabreezetodealwithfilesandsockets
withoutresourceleaks.
Streaming To move past toy examples that fit easily into memory, we
havetostartwritingstreamingprocessesthatcandealwithlargeamounts
ofdatabyhandlingitinsmallerpieces. Allofthecodewithinthisbookis
writtenwithmemoryusageinmind.ListT,thesubjectofchapter12,pro-
videsanespeciallyconvenientfacilityforworkingwithstreams.
Errorhandling Astheamountoffunctionalityofourserverbuildsup,the
numberofpossibleerrorconditionsstartstorise. Chapter14introduces
ExceptTtoworkwitherrorsinacleanandwell-typedmanner.
ThisbookhasacompanionHaskelllibrarycalledsockets-and-pipes,
availablefromthestandardpackagerepository.
https://hackage.haskell.org/package/sockets-and-pipes
Thelibraryre-exportsallofthemodulesfromotherlibrariesthatwe
useinthebook; prospectivereadersareencouragedtobrowsethedocu-
mentationatthewebaddressgivenabove,asitprovidesanoverviewofthe
librariesthatyouwilllearntousefromreadingthisbook.
9
Setup
Westronglyencourageyoutofollowalongwiththebookandtypethecode
asyouread. Theexercisesattheendofeachchaptermakeuseofthecode
giveninthechapter. Subsequentchapterswillalsoreferbacktodefini-
tionsfromearlierinthebook,soitisimportanttokeepeverythingasyou
progress.
Youcanorganizethecodehoweveryoulike,butherewegivearecom-
mendedsetupfortheconvenienceoflessopinionatedreaders.
book.cabal
cabal-version: 3.0
name: book
version: 0
data-files: **/*.txt
library
default-language: Haskell2010
default-extensions: BlockArguments QuasiQuotes
TypeApplications ScopedTypeVariables
ghc-options: -Wall -fdefer-typed-holes
build-depends: sockets-and-pipes ^>= 0.3
exposed-modules: Book
cabal-version,name,andversionarenecessitiesinanyCabalpack-
agefile.
Thedefault-extensionsfieldenablesafewlanguageextensions:
(cid:228) BlockargumentsisasmalladjustmenttotheHaskellsyntaxwhich
allowsadoblocktobeusedasafunctionparameter,ataskwhich
hastraditionallybeenaccomplishedusingthe($)operator.
10