@@ -19,9 +19,10 @@ import (
19
19
// Stream abstracts the transport mechanics from the JSON RPC protocol.
20
20
type Stream interface {
21
21
// Read gets the next message from the stream.
22
- Read (context.Context ) ([]byte , error )
22
+ Read (ctx context.Context , p []byte ) (n int , err error )
23
+
23
24
// Write sends a message to the stream.
24
- Write (context.Context , []byte ) error
25
+ Write (ctx context.Context , p []byte ) ( n int , err error )
25
26
}
26
27
27
28
type stream struct {
@@ -30,26 +31,25 @@ type stream struct {
30
31
sync.Mutex
31
32
}
32
33
33
- // NewStream returns the new Stream.
34
34
func NewStream (in io.Reader , out io.Writer ) Stream {
35
35
return & stream {
36
36
in : bufio .NewReader (in ),
37
37
out : out ,
38
38
}
39
39
}
40
40
41
- func (s * stream ) Read (ctx context.Context ) ( []byte , error ) {
41
+ func (s * stream ) Read (ctx context.Context , p []byte ) ( n int , err error ) {
42
42
select {
43
43
case <- ctx .Done ():
44
- return nil , ctx .Err ()
44
+ return 0 , ctx .Err ()
45
45
default :
46
46
}
47
47
48
48
var length int64
49
49
for {
50
50
line , err := s .in .ReadString ('\n' )
51
51
if err != nil {
52
- return nil , xerrors .Errorf ("failed reading header line: %w" , err )
52
+ return 0 , xerrors .Errorf ("failed reading header line: %w" , err )
53
53
}
54
54
55
55
line = strings .TrimSpace (line )
@@ -59,49 +59,49 @@ func (s *stream) Read(ctx context.Context) ([]byte, error) {
59
59
60
60
colon := strings .IndexRune (line , ':' )
61
61
if colon < 0 {
62
- return nil , xerrors .Errorf ("invalid header line: %q" , line )
62
+ return 0 , xerrors .Errorf ("invalid header line: %q" , line )
63
63
}
64
64
65
65
name , value := line [:colon ], strings .TrimSpace (line [colon + 1 :])
66
- switch name {
67
- case "Content-Length" :
68
- if length , err = strconv .ParseInt (value , 10 , 32 ); err != nil {
69
- return nil , xerrors .Errorf ("failed parsing Content-Length: %v" , value )
70
- }
71
-
72
- if length <= 0 {
73
- return nil , xerrors .Errorf ("invalid Content-Length: %v" , length )
74
- }
75
- default :
76
- // ignoring unknown headers
66
+ if name != "Content-Length" {
67
+ continue
68
+ }
69
+
70
+ if length , err = strconv .ParseInt (value , 10 , 32 ); err != nil {
71
+ return 0 , xerrors .Errorf ("failed parsing Content-Length: %v" , value )
72
+ }
73
+
74
+ if length <= 0 {
75
+ return 0 , xerrors .Errorf ("invalid Content-Length: %v" , length )
77
76
}
78
77
}
79
78
80
79
if length == 0 {
81
- return nil , xerrors .New ("missing Content-Length header" )
80
+ return 0 , xerrors .New ("missing Content-Length header" )
82
81
}
83
82
84
- data := make ([]byte , length )
85
- if _ , err := io .ReadFull (s .in , data ); err != nil {
86
- return nil , xerrors .Errorf ("failed reading data: %w" , err )
83
+ p = make ([]byte , length )
84
+ n , err = io .ReadFull (s .in , p )
85
+ if err != nil {
86
+ return 0 , xerrors .Errorf ("failed reading data: %w" , err )
87
87
}
88
88
89
- return data , nil
89
+ return n , nil
90
90
}
91
91
92
- func (s * stream ) Write (ctx context.Context , data []byte ) error {
92
+ func (s * stream ) Write (ctx context.Context , p []byte ) ( n int , err error ) {
93
93
select {
94
94
case <- ctx .Done ():
95
- return ctx .Err ()
95
+ return 0 , ctx .Err ()
96
96
default :
97
97
}
98
98
99
99
s .Lock ()
100
- _ , err : = fmt .Fprintf (s .out , "Content-Length: %v\r \n \r \n " , len (data ))
100
+ n , err = fmt .Fprintf (s .out , "Content-Length: %v\r \n \r \n " , len (p ))
101
101
if err == nil {
102
- _ , err = s .out .Write (data )
102
+ n , err = s .out .Write (p )
103
103
}
104
104
s .Unlock ()
105
105
106
- return err
106
+ return n , err
107
107
}
0 commit comments