Repository: conan-io/conan

Issue:
[bug] Bad UX when trying to fetch deactivated Artifactory
### Describe the bug

When trying to install a new package, and the remote is Cloud Artifactory, and it's deactivated, Conan client returns not optimal information.

For Conan 1.64.0, the Artifactory page returns an html text, and the Conan client only forwards the html content as error, but does not add clear information about remote not available.

For Conan 2.2.3, the Conan client returns a message not corresponding to the error: `The remote doesn't support revisions`. But there is no remote, actually.

#### Environment Details

OS: OSX
Conan Version: 1.64.0 and 2.2.3
Arch: M1

### How to reproduce it

#### Conan 1.64.0

```
conan remote add bincrafters https://bincrafters.jfrog.io/artifactory/api/conan/public-conan  
conan install -r bincrafters antlr4-cppruntime/4.13.1@                                                                                                                                                     

WARN: *** Conan 1 is legacy and on a deprecation path ***
WARN: *** Please upgrade to Conan 2 ***
Configuration:
[settings]
arch=armv8
arch_build=armv8
build_type=Release
compiler=apple-clang
compiler.libcxx=libc++
compiler.version=15
os=Macos
os_build=Macos
[options]
[build_requires]
[env]
[conf]
tools.system.package_manager:mode=install

antlr4-cppruntime/4.13.1: ERROR: Error downloading binary package: 'antlr4-cppruntime/4.13.1:c6a7b978c36bfbdf05646cef650d3b8d3c8bea46'
ERROR: <!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/favicon.ico"><title>JFrog Landing</title><link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700,800&display=swap" rel="stylesheet"><script>VERSION = "2024.2.251";
      API_PROXY_URL = "https://landing-api.jfrog.com/api/v1/";
      API_PROXY_URL_V2 = "https://landing-api.jfrog.com/api/v2/";
      MYJFROG_UI_URL = "https://my.jfrog.com";
      COOKIES_DOMAIN = "jfrog.com";
      AWS_PROX_URL = "https://aws.amazon.com/marketplace/pp/B0819LTNJR";
      DRIFT_EMBED_ID = "gebxvrgwfyr7";
      GOOGLE_CLIENT_ID = "527996402582-i2kl20du99gjd8dnr3cce1a8ao0sgou7.apps.googleusercontent.com";
      PLATFORM_DOMAIN = "jfrog.io";
      CONNECT_DOMAIN = "https://connect.jfrog.io";
      ENABLE_GCP_PRIVATE_LINK = "true";
      HEAP_PROJECT_ID = "1702671756";
      HEAP_ALLOWED_URLS = "https://landing.jfrog.com/mp-unified/";
      GITHUB_CLIENT_ID = "83db76bbde6d1d9c7140";
      GITHUB_SSO_REDIRECT_URL = "https://landing.jfrog.com/register/STEP_PLACEHOLDER";
      RATE_PLAN_ID_PRO_MONTHLY= "8a12862986e9fbda01870499deb37044";
      RATE_PLAN_ID_ENT_X_MONTHLY= "8a1290f186ea14aa0187048fc33e5334";
      MAINTENANCE_MODE= "false";</script><script>if (window.MAINTENANCE_MODE === "true" && window.location.href.indexOf("maintenance") === -1) {
        window.location.href = "/maintenance";
      }</script><script>MYJFROG_STATE = {};</script><script>(function(w, d, s, l, i) {
        w[l] = w[l] || [];
        w[l].push({ "gtm.start": new Date().getTime(), event: "gtm.js" });
        var f = d.getElementsByTagName(s)[0],
          j = d.createElement(s),
          dl = l != "dataLayer" ? "&l=" + l : "";
        j.async = true;
        j.src = "https://www.googletagmanager.com/gtm.js?id=" + i + dl;
        f.parentNode.insertBefore(j, f);
      })(window, document, "script", "dataLayer", "GTM-N3P9XVQ");</script><script>(function(w, d, s, l, i) {
        w[l] = w[l] || [];
        w[l].push({ "gtm.start": new Date().getTime(), event: "gtm.js" });
        var f = d.getElementsByTagName(s)[0],
          j = d.createElement(s),
          dl = l != "dataLayer" ? "&l=" + l : "";
        j.async = true;
        j.src = "https://www.googletagmanager.com/gtm.js?id=" + i + dl;
        f.parentNode.insertBefore(j, f);
      })(window, document, "script", "dataLayer", "GTM-T6MF8M");</script><script src="https://accounts.google.com/gsi/client" async defer></script><script>(function() {
        var didInit = false;
        function initMunchkin() {
          if (didInit === false) {
            didInit = true;
            Munchkin.init("256-FNZ-187");
          }
        }
        var s = document.createElement("script");
        s.type = "text/javascript";
        s.async = true;
        s.src = "//munchkin.marketo.net/munchkin.js";
        s.onreadystatechange = function () {
          if (this.readyState === "complete" || this.readyState === "loaded") {
            initMunchkin();
          }
        };
        s.onload = initMunchkin;
        document.getElementsByTagName("head")[0].appendChild(s);
      })();</script><script>const currentUrl = window.location.href;
      const heapAllowedUrls = HEAP_ALLOWED_URLS;
      let enableHeap = false;
      const urls = heapAllowedUrls.split(",");
      for(const allowedUrl of urls){
        if(allowedUrl && currentUrl.indexOf(allowedUrl)>-1){
          enableHeap = true;
        }
      }

      if (enableHeap) {
        window.heap = window.heap || [], heap.load = function (e, t) {
          window.heap.appid = e, window.heap.config = t = t || {};
          var r = document.createElement("script");
          r.type = "text/javascript", r.async = !0, r.src = "https://cdn.heapanalytics.com/js/heap-" + e + ".js";
          var a = document.getElementsByTagName("script")[0];
          a.parentNode.insertBefore(r, a);
          for (var n = function (e) {
            return function () {
              heap.push([e].concat(Array.prototype.slice.call(arguments, 0)))
            }
          }, p = ["addEventProperties", "addUserProperties", "clearEventProperties", "identify", "resetIdentity", "removeEventProperty", "setEventProperties", "track", "unsetEventProperty"], o = 0; o < p.length; o++) heap[p[o]] = n(p[o])
        };

        heap.load("1702671756");
      }</script><link href="/css/chunk-04677092.1a354d09.css" rel="prefetch"><link href="/css/chunk-0513e1c1.0bd40812.css" rel="prefetch"><link href="/css/chunk-0920391f.bd663e08.css" rel="prefetch"><link href="/css/chunk-1068f83c.0a542980.css" rel="prefetch"><link href="/css/chunk-12b6b26f.95b938ae.css" rel="prefetch"><link href="/css/chunk-148b227a.1a354d09.css" rel="prefetch"><link href="/css/chunk-1757042f.1f165cbb.css" rel="prefetch"><link href="/css/chunk-1a015bbd.5b3c826f.css" rel="prefetch"><link href="/css/chunk-1ff64d98.3798d290.css" rel="prefetch"><link href="/css/chunk-2893fe67.2987d70c.css" rel="prefetch"><link href="/css/chunk-2c185c30.ac66e9b1.css" rel="prefetch"><link href="/css/chunk-317395a4.1890e70a.css" rel="prefetch"><link href="/css/chunk-31da8e23.f91fd2df.css" rel="prefetch"><link href="/css/chunk-33d9a224.5bc476bc.css" rel="prefetch"><link href="/css/chunk-3420a2c9.6b5c42f5.css" rel="prefetch"><link href="/css/chunk-381827b0.81b19452.css" rel="prefetch"><link href="/css/chunk-39618514.1f9e29b5.css" rel="prefetch"><link href="/css/chunk-3c564152.03291ac0.css" rel="prefetch"><link href="/css/chunk-3ce4f4ad.0b152cec.css" rel="prefetch"><link href="/css/chunk-3d58e4c9.00bd86a6.css" rel="prefetch"><link href="/css/chunk-4746d5a8.31f54e92.css" rel="prefetch"><link href="/css/chunk-4a4253d3.04bb01f9.css" rel="prefetch"><link href="/css/chunk-4b52d6f9.48d9dedf.css" rel="prefetch"><link href="/css/chunk-50de8675.9d2899f2.css" rel="prefetch"><link href="/css/chunk-50f50b53.b29ac503.css" rel="prefetch"><link href="/css/chunk-5373bc52.e621a177.css" rel="prefetch"><link href="/css/chunk-54b2cb72.7e85bc6f.css" rel="prefetch"><link href="/css/chunk-568d7eca.2d7f5384.css" rel="prefetch"><link href="/css/chunk-58b69de0.4edc0677.css" rel="prefetch"><link href="/css/chunk-5992bc6f.7d2788b3.css" rel="prefetch"><link href="/css/chunk-5b7729f7.2f0e820a.css" rel="prefetch"><link href="/css/chunk-5f676ef6.a0165a89.css" rel="prefetch"><link href="/css/chunk-611fed26.8094c7fa.css" rel="prefetch"><link href="/css/chunk-62250f32.d4a113a2.css" rel="prefetch"><link href="/css/chunk-62a7dd00.a0cdf461.css" rel="prefetch"><link href="/css/chunk-67296aa6.3ffe749a.css" rel="prefetch"><link href="/css/chunk-6b09c278.1d5d32c1.css" rel="prefetch"><link href="/css/chunk-7c731679.348194d7.css" rel="prefetch"><link href="/css/chunk-7ec8e372.87773602.css" rel="prefetch"><link href="/css/chunk-8aae8b36.7d2cd02e.css" rel="prefetch"><link href="/css/chunk-91fa9824.069d8018.css" rel="prefetch"><link href="/css/chunk-a8a61f36.677a2402.css" rel="prefetch"><link href="/css/chunk-aafdb71e.f14be58a.css" rel="prefetch"><link href="/css/chunk-b4abecc2.a326e93a.css" rel="prefetch"><link href="/css/chunk-ce1225f8.e88302cb.css" rel="prefetch"><link href="/css/chunk-dc2cb30e.759abff0.css" rel="prefetch"><link href="/css/chunk-f6dbd184.2c728934.css" rel="prefetch"><link href="/css/chunk-f7c81e10.8edf82e0.css" rel="prefetch"><link href="/js/chunk-04677092.346a1464.js" rel="prefetch"><link href="/js/chunk-0513e1c1.26915696.js" rel="prefetch"><link href="/js/chunk-0920391f.522b8f76.js" rel="prefetch"><link href="/js/chunk-1068f83c.ebe2ae83.js" rel="prefetch"><link href="/js/chunk-12b6b26f.c8635c06.js" rel="prefetch"><link href="/js/chunk-148b227a.e4e4a54e.js" rel="prefetch"><link href="/js/chunk-1757042f.618d7203.js" rel="prefetch"><link href="/js/chunk-1a015bbd.f04583fa.js" rel="prefetch"><link href="/js/chunk-1bb05a92.cce08d18.js" rel="prefetch"><link href="/js/chunk-1ff64d98.b309c15b.js" rel="prefetch"><link href="/js/chunk-2893fe67.7d427193.js" rel="prefetch"><link href="/js/chunk-2c185c30.68dc1c90.js" rel="prefetch"><link href="/js/chunk-2d0b2916.8235638f.js" rel="prefetch"><link href="/js/chunk-2d0ddbee.d24f4ae0.js" rel="prefetch"><link href="/js/chunk-2d208668.514f22c6.js" rel="prefetch"><link href="/js/chunk-2d20f68c.317cae83.js" rel="prefetch"><link href="/js/chunk-2d230855.8954a60f.js" rel="prefetch"><link href="/js/chunk-2d230df6.6044258f.js" rel="prefetch"><link href="/js/chunk-317395a4.37583959.js" rel="prefetch"><link href="/js/chunk-31da8e23.1a75da5b.js" rel="prefetch"><link href="/js/chunk-33d9a224.75a183e3.js" rel="prefetch"><link href="/js/chunk-3420a2c9.9a984d60.js" rel="prefetch"><link href="/js/chunk-381827b0.975d2ebd.js" rel="prefetch"><link href="/js/chunk-39618514.be39e84f.js" rel="prefetch"><link href="/js/chunk-3c564152.6338dd67.js" rel="prefetch"><link href="/js/chunk-3ce4f4ad.1423eabd.js" rel="prefetch"><link href="/js/chunk-3d58e4c9.eebd4e15.js" rel="prefetch"><link href="/js/chunk-4746d5a8.fdc679dd.js" rel="prefetch"><link href="/js/chunk-4a4253d3.bf56dd44.js" rel="prefetch"><link href="/js/chunk-4b52d6f9.fe48c922.js" rel="prefetch"><link href="/js/chunk-50de8675.c3c6b54e.js" rel="prefetch"><link href="/js/chunk-50f50b53.b1e3ee67.js" rel="prefetch"><link href="/js/chunk-5373bc52.218474a6.js" rel="prefetch"><link href="/js/chunk-54b2cb72.6370867a.js" rel="prefetch"><link href="/js/chunk-568d7eca.66f26f0e.js" rel="prefetch"><link href="/js/chunk-58b69de0.1d0345cd.js" rel="prefetch"><link href="/js/chunk-5992bc6f.44cb180b.js" rel="prefetch"><link href="/js/chunk-5b7729f7.05d0fd27.js" rel="prefetch"><link href="/js/chunk-5f676ef6.b012180a.js" rel="prefetch"><link href="/js/chunk-611fed26.46b435dd.js" rel="prefetch"><link href="/js/chunk-62250f32.f64ca8ef.js" rel="prefetch"><link href="/js/chunk-62a7dd00.56b6d3d6.js" rel="prefetch"><link href="/js/chunk-67296aa6.9f77640d.js" rel="prefetch"><link href="/js/chunk-6b09c278.4f0eaf3e.js" rel="prefetch"><link href="/js/chunk-7c731679.56327901.js" rel="prefetch"><link href="/js/chunk-7ec8e372.698151ce.js" rel="prefetch"><link href="/js/chunk-8aae8b36.c04113b3.js" rel="prefetch"><link href="/js/chunk-91fa9824.96854313.js" rel="prefetch"><link href="/js/chunk-a8a61f36.fccaf1e0.js" rel="prefetch"><link href="/js/chunk-aafdb71e.6f7e1612.js" rel="prefetch"><link href="/js/chunk-b4abecc2.50f250f5.js" rel="prefetch"><link href="/js/chunk-ce1225f8.e76625a2.js" rel="prefetch"><link href="/js/chunk-dc2cb30e.a074ed55.js" rel="prefetch"><link href="/js/chunk-f6dbd184.3b41dc43.js" rel="prefetch"><link href="/js/chunk-f7c81e10.4da03f12.js" rel="prefetch"><link href="/css/app.d0bffb53.css" rel="preload" as="style"><link href="/css/chunk-vendors.8d0ab741.css" rel="preload" as="style"><link href="/js/app.91f5ee66.js" rel="preload" as="script"><link href="/js/chunk-vendors.b34998fb.js" rel="preload" as="script"><link href="/css/chunk-vendors.8d0ab741.css" rel="stylesheet"><link href="/css/app.d0bffb53.css" rel="stylesheet"></head><body><noscript><strong>MyJFrog doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-N3P9XVQ" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript><div id="app"></div><script src="//sec.webeyez.com/js/wDv55PKmTtpCTH14WWzDXw2yJ3Gz/wzbody.js" async></script><script src="/js/chunk-vendors.b34998fb.js"></script><script src="/js/app.91f5ee66.js"></script></body></html>

Response from remote is not json, but 'text/html; charset=utf-8'. [Remote: bincrafters]
```


