src: Move http_parser_url related functions to util
This commit is contained in:
parent
ddf6162528
commit
227a48cea1
142
src/nghttp.cc
142
src/nghttp.cc
|
@ -136,105 +136,6 @@ struct RequestStat {
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
|
||||||
bool has_uri_field(const http_parser_url &u, http_parser_url_fields field)
|
|
||||||
{
|
|
||||||
return u.field_set & (1 << field);
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
bool fieldeq(const char *uri1, const http_parser_url &u1,
|
|
||||||
const char *uri2, const http_parser_url &u2,
|
|
||||||
http_parser_url_fields field)
|
|
||||||
{
|
|
||||||
if(!has_uri_field(u1, field)) {
|
|
||||||
if(!has_uri_field(u2, field)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if(!has_uri_field(u2, field)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(u1.field_data[field].len != u2.field_data[field].len) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return memcmp(uri1+u1.field_data[field].off,
|
|
||||||
uri2+u2.field_data[field].off,
|
|
||||||
u1.field_data[field].len) == 0;
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
bool fieldeq(const char *uri, const http_parser_url &u,
|
|
||||||
http_parser_url_fields field,
|
|
||||||
const char *t)
|
|
||||||
{
|
|
||||||
if(!has_uri_field(u, field)) {
|
|
||||||
if(!t[0]) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if(!t[0]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
int i, len = u.field_data[field].len;
|
|
||||||
const char *p = uri+u.field_data[field].off;
|
|
||||||
for(i = 0; i < len && t[i] && p[i] == t[i]; ++i);
|
|
||||||
return i == len && !t[i];
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
uint16_t get_default_port(const char *uri, const http_parser_url &u)
|
|
||||||
{
|
|
||||||
if(fieldeq(uri, u, UF_SCHEMA, "https")) {
|
|
||||||
return 443;
|
|
||||||
} else if(fieldeq(uri, u, UF_SCHEMA, "http")) {
|
|
||||||
return 80;
|
|
||||||
} else {
|
|
||||||
return 443;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
std::string get_uri_field(const char *uri, const http_parser_url &u,
|
|
||||||
http_parser_url_fields field)
|
|
||||||
{
|
|
||||||
if(has_uri_field(u, field)) {
|
|
||||||
return std::string(uri+u.field_data[field].off,
|
|
||||||
u.field_data[field].len);
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
bool porteq(const char *uri1, const http_parser_url &u1,
|
|
||||||
const char *uri2, const http_parser_url &u2)
|
|
||||||
{
|
|
||||||
uint16_t port1, port2;
|
|
||||||
port1 = has_uri_field(u1, UF_PORT) ? u1.port : get_default_port(uri1, u1);
|
|
||||||
port2 = has_uri_field(u2, UF_PORT) ? u2.port : get_default_port(uri2, u2);
|
|
||||||
return port1 == port2;
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
void write_uri_field(std::ostream& o,
|
|
||||||
const char *uri, const http_parser_url &u,
|
|
||||||
http_parser_url_fields field)
|
|
||||||
{
|
|
||||||
if(has_uri_field(u, field)) {
|
|
||||||
o.write(uri+u.field_data[field].off, u.field_data[field].len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
std::string strip_fragment(const char *raw_uri)
|
std::string strip_fragment(const char *raw_uri)
|
||||||
{
|
{
|
||||||
|
@ -308,9 +209,9 @@ struct Request {
|
||||||
|
|
||||||
std::string make_reqpath() const
|
std::string make_reqpath() const
|
||||||
{
|
{
|
||||||
std::string path = has_uri_field(u, UF_PATH) ?
|
std::string path = util::has_uri_field(u, UF_PATH) ?
|
||||||
get_uri_field(uri.c_str(), u, UF_PATH) : "/";
|
util::get_uri_field(uri.c_str(), u, UF_PATH) : "/";
|
||||||
if(has_uri_field(u, UF_QUERY)) {
|
if(util::has_uri_field(u, UF_QUERY)) {
|
||||||
path += "?";
|
path += "?";
|
||||||
path.append(uri.c_str()+u.field_data[UF_QUERY].off,
|
path.append(uri.c_str()+u.field_data[UF_QUERY].off,
|
||||||
u.field_data[UF_QUERY].len);
|
u.field_data[UF_QUERY].len);
|
||||||
|
@ -320,7 +221,7 @@ struct Request {
|
||||||
|
|
||||||
bool is_ipv6_literal_addr() const
|
bool is_ipv6_literal_addr() const
|
||||||
{
|
{
|
||||||
if(has_uri_field(u, UF_HOST)) {
|
if(util::has_uri_field(u, UF_HOST)) {
|
||||||
return memchr(uri.c_str()+u.field_data[UF_HOST].off, ':',
|
return memchr(uri.c_str()+u.field_data[UF_HOST].off, ':',
|
||||||
u.field_data[UF_HOST].len);
|
u.field_data[UF_HOST].len);
|
||||||
} else {
|
} else {
|
||||||
|
@ -844,18 +745,19 @@ struct HttpClient {
|
||||||
if(reqvec.empty()) {
|
if(reqvec.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
scheme = get_uri_field(reqvec[0]->uri.c_str(), reqvec[0]->u, UF_SCHEMA);
|
scheme = util::get_uri_field(reqvec[0]->uri.c_str(), reqvec[0]->u,
|
||||||
|
UF_SCHEMA);
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
if(reqvec[0]->is_ipv6_literal_addr()) {
|
if(reqvec[0]->is_ipv6_literal_addr()) {
|
||||||
ss << "[";
|
ss << "[";
|
||||||
write_uri_field(ss, reqvec[0]->uri.c_str(), reqvec[0]->u, UF_HOST);
|
util::write_uri_field(ss, reqvec[0]->uri.c_str(), reqvec[0]->u, UF_HOST);
|
||||||
ss << "]";
|
ss << "]";
|
||||||
} else {
|
} else {
|
||||||
write_uri_field(ss, reqvec[0]->uri.c_str(), reqvec[0]->u, UF_HOST);
|
util::write_uri_field(ss, reqvec[0]->uri.c_str(), reqvec[0]->u, UF_HOST);
|
||||||
}
|
}
|
||||||
if(has_uri_field(reqvec[0]->u, UF_PORT) &&
|
if(util::has_uri_field(reqvec[0]->u, UF_PORT) &&
|
||||||
reqvec[0]->u.port != get_default_port(reqvec[0]->uri.c_str(),
|
reqvec[0]->u.port != util::get_default_port(reqvec[0]->uri.c_str(),
|
||||||
reqvec[0]->u)) {
|
reqvec[0]->u)) {
|
||||||
ss << ":" << reqvec[0]->u.port;
|
ss << ":" << reqvec[0]->u.port;
|
||||||
}
|
}
|
||||||
hostport = ss.str();
|
hostport = ss.str();
|
||||||
|
@ -937,7 +839,7 @@ int submit_request
|
||||||
Request *req)
|
Request *req)
|
||||||
{
|
{
|
||||||
auto path = req->make_reqpath();
|
auto path = req->make_reqpath();
|
||||||
auto scheme = get_uri_field(req->uri.c_str(), req->u, UF_SCHEMA);
|
auto scheme = util::get_uri_field(req->uri.c_str(), req->u, UF_SCHEMA);
|
||||||
auto build_headers = std::vector<std::pair<std::string, std::string>>
|
auto build_headers = std::vector<std::pair<std::string, std::string>>
|
||||||
{{":method", req->data_prd ? "POST" : "GET"},
|
{{":method", req->data_prd ? "POST" : "GET"},
|
||||||
{":path", path},
|
{":path", path},
|
||||||
|
@ -1016,9 +918,9 @@ void update_html_parser(HttpClient *client, Request *req,
|
||||||
auto uri = strip_fragment(p.first.c_str());
|
auto uri = strip_fragment(p.first.c_str());
|
||||||
http_parser_url u;
|
http_parser_url u;
|
||||||
if(http_parser_parse_url(uri.c_str(), uri.size(), 0, &u) == 0 &&
|
if(http_parser_parse_url(uri.c_str(), uri.size(), 0, &u) == 0 &&
|
||||||
fieldeq(uri.c_str(), u, req->uri.c_str(), req->u, UF_SCHEMA) &&
|
util::fieldeq(uri.c_str(), u, req->uri.c_str(), req->u, UF_SCHEMA) &&
|
||||||
fieldeq(uri.c_str(), u, req->uri.c_str(), req->u, UF_HOST) &&
|
util::fieldeq(uri.c_str(), u, req->uri.c_str(), req->u, UF_HOST) &&
|
||||||
porteq(uri.c_str(), u, req->uri.c_str(), req->u)) {
|
util::porteq(uri.c_str(), u, req->uri.c_str(), req->u)) {
|
||||||
int32_t pri = adjust_pri(req->pri, p.second);
|
int32_t pri = adjust_pri(req->pri, p.second);
|
||||||
// No POST data for assets
|
// No POST data for assets
|
||||||
if ( client->add_request(uri, nullptr, 0, pri, req->level+1) ) {
|
if ( client->add_request(uri, nullptr, 0, pri, req->level+1) ) {
|
||||||
|
@ -1682,11 +1584,11 @@ int run(char **uris, int n)
|
||||||
http_parser_url u;
|
http_parser_url u;
|
||||||
auto uri = strip_fragment(uris[i]);
|
auto uri = strip_fragment(uris[i]);
|
||||||
if(http_parser_parse_url(uri.c_str(), uri.size(), 0, &u) == 0 &&
|
if(http_parser_parse_url(uri.c_str(), uri.size(), 0, &u) == 0 &&
|
||||||
has_uri_field(u, UF_SCHEMA)) {
|
util::has_uri_field(u, UF_SCHEMA)) {
|
||||||
uint16_t port = has_uri_field(u, UF_PORT) ?
|
uint16_t port = util::has_uri_field(u, UF_PORT) ?
|
||||||
u.port : get_default_port(uri.c_str(), u);
|
u.port : util::get_default_port(uri.c_str(), u);
|
||||||
if(!fieldeq(uri.c_str(), u, UF_SCHEMA, prev_scheme.c_str()) ||
|
if(!util::fieldeq(uri.c_str(), u, UF_SCHEMA, prev_scheme.c_str()) ||
|
||||||
!fieldeq(uri.c_str(), u, UF_HOST, prev_host.c_str()) ||
|
!util::fieldeq(uri.c_str(), u, UF_HOST, prev_host.c_str()) ||
|
||||||
port != prev_port) {
|
port != prev_port) {
|
||||||
if(!requests.empty()) {
|
if(!requests.empty()) {
|
||||||
if (communicate(prev_scheme, prev_host, prev_port,
|
if (communicate(prev_scheme, prev_host, prev_port,
|
||||||
|
@ -1695,8 +1597,8 @@ int run(char **uris, int n)
|
||||||
}
|
}
|
||||||
requests.clear();
|
requests.clear();
|
||||||
}
|
}
|
||||||
prev_scheme = get_uri_field(uri.c_str(), u, UF_SCHEMA);
|
prev_scheme = util::get_uri_field(uri.c_str(), u, UF_SCHEMA);
|
||||||
prev_host = get_uri_field(uri.c_str(), u, UF_HOST);
|
prev_host = util::get_uri_field(uri.c_str(), u, UF_HOST);
|
||||||
prev_port = port;
|
prev_port = port;
|
||||||
}
|
}
|
||||||
requests.emplace_back(uri, data_fd == -1 ? nullptr : &data_prd,
|
requests.emplace_back(uri, data_fd == -1 ? nullptr : &data_prd,
|
||||||
|
|
87
src/util.cc
87
src/util.cc
|
@ -382,6 +382,93 @@ void show_candidates(const char *unkopt, option *options)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_uri_field(const http_parser_url &u, http_parser_url_fields field)
|
||||||
|
{
|
||||||
|
return u.field_set & (1 << field);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fieldeq(const char *uri1, const http_parser_url &u1,
|
||||||
|
const char *uri2, const http_parser_url &u2,
|
||||||
|
http_parser_url_fields field)
|
||||||
|
{
|
||||||
|
if(!has_uri_field(u1, field)) {
|
||||||
|
if(!has_uri_field(u2, field)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if(!has_uri_field(u2, field)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(u1.field_data[field].len != u2.field_data[field].len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return memcmp(uri1+u1.field_data[field].off,
|
||||||
|
uri2+u2.field_data[field].off,
|
||||||
|
u1.field_data[field].len) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fieldeq(const char *uri, const http_parser_url &u,
|
||||||
|
http_parser_url_fields field,
|
||||||
|
const char *t)
|
||||||
|
{
|
||||||
|
if(!has_uri_field(u, field)) {
|
||||||
|
if(!t[0]) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if(!t[0]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int i, len = u.field_data[field].len;
|
||||||
|
const char *p = uri+u.field_data[field].off;
|
||||||
|
for(i = 0; i < len && t[i] && p[i] == t[i]; ++i);
|
||||||
|
return i == len && !t[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_uri_field(const char *uri, const http_parser_url &u,
|
||||||
|
http_parser_url_fields field)
|
||||||
|
{
|
||||||
|
if(util::has_uri_field(u, field)) {
|
||||||
|
return std::string(uri+u.field_data[field].off,
|
||||||
|
u.field_data[field].len);
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t get_default_port(const char *uri, const http_parser_url &u)
|
||||||
|
{
|
||||||
|
if(util::fieldeq(uri, u, UF_SCHEMA, "https")) {
|
||||||
|
return 443;
|
||||||
|
} else if(util::fieldeq(uri, u, UF_SCHEMA, "http")) {
|
||||||
|
return 80;
|
||||||
|
} else {
|
||||||
|
return 443;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool porteq(const char *uri1, const http_parser_url &u1,
|
||||||
|
const char *uri2, const http_parser_url &u2)
|
||||||
|
{
|
||||||
|
uint16_t port1, port2;
|
||||||
|
port1 = util::has_uri_field(u1, UF_PORT) ?
|
||||||
|
u1.port : get_default_port(uri1, u1);
|
||||||
|
port2 = util::has_uri_field(u2, UF_PORT) ?
|
||||||
|
u2.port : get_default_port(uri2, u2);
|
||||||
|
return port1 == port2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_uri_field(std::ostream& o,
|
||||||
|
const char *uri, const http_parser_url &u,
|
||||||
|
http_parser_url_fields field)
|
||||||
|
{
|
||||||
|
if(util::has_uri_field(u, field)) {
|
||||||
|
o.write(uri+u.field_data[field].off, u.field_data[field].len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|
24
src/util.h
24
src/util.h
|
@ -37,6 +37,8 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "http-parser/http_parser.h"
|
||||||
|
|
||||||
namespace nghttp2 {
|
namespace nghttp2 {
|
||||||
|
|
||||||
namespace util {
|
namespace util {
|
||||||
|
@ -408,6 +410,28 @@ void to_base64(std::string& token68str);
|
||||||
|
|
||||||
void show_candidates(const char *unkopt, option *options);
|
void show_candidates(const char *unkopt, option *options);
|
||||||
|
|
||||||
|
bool has_uri_field(const http_parser_url &u, http_parser_url_fields field);
|
||||||
|
|
||||||
|
bool fieldeq(const char *uri1, const http_parser_url &u1,
|
||||||
|
const char *uri2, const http_parser_url &u2,
|
||||||
|
http_parser_url_fields field);
|
||||||
|
|
||||||
|
bool fieldeq(const char *uri, const http_parser_url &u,
|
||||||
|
http_parser_url_fields field,
|
||||||
|
const char *t);
|
||||||
|
|
||||||
|
std::string get_uri_field(const char *uri, const http_parser_url &u,
|
||||||
|
http_parser_url_fields field);
|
||||||
|
|
||||||
|
uint16_t get_default_port(const char *uri, const http_parser_url &u);
|
||||||
|
|
||||||
|
bool porteq(const char *uri1, const http_parser_url &u1,
|
||||||
|
const char *uri2, const http_parser_url &u2);
|
||||||
|
|
||||||
|
void write_uri_field(std::ostream& o,
|
||||||
|
const char *uri, const http_parser_url &u,
|
||||||
|
http_parser_url_fields field);
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|
Loading…
Reference in New Issue