Commit 5d091d04 authored by jan.koester's avatar jan.koester
Browse files

ctor patch

parent 0af85688
Loading
Loading
Loading
Loading
+35 −22
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@

libhttppp::HttpUrl::HttpUrl(){
  _protocol=HTTP;
  _origProtocol=HTTP;
  _port=80;
  _path="/";
}
@@ -64,40 +65,39 @@ libhttppp::HttpUrl::HttpUrl(const std::string& url, bool http3) {
    const char* c_url = url.c_str();
    const char* p = c_url;

    if (http3) {
        _protocol = HttpProtocol::HTTP3;
        _port = 443;
        // Strip scheme prefix before host parsing
        if (url.rfind("https://", 0) == 0) {
            p += 8;
        } else if (url.rfind("http://", 0) == 0) {
            p += 7;
        }
    }
    // Update c_url pointer based on scheme matching
    else if (url.rfind("https://", 0) == 0) { // Using rfind for string prefix check
        _protocol = HTTPS;
    // Detect the scheme as it actually appears in the URL string first --
    // _origProtocol keeps this even when http3 below forces _protocol to
    // HTTP3, so fallback logic downstream can still tell https from http.
    if (url.rfind("https://", 0) == 0) { // Using rfind for string prefix check
        _origProtocol = HTTPS;
        _port = 443;
        p += 8; // Advance pointer past "https://"
    }
    else if (url.rfind("http://", 0) == 0) {
        _protocol = HTTP;
        _origProtocol = HTTP;
        _port = 80;
        p += 7; // Advance pointer past "http://"
    }
    // Note: The "https" and "http" (without ://) checks are less robust but kept for compatibility
    else if (url.rfind("https", 0) == 0) {
        _protocol = HTTPS;
        _origProtocol = HTTPS;
        _port = 443;
    }
    else if (url.rfind("http", 0) == 0) {
        _protocol = HTTP;
        _origProtocol = HTTP;
        _port = 80;
    }
    else {
        exp[HTTPException::Error] << "Httpurl: protocol not supported!";
        throw exp;
    }

    if (http3) {
        _protocol = HttpProtocol::HTTP3;
        _port = 443;
    } else {
        _protocol = _origProtocol;
    }
    _path = "/";

    const char* host_start = p;
@@ -143,6 +143,7 @@ libhttppp::HttpUrl::HttpUrl(const std::string& url, bool http3) {

libhttppp::HttpUrl::HttpUrl(const HttpUrl& src){
  _protocol=src._protocol;
  _origProtocol=src._origProtocol;
  _host=src._host;
  _port=src._port;
  _path=src._path;
@@ -153,6 +154,7 @@ libhttppp::HttpUrl::~HttpUrl(){

void libhttppp::HttpUrl::clear(){
  _protocol=HTTP;
  _origProtocol=HTTP;
  _host.clear();
  _port=80;
  _path="/";
@@ -200,6 +202,10 @@ int libhttppp::HttpUrl::getProtocol() const{
  return _protocol;
}

int libhttppp::HttpUrl::getOriginalProtocol() const{
  return _origProtocol;
}

const std::string & libhttppp::HttpUrl::getHost() const{
  return _host;
}
@@ -225,8 +231,10 @@ libhttppp::HttpClient::HttpClient(const HttpUrl& desturl, int vers, int timeoutS
    try {
      if(vers == 3) {
        if (!tryHttp3First()) {
          // HTTP/3 failed: try HTTP/2 first, then HTTP/1.1.
          if (_url.getProtocol() == HttpUrl::HTTPS) {
          // HTTP/3 failed: try HTTP/2 first, then HTTP/1.1. Must check the
          // URL's original scheme here, not getProtocol() -- that's pinned
          // to HTTP3 for the lifetime of this object once requested above.
          if (_url.getOriginalProtocol() == HttpUrl::HTTPS) {
            bool h2_ok = false;
            try {
              // Internal probe mode: advertise ALPN h2 only.
@@ -314,7 +322,10 @@ void libhttppp::HttpClient::resetConnection(){
  _h2PrefaceSent = false;
  _h2NextStreamId = 1;
  _h2Decoder.reset();
  if (_url.getProtocol() == HttpUrl::HTTP3) {
  // getProtocol() alone isn't enough: it's pinned to HTTP3 for the object's
  // whole lifetime once requested, even after the ctor downgrades _vers on
  // fallback. Only take the QUIC path when HTTP/3 is still what we want.
  if (_url.getProtocol() == HttpUrl::HTTP3 && _vers == 3) {
    auto q = std::make_unique<netplus::quic>();
    q->connect(_url.getHost(), _url.getPort(), false);
    q->setNonBlock();
@@ -335,7 +346,7 @@ void libhttppp::HttpClient::resetConnection(){
    }
    _cltsock = std::move(q);
    _isH2 = false;
  } else if (_url.getProtocol() == HttpUrl::HTTPS) {
  } else if (_url.getOriginalProtocol() == HttpUrl::HTTPS) {
    std::map<std::string, netplus::ssl::CertificateBundle> certs;
    auto sslsock = std::make_unique<netplus::ssl>(certs,-1);

@@ -411,7 +422,9 @@ void libhttppp::HttpClient::reconnect(){
  _h2PrefaceSent = false;
  _h2NextStreamId = 1;
  _h2Decoder.reset();
  if (_url.getProtocol() == HttpUrl::HTTP3) {
  // See resetConnection(): getProtocol() stays HTTP3 for this object's whole
  // lifetime once requested, so it must be paired with _vers == 3 here too.
  if (_url.getProtocol() == HttpUrl::HTTP3 && _vers == 3) {
    auto q = std::make_unique<netplus::quic>();
    q->connect(_url.getHost(), _url.getPort(), false);
    q->setNonBlock();
@@ -432,7 +445,7 @@ void libhttppp::HttpClient::reconnect(){
    }
    _cltsock = std::move(q);
    _isH2 = false;
  } else if(_url.getProtocol() == HttpUrl::HTTPS) {
  } else if(_url.getOriginalProtocol() == HttpUrl::HTTPS) {
    std::map<std::string, netplus::ssl::CertificateBundle> certs;
    auto sslsock = std::make_unique<netplus::ssl>(certs,-1);

+6 −0
Original line number Diff line number Diff line
@@ -69,6 +69,11 @@ namespace libhttppp {
     bool operator<(const HttpUrl& other) const;

     int getProtocol() const;
     // The scheme (HTTP or HTTPS) as it actually appeared in the URL string,
     // unaffected by the http3 ctor flag -- getProtocol() returns HTTP3 once
     // that flag is set, which loses the info needed to fall back correctly
     // when HTTP/3 isn't available.
     int getOriginalProtocol() const;
     const std::string &getHost() const;
     int getPort() const;
     const std::string &getPath() const;
@@ -79,6 +84,7 @@ namespace libhttppp {

  private:
      int            _protocol;
      int            _origProtocol;
      std::string _host;
      int             _port;
      std::string _path;