#### Conan 2.2.3

```
conan remote add bincrafters https://bincrafters.jfrog.io/artifactory/api/conan/public-conan  
conan install -r bincrafters --requires=tree-gen/1.0.7                                                                                                                                                     
======== Input profiles ========
Profile host:
[settings]
arch=armv8
build_type=Release
compiler=apple-clang
compiler.cppstd=17
compiler.libcxx=libc++
compiler.version=15
os=Macos

Profile build:
[settings]
arch=armv8
build_type=Release
compiler=apple-clang
compiler.cppstd=17
compiler.libcxx=libc++
compiler.version=15
os=Macos


======== Computing dependency graph ========
tree-gen/1.0.7: Not found in local cache, looking in remotes...
tree-gen/1.0.7: Checking remote: bincrafters
Graph root
    cli
ERROR: Package 'tree-gen/1.0.7' not resolved: The remote doesn't support revisions. Conan 2.0 is no longer compatible with remotes that don't accept revisions.. [Remote: bincrafters].
```



Discussion:

Patch:
diff --git a/conans/client/rest/rest_client_common.py b/conans/client/rest/rest_client_common.py
index b0956c2ce3f..9a3f76243b2 100644
--- a/conans/client/rest/rest_client_common.py
+++ b/conans/client/rest/rest_client_common.py
@@ -142,11 +142,14 @@ def server_capabilities(self, user=None, password=None):
             auth = self.auth
         ret = self.requester.get(url, auth=auth, headers=self.custom_headers, verify=self.verify_ssl)
 
