Bug 1623755 - Fix http version parsing. r=mayhemer

Differential Revision: https://phabricator.services.mozilla.com/D67549

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Dragana Damjanovic 2020-03-23 18:38:45 +00:00
parent dcf75e7f03
commit f5a03c008e
4 changed files with 39 additions and 19 deletions

View File

@ -544,7 +544,7 @@ nsresult Http2Decompressor::OutputHeader(const nsACString& name,
// Status comes first
if (name.EqualsLiteral(":status")) {
nsAutoCString status(NS_LITERAL_CSTRING("HTTP/2.0 "));
nsAutoCString status(NS_LITERAL_CSTRING("HTTP/2 "));
status.Append(value);
status.AppendLiteral("\r\n");
mOutput->Insert(status, 0);

View File

@ -1078,9 +1078,10 @@ void nsHttpResponseHead::ParseVersion(const char* str) {
LOG(("nsHttpResponseHead::ParseVersion [version=%s]\n", str));
Tokenizer t(str, nullptr, "");
// make sure we have HTTP at the beginning
if (PL_strncasecmp(str, "HTTP", 4) != 0) {
if (PL_strncasecmp(str, "ICY ", 4) == 0) {
if (!t.CheckWord("HTTP")) {
if (t.CheckWord("ICY ")) {
// ShoutCast ICY is HTTP/1.0-like. Assume it is HTTP/1.0.
LOG(("Treating ICY as HTTP 1.0\n"));
mVersion = HttpVersion::v1_0;
@ -1090,9 +1091,8 @@ void nsHttpResponseHead::ParseVersion(const char* str) {
mVersion = HttpVersion::v0_9;
return;
}
str += 4;
if (*str != '/') {
if (!t.CheckChar('/')) {
LOG(("server did not send a version number; assuming HTTP/1.0\n"));
// NCSA/1.5.2 has a bug in which it fails to send a version number
// if the request version is HTTP/1.1, so we fall back on HTTP/1.0
@ -1100,23 +1100,43 @@ void nsHttpResponseHead::ParseVersion(const char* str) {
return;
}
char* p = PL_strchr(str, '.');
if (p == nullptr) {
uint32_t major;
if (!t.ReadInteger(&major)) {
LOG(("server did not send a correct version number; assuming HTTP/1.0"));
mVersion = HttpVersion::v1_0;
return;
}
if (major == 3) {
mVersion = HttpVersion::v3_0;
return;
}
if (major == 2) {
mVersion = HttpVersion::v2_0;
return;
}
if (major != 1) {
LOG(("server did not send a correct version number; assuming HTTP/1.0"));
mVersion = HttpVersion::v1_0;
return;
}
if (!t.CheckChar('.')) {
LOG(("mal-formed server version; assuming HTTP/1.0\n"));
mVersion = HttpVersion::v1_0;
return;
}
++p; // let b point to the minor version
uint32_t minor;
if (!t.ReadInteger(&minor)) {
LOG(("server did not send a correct version number; assuming HTTP/1.0"));
mVersion = HttpVersion::v1_0;
return;
}
int major = atoi(str + 1);
int minor = atoi(p);
if ((major > 3) || ((major == 3) && (minor >= 0))) {
mVersion = HttpVersion::v3_0;
} else if ((major > 2) || ((major == 2) && (minor >= 0))) {
mVersion = HttpVersion::v2_0;
} else if ((major == 1) && (minor >= 1)) {
if (minor >= 1) {
// at least HTTP/1.1
mVersion = HttpVersion::v1_1;
} else {

View File

@ -1400,9 +1400,9 @@ char* nsHttpTransaction::LocateHttpStart(char* buf, uint32_t len,
static const char HTTPHeader[] = "HTTP/1.";
static const uint32_t HTTPHeaderLen = sizeof(HTTPHeader) - 1;
static const char HTTP2Header[] = "HTTP/2.0";
static const char HTTP2Header[] = "HTTP/2";
static const uint32_t HTTP2HeaderLen = sizeof(HTTP2Header) - 1;
static const char HTTP3Header[] = "HTTP/3.0";
static const char HTTP3Header[] = "HTTP/3";
static const uint32_t HTTP3HeaderLen = sizeof(HTTP3Header) - 1;
// ShoutCast ICY is treated as HTTP/1.0
static const char ICYHeader[] = "ICY ";

View File

@ -477,7 +477,7 @@ pub extern "C" fn neqo_http3conn_read_response_headers(
if status_element.len() != 1 {
return NS_ERROR_ILLEGAL_VALUE;
}
headers.extend_from_slice("HTTP/3.0 ".as_bytes());
headers.extend_from_slice("HTTP/3 ".as_bytes());
headers.extend_from_slice(status_element[0].1.as_bytes());
headers.extend_from_slice("\r\n".as_bytes());