@@ -391,15 +391,28 @@ namespace plain {
391
391
case d and d.isAlphanumeric => true
392
392
case _ => false
393
393
}
394
+ def isLWS(c: Char): Bool = c match {
395
+ case '\t' => true
396
+ case ' ' => true
397
+ case _ => false
398
+ }
394
399
395
- // TODO line continuations
396
400
def parseHeaderLine(): (String, String) / { Scan[Char], Exception[WrongFormat] } = {
397
401
with returning::expect("HTTP Header line")
398
402
val k = collectString { readWhile { c => c.isHTTPTokenChar() } }
399
403
readIf(':')
400
- skipWhile { c => c == ' ' || c == '\t' }
401
- val v = collectString { readWhile { c => c != '\r' } }
402
- skipWhile { c => c == ' ' || c == '\t' }
404
+ skipWhile { c => c.isLWS }
405
+ val v = collectString {
406
+ readWhile { c => c != '\r' }
407
+ readIf('\r'); readIf('\n')
408
+ while(do peek[Char]().isLWS) {
409
+ // continuation line
410
+ skipWhile { c => c.isLWS }
411
+ do emit('\n')
412
+ readWhile { c => c != '\r'}
413
+ readIf('\r'); readIf('\n')
414
+ }
415
+ }
403
416
(k, v)
404
417
}
405
418
@@ -431,8 +444,6 @@ namespace plain {
431
444
expect("Trailers or end of response"){
432
445
while(do peek[Char]() != '\r') {
433
446
do emit(parseHeaderLine())
434
- readIf('\r')
435
- readIf('\n')
436
447
}
437
448
readIf('\r')
438
449
readIf('\n')
@@ -459,8 +470,6 @@ namespace plain {
459
470
headers = collectList {
460
471
while(do peek[Char]() != '\r') {
461
472
do emit(parseHeaderLine())
462
- readIf('\r')
463
- readIf('\n')
464
473
}
465
474
}
466
475
readIf('\r')
@@ -680,12 +689,18 @@ namespace example {
680
689
crlf()
681
690
"content-type: text/plain".each;
682
691
crlf()
692
+ "x-multiline-test-header: This is the first line".each
693
+ crlf()
694
+ " and this is the second line".each
695
+ crlf()
683
696
crlf()
684
697
"Hello!".each
685
698
}
686
699
with def res = plain::parseResponse
687
700
println(res.status())
688
701
println(res.getHeader("content-type").show{ x => x })
702
+ println("X-Multiline-Test-Header:")
703
+ println(res.getHeader("x-multiline-test-header").show{ x => x })
689
704
with source[Byte]{ res.body() }
690
705
with decodeUTF8
691
706
with stringBuffer
0 commit comments