FetchUtil.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #include "FetchUtil.h"
  2. #include "nsError.h"
  3. #include "nsIUnicodeDecoder.h"
  4. #include "nsNetUtil.h"
  5. #include "nsString.h"
  6. #include "mozilla/dom/EncodingUtils.h"
  7. namespace mozilla {
  8. namespace dom {
  9. // static
  10. nsresult
  11. FetchUtil::GetValidRequestMethod(const nsACString& aMethod, nsCString& outMethod)
  12. {
  13. nsAutoCString upperCaseMethod(aMethod);
  14. ToUpperCase(upperCaseMethod);
  15. if (!NS_IsValidHTTPToken(aMethod)) {
  16. outMethod.SetIsVoid(true);
  17. return NS_ERROR_DOM_SYNTAX_ERR;
  18. }
  19. if (upperCaseMethod.EqualsLiteral("CONNECT") ||
  20. upperCaseMethod.EqualsLiteral("TRACE") ||
  21. upperCaseMethod.EqualsLiteral("TRACK")) {
  22. outMethod.SetIsVoid(true);
  23. return NS_ERROR_DOM_SECURITY_ERR;
  24. }
  25. if (upperCaseMethod.EqualsLiteral("DELETE") ||
  26. upperCaseMethod.EqualsLiteral("GET") ||
  27. upperCaseMethod.EqualsLiteral("HEAD") ||
  28. upperCaseMethod.EqualsLiteral("OPTIONS") ||
  29. upperCaseMethod.EqualsLiteral("POST") ||
  30. upperCaseMethod.EqualsLiteral("PUT")) {
  31. outMethod = upperCaseMethod;
  32. }
  33. else {
  34. outMethod = aMethod; // Case unchanged for non-standard methods
  35. }
  36. return NS_OK;
  37. }
  38. static bool
  39. FindCRLF(nsACString::const_iterator& aStart,
  40. nsACString::const_iterator& aEnd)
  41. {
  42. nsACString::const_iterator end(aEnd);
  43. return FindInReadable(NS_LITERAL_CSTRING("\r\n"), aStart, end);
  44. }
  45. // Reads over a CRLF and positions start after it.
  46. static bool
  47. PushOverLine(nsACString::const_iterator& aStart,
  48. const nsACString::const_iterator& aEnd)
  49. {
  50. if (*aStart == nsCRT::CR && (aEnd - aStart > 1) && *(++aStart) == nsCRT::LF) {
  51. ++aStart; // advance to after CRLF
  52. return true;
  53. }
  54. return false;
  55. }
  56. // static
  57. bool
  58. FetchUtil::ExtractHeader(nsACString::const_iterator& aStart,
  59. nsACString::const_iterator& aEnd,
  60. nsCString& aHeaderName,
  61. nsCString& aHeaderValue,
  62. bool* aWasEmptyHeader)
  63. {
  64. MOZ_ASSERT(aWasEmptyHeader);
  65. // Set it to a valid value here so we don't forget later.
  66. *aWasEmptyHeader = false;
  67. const char* beginning = aStart.get();
  68. nsACString::const_iterator end(aEnd);
  69. if (!FindCRLF(aStart, end)) {
  70. return false;
  71. }
  72. if (aStart.get() == beginning) {
  73. *aWasEmptyHeader = true;
  74. return true;
  75. }
  76. nsAutoCString header(beginning, aStart.get() - beginning);
  77. nsACString::const_iterator headerStart, iter, headerEnd;
  78. header.BeginReading(headerStart);
  79. header.EndReading(headerEnd);
  80. iter = headerStart;
  81. if (!FindCharInReadable(':', iter, headerEnd)) {
  82. return false;
  83. }
  84. aHeaderName.Assign(StringHead(header, iter - headerStart));
  85. aHeaderName.CompressWhitespace();
  86. if (!NS_IsValidHTTPToken(aHeaderName)) {
  87. return false;
  88. }
  89. aHeaderValue.Assign(Substring(++iter, headerEnd));
  90. if (!NS_IsReasonableHTTPHeaderValue(aHeaderValue)) {
  91. return false;
  92. }
  93. aHeaderValue.CompressWhitespace();
  94. return PushOverLine(aStart, aEnd);
  95. }
  96. } // namespace dom
  97. } // namespace mozilla