summaryrefslogtreecommitdiffstats
path: root/dom/fetch/FetchUtil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/fetch/FetchUtil.cpp')
-rw-r--r--dom/fetch/FetchUtil.cpp114
1 files changed, 114 insertions, 0 deletions
diff --git a/dom/fetch/FetchUtil.cpp b/dom/fetch/FetchUtil.cpp
new file mode 100644
index 000000000..601d99216
--- /dev/null
+++ b/dom/fetch/FetchUtil.cpp
@@ -0,0 +1,114 @@
+#include "FetchUtil.h"
+
+#include "nsError.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsString.h"
+
+#include "mozilla/dom/EncodingUtils.h"
+
+namespace mozilla {
+namespace dom {
+
+// static
+nsresult
+FetchUtil::GetValidRequestMethod(const nsACString& aMethod, nsCString& outMethod)
+{
+ nsAutoCString upperCaseMethod(aMethod);
+ ToUpperCase(upperCaseMethod);
+ if (!NS_IsValidHTTPToken(aMethod)) {
+ outMethod.SetIsVoid(true);
+ return NS_ERROR_DOM_SYNTAX_ERR;
+ }
+
+ if (upperCaseMethod.EqualsLiteral("CONNECT") ||
+ upperCaseMethod.EqualsLiteral("TRACE") ||
+ upperCaseMethod.EqualsLiteral("TRACK")) {
+ outMethod.SetIsVoid(true);
+ return NS_ERROR_DOM_SECURITY_ERR;
+ }
+
+ if (upperCaseMethod.EqualsLiteral("DELETE") ||
+ upperCaseMethod.EqualsLiteral("GET") ||
+ upperCaseMethod.EqualsLiteral("HEAD") ||
+ upperCaseMethod.EqualsLiteral("OPTIONS") ||
+ upperCaseMethod.EqualsLiteral("POST") ||
+ upperCaseMethod.EqualsLiteral("PUT")) {
+ outMethod = upperCaseMethod;
+ }
+ else {
+ outMethod = aMethod; // Case unchanged for non-standard methods
+ }
+ return NS_OK;
+}
+
+static bool
+FindCRLF(nsACString::const_iterator& aStart,
+ nsACString::const_iterator& aEnd)
+{
+ nsACString::const_iterator end(aEnd);
+ return FindInReadable(NS_LITERAL_CSTRING("\r\n"), aStart, end);
+}
+
+// Reads over a CRLF and positions start after it.
+static bool
+PushOverLine(nsACString::const_iterator& aStart,
+ const nsACString::const_iterator& aEnd)
+{
+ if (*aStart == nsCRT::CR && (aEnd - aStart > 1) && *(++aStart) == nsCRT::LF) {
+ ++aStart; // advance to after CRLF
+ return true;
+ }
+
+ return false;
+}
+
+// static
+bool
+FetchUtil::ExtractHeader(nsACString::const_iterator& aStart,
+ nsACString::const_iterator& aEnd,
+ nsCString& aHeaderName,
+ nsCString& aHeaderValue,
+ bool* aWasEmptyHeader)
+{
+ MOZ_ASSERT(aWasEmptyHeader);
+ // Set it to a valid value here so we don't forget later.
+ *aWasEmptyHeader = false;
+
+ const char* beginning = aStart.get();
+ nsACString::const_iterator end(aEnd);
+ if (!FindCRLF(aStart, end)) {
+ return false;
+ }
+
+ if (aStart.get() == beginning) {
+ *aWasEmptyHeader = true;
+ return true;
+ }
+
+ nsAutoCString header(beginning, aStart.get() - beginning);
+
+ nsACString::const_iterator headerStart, iter, headerEnd;
+ header.BeginReading(headerStart);
+ header.EndReading(headerEnd);
+ iter = headerStart;
+ if (!FindCharInReadable(':', iter, headerEnd)) {
+ return false;
+ }
+
+ aHeaderName.Assign(StringHead(header, iter - headerStart));
+ aHeaderName.CompressWhitespace();
+ if (!NS_IsValidHTTPToken(aHeaderName)) {
+ return false;
+ }
+
+ aHeaderValue.Assign(Substring(++iter, headerEnd));
+ if (!NS_IsReasonableHTTPHeaderValue(aHeaderValue)) {
+ return false;
+ }
+ aHeaderValue.CompressWhitespace();
+
+ return PushOverLine(aStart, aEnd);
+}
+
+} // namespace dom
+} // namespace mozilla