Skip to content

Commit 50855c4

Browse files
Scan request headers
1 parent ef8f42d commit 50855c4

File tree

5 files changed

+114
-3
lines changed

5 files changed

+114
-3
lines changed

internal/syntax/scanner/v2/scanner.go

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,9 @@ func scanText(s *Scanner) stateFn {
412412
// scanRequest scans inside a HTTP request definition.
413413
//
414414
// The opening '###' and any request comment has already been consumed.
415+
//
416+
// The only thing allowed top level in a request is '#', '//' and
417+
// a request method.
415418
func scanRequest(s *Scanner) stateFn {
416419
s.skip(unicode.IsSpace)
417420

@@ -428,7 +431,6 @@ func scanRequest(s *Scanner) stateFn {
428431
return scanRequestSlash
429432
default:
430433
if isUpperAlpha(char) {
431-
// A request method
432434
return scanMethod
433435
}
434436

@@ -528,8 +530,68 @@ func scanURL(s *Scanner) stateFn {
528530
s.takeWhile(isURL)
529531
s.emit(token.Text)
530532

531-
// TODO(@FollowTheProcess): Should move the state to scanHTTPVersion or scanHeaders
532-
return scanStart
533+
s.skip(isLineSpace)
534+
535+
// Is there a HTTP version?
536+
if s.restHasPrefix("HTTP/") {
537+
return scanHTTPVersion
538+
}
539+
540+
s.skip(unicode.IsSpace)
541+
542+
if isIdent(s.peek()) {
543+
return scanHeaders
544+
}
545+
546+
// TODO(@FollowTheProcess): Probably should be scan body
547+
return scanRequest
548+
}
549+
550+
// scanHTTPVersion scans a literal 'HTTP/<version>' declaration.
551+
func scanHTTPVersion(s *Scanner) stateFn {
552+
s.takeExact("HTTP/")
553+
554+
s.takeWhile(isDigit)
555+
556+
if s.take(".") {
557+
// It's e.g 1.2
558+
s.takeWhile(isDigit)
559+
}
560+
561+
s.emit(token.HTTPVersion)
562+
563+
return scanHeaders
564+
}
565+
566+
// scanHeaders scans a request header.
567+
func scanHeaders(s *Scanner) stateFn {
568+
s.takeWhile(isIdent)
569+
s.emit(token.Ident)
570+
571+
if s.peek() != ':' {
572+
s.errorf("invalid header, expected ':', got %q", s.peek())
573+
return nil
574+
}
575+
576+
s.take(":")
577+
s.emit(token.Colon)
578+
579+
s.skip(isLineSpace)
580+
581+
if isText(s.peek()) {
582+
s.takeWhile(isText)
583+
s.emit(token.Text)
584+
}
585+
586+
s.skip(unicode.IsSpace)
587+
588+
// If there are more headers, call this function again!
589+
if isIdent(s.peek()) {
590+
return scanHeaders
591+
}
592+
593+
// TODO(@FollowTheProcess): Scan body
594+
return scanRequest
533595
}
534596

535597
// isLineSpace reports whether r is a non line terminating whitespace character,
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- src.http --
2+
# I'm a normal comment
3+
/ <- This is wrong, should be two '//'
4+
-- tokens.txt --
5+
<Token::Comment start=2, end=22>
6+
<Token::Error start=23, end=24>
7+
-- errors.txt --
8+
single-slash-global.txtar:2:1: invalid use of '/', two '//' mark a comment start, got '/'
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
-- src.http --
2+
###
3+
# I'm a normal comment
4+
/ <- This is wrong, should be two '//'
5+
GET https://example.com
6+
-- tokens.txt --
7+
<Token::Separator start=0, end=3>
8+
<Token::Comment start=6, end=26>
9+
<Token::Error start=27, end=28>
10+
-- errors.txt --
11+
single-slash-request.txtar:3:1: invalid use of '/', two '//' mark a comment start, got '/'
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
-- src.http --
2+
### Test
3+
GET https://api.somewhere.com/items/1
4+
Content-Type: application/json
5+
Accept: application/json
6+
X-Something-Else: yes
7+
-- tokens.txt --
8+
<Token::Separator start=0, end=3>
9+
<Token::Comment start=4, end=8>
10+
<Token::MethodGet start=9, end=12>
11+
<Token::Text start=13, end=46>
12+
<Token::Ident start=47, end=59>
13+
<Token::Colon start=59, end=60>
14+
<Token::Text start=61, end=77>
15+
<Token::Ident start=78, end=84>
16+
<Token::Colon start=84, end=85>
17+
<Token::Text start=86, end=102>
18+
<Token::Ident start=103, end=119>
19+
<Token::Colon start=119, end=120>
20+
<Token::Text start=121, end=124>
21+
<Token::EOF start=125, end=125>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-- src.http --
2+
###
3+
GET https://api.somewhere.com/items/1 HTTP/1.1
4+
-- tokens.txt --
5+
<Token::Separator start=0, end=3>
6+
<Token::MethodGet start=4, end=7>
7+
<Token::Text start=8, end=41>
8+
<Token::HTTPVersion start=42, end=50>
9+
<Token::EOF start=51, end=51>

0 commit comments

Comments
 (0)