multipart.go 1.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. package mpjpeg
  2. import (
  3. "bufio"
  4. "errors"
  5. "io"
  6. "net/http"
  7. "net/textproto"
  8. "strconv"
  9. "strings"
  10. )
  11. func Next(rd *bufio.Reader) (http.Header, []byte, error) {
  12. for {
  13. // search next boundary and skip empty lines
  14. s, err := rd.ReadString('\n')
  15. if err != nil {
  16. return nil, nil, err
  17. }
  18. if s == "\r\n" {
  19. continue
  20. }
  21. if !strings.HasPrefix(s, "--") {
  22. return nil, nil, errors.New("multipart: wrong boundary: " + s)
  23. }
  24. // Foscam G2 has a awful implementation of MJPEG
  25. // https://github.com/AlexxIT/go2rtc/issues/1258
  26. if b, _ := rd.Peek(2); string(b) == "--" {
  27. continue
  28. }
  29. break
  30. }
  31. tp := textproto.NewReader(rd)
  32. header, err := tp.ReadMIMEHeader()
  33. if err != nil {
  34. return nil, nil, err
  35. }
  36. s := header.Get("Content-Length")
  37. if s == "" {
  38. return nil, nil, errors.New("multipart: no content length")
  39. }
  40. size, err := strconv.Atoi(s)
  41. if err != nil {
  42. return nil, nil, err
  43. }
  44. buf := make([]byte, size)
  45. if _, err = io.ReadFull(rd, buf); err != nil {
  46. return nil, nil, err
  47. }
  48. return http.Header(header), buf, nil
  49. }