response.go 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // Copyright 2017 Frédéric Guillot. All rights reserved.
  2. // Use of this source code is governed by the Apache 2.0
  3. // license that can be found in the LICENSE file.
  4. package client // import "miniflux.app/http/client"
  5. import (
  6. "io"
  7. "io/ioutil"
  8. "mime"
  9. "strings"
  10. "golang.org/x/net/html/charset"
  11. "miniflux.app/logger"
  12. )
  13. // Response wraps a server response.
  14. type Response struct {
  15. Body io.Reader
  16. StatusCode int
  17. EffectiveURL string
  18. LastModified string
  19. ETag string
  20. ContentType string
  21. ContentLength int64
  22. }
  23. // IsNotFound returns true if the resource doesn't exists anymore.
  24. func (r *Response) IsNotFound() bool {
  25. return r.StatusCode == 404 || r.StatusCode == 410
  26. }
  27. // IsNotAuthorized returns true if the resource require authentication.
  28. func (r *Response) IsNotAuthorized() bool {
  29. return r.StatusCode == 401
  30. }
  31. // HasServerFailure returns true if the status code represents a failure.
  32. func (r *Response) HasServerFailure() bool {
  33. return r.StatusCode >= 400
  34. }
  35. // IsModified returns true if the resource has been modified.
  36. func (r *Response) IsModified(etag, lastModified string) bool {
  37. if r.StatusCode == 304 {
  38. return false
  39. }
  40. if r.ETag != "" && r.ETag == etag {
  41. return false
  42. }
  43. if r.LastModified != "" && r.LastModified == lastModified {
  44. return false
  45. }
  46. return true
  47. }
  48. // EnsureUnicodeBody makes sure the body is encoded in UTF-8.
  49. //
  50. // If a charset other than UTF-8 is detected, we convert the document to UTF-8.
  51. // This is used by the scraper and feed readers.
  52. //
  53. // Do not forget edge cases:
  54. // - Some non-utf8 feeds specify encoding only in Content-Type, not in XML document.
  55. func (r *Response) EnsureUnicodeBody() error {
  56. _, params, err := mime.ParseMediaType(r.ContentType)
  57. if err == nil {
  58. if enc, found := params["charset"]; found {
  59. enc = strings.ToLower(enc)
  60. if enc != "utf-8" && enc != "utf8" && enc != "" {
  61. logger.Debug("[EnsureUnicodeBody] Convert body to utf-8 from %s", enc)
  62. r.Body, err = charset.NewReader(r.Body, r.ContentType)
  63. if err != nil {
  64. return err
  65. }
  66. }
  67. }
  68. }
  69. return nil
  70. }
  71. // String returns the response body as string.
  72. func (r *Response) String() string {
  73. bytes, _ := ioutil.ReadAll(r.Body)
  74. return string(bytes)
  75. }