()
| 195 | } |
| 196 | |
| 197 | func (sc *serverConn) readLoop() (err error) { |
| 198 | defer func() { |
| 199 | if err := recover(); err != nil { |
| 200 | sc.logger.Printf("readLoop panicked: %s\n%s\n", err, debug.Stack()) |
| 201 | } |
| 202 | }() |
| 203 | |
| 204 | var fr *FrameHeader |
| 205 | |
| 206 | for err == nil { |
| 207 | fr, err = ReadFrameFromWithSize(sc.br, sc.clientS.frameSize) |
| 208 | if err != nil { |
| 209 | if errors.Is(err, ErrUnknownFrameType) { |
| 210 | sc.writeGoAway(0, ProtocolError, "unknown frame type") |
| 211 | err = nil |
| 212 | continue |
| 213 | } |
| 214 | |
| 215 | break |
| 216 | } |
| 217 | |
| 218 | if fr.Stream() != 0 { |
| 219 | err := sc.checkFrameWithStream(fr) |
| 220 | if err != nil { |
| 221 | sc.writeError(nil, err) |
| 222 | } else { |
| 223 | sc.reader <- fr |
| 224 | } |
| 225 | |
| 226 | continue |
| 227 | } |
| 228 | |
| 229 | // handle 'anonymous' frames (frames without stream_id) |
| 230 | switch fr.Type() { |
| 231 | case FrameSettings: |
| 232 | st := fr.Body().(*Settings) |
| 233 | if !st.IsAck() { // if it has ack, just ignore |
| 234 | sc.handleSettings(st) |
| 235 | } |
| 236 | case FrameWindowUpdate: |
| 237 | win := int64(fr.Body().(*WindowUpdate).Increment()) |
| 238 | if win == 0 { |
| 239 | sc.writeGoAway(0, ProtocolError, "window increment of 0") |
| 240 | // return |
| 241 | continue |
| 242 | } |
| 243 | |
| 244 | if atomic.AddInt64(&sc.clientWindow, win) >= 1<<31-1 { |
| 245 | sc.writeGoAway(0, FlowControlError, "window is above limits") |
| 246 | } |
| 247 | case FramePing: |
| 248 | ping := fr.Body().(*Ping) |
| 249 | if !ping.IsAck() { |
| 250 | sc.handlePing(ping) |
| 251 | } |
| 252 | case FrameGoAway: |
| 253 | ga := fr.Body().(*GoAway) |
| 254 | if ga.Code() == NoError { |
no test coverage detected