-        server_capabilities = ret.headers.get('X-Conan-Server-Capabilities', "")
+        server_capabilities = ret.headers.get('X-Conan-Server-Capabilities')
         if not server_capabilities and not ret.ok:
             # Old Artifactory might return 401/403 without capabilities, we don't want
             # to cache them #5687, so raise the exception and force authentication
             raise get_exception_from_error(ret.status_code)(response_to_str(ret))
+        if server_capabilities is None:
+            # Some servers returning 200-ok, even if not valid repo
+            raise ConanException(f"Remote {self.remote_url} doesn't seem like a valid Conan remote")
 
         return [cap.strip() for cap in server_capabilities.split(",") if cap]
 


Test patch:
diff --git a/conans/test/integration/command/upload/upload_test.py b/conans/test/integration/command/upload/upload_test.py
index 7a17a61aa37..eda0c069573 100644
--- a/conans/test/integration/command/upload/upload_test.py
+++ b/conans/test/integration/command/upload/upload_test.py
@@ -8,6 +8,7 @@
 import pytest
 import requests
 from mock import patch
+from requests import Response
 
 from conans.errors import ConanException
 from conans.model.package_ref import PkgReference
@@ -485,6 +486,21 @@ def get(self, url, **kwargs):
         client.run("upload hello0/1.2.1@user/testing -r default")
         assert "Uploading recipe 'hello0/1.2.1@user/testing" in client.out
 
+    def test_server_returns_200_ok(self):
+        # https://github.com/conan-io/conan/issues/16104
+        # If server returns 200 ok, without headers, it raises an error
+        class MyHttpRequester(TestRequester):
+            def get(self, _, **kwargs):
+                resp = Response()
+                resp.status_code = 200
+                return resp
+
+        client = TestClient(requester_class=MyHttpRequester, servers={"default": TestServer()})
+        client.save({"conanfile.py": GenConanfile("hello0", "1.2.1")})
+        client.run("create . ")
+        client.run("upload * -c -r default", assert_error=True)
+        assert "doesn't seem like a valid Conan remote" in client.out
+
 
 def test_upload_only_without_user_channel():
     """