mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-29 21:25:35 +00:00
113 lines
2.8 KiB
C++
113 lines
2.8 KiB
C++
#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)
|
|
{
|
|
if (*aStart == nsCRT::CR && (aStart.size_forward() > 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, headerEnd;
|
|
header.BeginReading(headerStart);
|
|
header.EndReading(headerEnd);
|
|
if (!FindCharInReadable(':', headerStart, headerEnd)) {
|
|
return false;
|
|
}
|
|
|
|
aHeaderName.Assign(StringHead(header, headerStart.size_backward()));
|
|
aHeaderName.CompressWhitespace();
|
|
if (!NS_IsValidHTTPToken(aHeaderName)) {
|
|
return false;
|
|
}
|
|
|
|
aHeaderValue.Assign(Substring(++headerStart, headerEnd));
|
|
if (!NS_IsReasonableHTTPHeaderValue(aHeaderValue)) {
|
|
return false;
|
|
}
|
|
aHeaderValue.CompressWhitespace();
|
|
|
|
return PushOverLine(aStart);
|
|
}
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|