Skip to content

Commit fc669e3

Browse files
committed
Issue #7749: ensure that request parameters are parsed only once
In WebController, CgiParser::parse is used once in handleRequest, and once in requestDataReceived. requestDataReceived is called repeatedly as uploads come in. This would cause a constant accumulation of duplicate values for parameters, and cause a race condition if the value is being updated while updateResourceProgress is being handled. This is most noticeable when the upload is coming in very fast (e.g. on localhost).
1 parent 5a0bd19 commit fc669e3

File tree

1 file changed

+16
-13
lines changed

1 file changed

+16
-13
lines changed

src/web/CgiParser.C

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,12 @@ void CgiParser::parse(WebRequest& request, ReadOption readOption)
194194

195195
std::string queryString = request.queryString();
196196

197+
LOG_DEBUG("queryString (len=" << len << "): " << queryString);
198+
199+
if (!queryString.empty() && request_->parameters_.empty()) {
200+
Http::Request::parseFormUrlEncoded(queryString, request_->parameters_);
201+
}
202+
197203
// XDomainRequest cannot set a contentType header, we therefore pass it
198204
// as a request parameter
199205
if (readOption != ReadHeadersOnly &&
@@ -222,17 +228,19 @@ void CgiParser::parse(WebRequest& request, ReadOption readOption)
222228

223229
// This is a special Wt feature, I do not think it standard.
224230
// For POST, parameters in url-encoded URL are still parsed.
225-
if (!queryString.empty())
226-
queryString += '&';
227231

228-
queryString += buf;
232+
std::string formQueryString = buf;
229233
delete[] buf;
230-
}
231-
232-
LOG_DEBUG("queryString (len=" << len << "): " << queryString);
233234

234-
if (!queryString.empty())
235-
Http::Request::parseFormUrlEncoded(queryString, request_->parameters_);
235+
LOG_DEBUG("formQueryString (len=" << len << "): " << formQueryString);
236+
if (!formQueryString.empty()) {
237+
Http::Request::parseFormUrlEncoded(formQueryString, request_->parameters_);
238+
}
239+
Http::ParameterMap::const_iterator it = request_->parameters_.find("Wt-params");
240+
if (it != request_->parameters_.end() && it->second.size() == 1) {
241+
Http::Request::parseFormUrlEncoded(it->second[0], request_->parameters_);
242+
}
243+
}
236244

237245
if (readOption != ReadHeadersOnly &&
238246
type && strstr(type, "multipart/form-data") == type) {
@@ -253,11 +261,6 @@ void CgiParser::parse(WebRequest& request, ReadOption readOption)
253261
}
254262
}
255263
}
256-
257-
Http::ParameterMap::const_iterator it = request_->parameters_.find("Wt-params");
258-
if (it != request_->parameters_.end() && it->second.size() == 1) {
259-
Http::Request::parseFormUrlEncoded(it->second[0], request_->parameters_);
260-
}
261264
}
262265

263266
void CgiParser::readMultipartData(WebRequest& request,

0 commit comments

Comments
 (0)