/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set sw=2 ts=8 et tw=80 : */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// This needs to be forward declared here so we can include only this header // without also including PHttpChannelParams.h namespace IPC { template <typename> struct ParamTraits;
} // namespace IPC
namespace mozilla { namespace net {
class nsHttpHeaderArray { public: constchar* PeekHeader(const nsHttpAtom& header) const;
// For nsHttpResponseHead nsHttpHeaderArray will keep track of the original // headers as they come from the network and the parse headers used in // firefox. // If the original and the firefox header are the same, we will keep just // one copy and marked it as eVarietyResponseNetOriginalAndResponse. // If firefox header representation changes a header coming from the // network (e.g. merged it) or a eVarietyResponseNetOriginalAndResponse // header has been changed by SetHeader method, we will keep the original // header as eVarietyResponseNetOriginal and make a copy for the new header // and mark it as eVarietyResponse. enum HeaderVariety {
eVarietyUnknown, // Used only for request header.
eVarietyRequestOverride,
eVarietyRequestDefault,
eVarietyRequestEnforceDefault, // Used only for response header.
eVarietyResponseNetOriginalAndResponse,
eVarietyResponseNetOriginal,
eVarietyResponse
};
// Used by internal setters: to set header from network use SetHeaderFromNet
[[nodiscard]] nsresult SetHeader(const nsACString& headerName, const nsACString& value, bool merge,
HeaderVariety variety);
[[nodiscard]] nsresult SetHeader(const nsHttpAtom& header, const nsACString& value, bool merge,
HeaderVariety variety);
[[nodiscard]] nsresult SetHeader(const nsHttpAtom& header, const nsACString& headerName, const nsACString& value, bool merge,
HeaderVariety variety);
// Used by internal setters to set an empty header
[[nodiscard]] nsresult SetEmptyHeader(const nsACString& headerName,
HeaderVariety variety);
// Merges supported headers. For other duplicate values, determines if error // needs to be thrown or 1st value kept. // For the response header we keep the original headers as well.
[[nodiscard]] nsresult SetHeaderFromNet(const nsHttpAtom& header, const nsACString& headerNameOriginal, const nsACString& value, bool response);
// Find the location of the given header value, or null if none exists. constchar* FindHeaderValue(const nsHttpAtom& header, constchar* value) const { return nsHttp::FindToken(PeekHeader(header), value, HTTP_HEADER_VALUE_SEPS);
}
// Determine if the given header value exists. bool HasHeaderValue(const nsHttpAtom& header, constchar* value) const { return FindHeaderValue(header, value) != nullptr;
}
private: // LookupEntry function will never return eVarietyResponseNetOriginal. // It will ignore original headers from the network.
int32_t LookupEntry(const nsHttpAtom& header, const nsEntry**) const;
int32_t LookupEntry(const nsHttpAtom& header, nsEntry**);
[[nodiscard]] nsresult MergeHeader(const nsHttpAtom& header, nsEntry* entry, const nsACString& value,
HeaderVariety variety);
[[nodiscard]] nsresult SetHeader_internal(const nsHttpAtom& header, const nsACString& headerName, const nsACString& value,
HeaderVariety variety);
// Header cannot be merged: only one value possible bool IsSingletonHeader(const nsHttpAtom& header); // Header cannot be merged, and subsequent values should be ignored bool IsIgnoreMultipleHeader(const nsHttpAtom& header);
// Subset of singleton headers: should never see multiple, different // instances of these, else something fishy may be going on (like CLRF // injection) bool IsSuspectDuplicateHeader(const nsHttpAtom& header);
// Removes duplicate header values entries // Will return unmodified header value if the header values contains // non-duplicate entries void RemoveDuplicateHeaderValues(const nsACString& aHeaderValue,
nsACString& aResult);
// All members must be copy-constructable and assignable
CopyableTArray<nsEntry> mHeaders;
// These are headers for which, in the presence of multiple values, we only // consider the first. inlinebool nsHttpHeaderArray::IsIgnoreMultipleHeader( const nsHttpAtom& header) { // https://tools.ietf.org/html/rfc6797#section-8: // // If a UA receives more than one STS header field in an HTTP // response message over secure transport, then the UA MUST process // only the first such header field. return header == nsHttp::Strict_Transport_Security;
}
// x-frame-options having an empty header value still has an effect so we make // sure that we retain encountering it
nsCString newValue = entry->value; if (!newValue.IsEmpty() || header == nsHttp::X_Frame_Options) { // Append the new value to the existing value if (header == nsHttp::Set_Cookie || header == nsHttp::WWW_Authenticate ||
header == nsHttp::Proxy_Authenticate) { // Special case these headers and use a newline delimiter to // delimit the values from one another as commas may appear // in the values of these headers contrary to what the spec says.
newValue.Append('\n');
} else { // Delimit each value from the others using a comma (per HTTP spec)
newValue.AppendLiteral(", ");
}
}
newValue.Append(value); if (entry->variety == eVarietyResponseNetOriginalAndResponse) {
MOZ_ASSERT(variety == eVarietyResponse);
entry->variety = eVarietyResponseNetOriginal; // Copy entry->headerNameOriginal because in SetHeader_internal we are going // to a new one and a realocation can happen.
nsCString headerNameOriginal = entry->headerNameOriginal;
nsresult rv = SetHeader_internal(header, headerNameOriginal, newValue,
eVarietyResponse); if (NS_FAILED(rv)) { return rv;
}
} else {
entry->value = newValue;
entry->variety = variety;
} return NS_OK;
}
MOZ_ASSERT(!retval || IsSingletonHeader(header), "Only non-mergeable headers should be in this list\n");
return retval;
}
inlinevoid nsHttpHeaderArray::RemoveDuplicateHeaderValues( const nsACString& aHeaderValue, nsACString& aResult) {
mozilla::Maybe<nsAutoCString> result; for (const nsACString& token :
nsCCharSeparatedTokenizer(aHeaderValue, ',').ToRange()) { if (result.isNothing()) { // assign the first value
result.emplace(token); continue;
} if (*result != token) { // non-identical header values. Do not change the header values
result.reset(); break;
}
}
if (result.isSome()) {
aResult = *result;
} else { // either header values do not have multiple values or // has unequal multiple values // for both the cases restore the original header value
aResult = aHeaderValue;
}
}
} // namespace net
} // namespace mozilla
#endif
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.