dirmngr: More binary I/O on Windows for CRLs
[gnupg.git] / dirmngr / ks-action.c
index 285167a..38cd02f 100644 (file)
@@ -16,7 +16,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
@@ -156,13 +156,13 @@ ks_action_search (ctrl_t ctrl, uri_item_t keyservers,
      parallel and merge them.  We also need to decide what to do with
      errors - it might not be the best idea to ignore an error from
      one server and silently continue with another server.  For now we
-     stop at the first error, unless it is GPG_ERR_NO_DATA, in which
-     case we try the next server.  Unfortunately, 'send_requests'
-     broadly maps all kinds of http errors to GPG_ERR_NO_DATA.  */
+     stop at the first error, unless the server responds with '404 Not
+     Found', in which case we try the next server.  */
   for (uri = keyservers; !err && uri; uri = uri->next)
     {
       int is_http = uri->parsed_uri->is_http;
       int is_ldap = 0;
+      unsigned int http_status = 0;
 #if USE_LDAP
       is_ldap = (strcmp (uri->parsed_uri->scheme, "ldap") == 0
                 || strcmp (uri->parsed_uri->scheme, "ldaps") == 0
@@ -177,10 +177,12 @@ ks_action_search (ctrl_t ctrl, uri_item_t keyservers,
          else
 #endif
            {
-             err = ks_hkp_search (ctrl, uri->parsed_uri, patterns->d, &infp);
+             err = ks_hkp_search (ctrl, uri->parsed_uri, patterns->d,
+                                   &infp, &http_status);
            }
 
-          if (err == gpg_error (GPG_ERR_NO_DATA))
+          if (err == gpg_error (GPG_ERR_NO_DATA)
+              && http_status == 404 /* not found */)
             {
               /* No record found.  Clear error and try next server.  */
               err = 0;
@@ -230,7 +232,10 @@ ks_action_get (ctrl_t ctrl, uri_item_t keyservers,
      Need to think about a better strategy.  */
   for (uri = keyservers; !err && uri; uri = uri->next)
     {
-      int is_http = uri->parsed_uri->is_http;
+      int is_hkp_s = (strcmp (uri->parsed_uri->scheme, "hkp") == 0
+                      || strcmp (uri->parsed_uri->scheme, "hkps") == 0);
+      int is_http_s = (strcmp (uri->parsed_uri->scheme, "http") == 0
+                       || strcmp (uri->parsed_uri->scheme, "https") == 0);
       int is_ldap = 0;
 
 #if USE_LDAP
@@ -239,7 +244,7 @@ ks_action_get (ctrl_t ctrl, uri_item_t keyservers,
                 || strcmp (uri->parsed_uri->scheme, "ldapi") == 0);
 #endif
 
-      if (is_http || is_ldap)
+      if (is_hkp_s || is_http_s || is_ldap)
         {
           any_server = 1;
           for (sl = patterns; !err && sl; sl = sl->next)
@@ -249,9 +254,12 @@ ks_action_get (ctrl_t ctrl, uri_item_t keyservers,
                err = ks_ldap_get (ctrl, uri->parsed_uri, sl->d, &infp);
              else
 #endif
-               {
-                 err = ks_hkp_get (ctrl, uri->parsed_uri, sl->d, &infp);
-               }
+              if (is_hkp_s)
+                err = ks_hkp_get (ctrl, uri->parsed_uri, sl->d, &infp);
+              else if (is_http_s)
+                err = ks_http_fetch (ctrl, uri->parsed_uri->original, &infp);
+              else
+                BUG ();
 
               if (err)
                 {
@@ -288,7 +296,8 @@ ks_action_get (ctrl_t ctrl, uri_item_t keyservers,
 
 
 /* Retrieve keys from URL and write the result to the provided output
-   stream OUTFP.  */
+ * stream OUTFP.  If OUTFP is NULL the data is written to the bit
+ * bucket. */
 gpg_error_t
 ks_action_fetch (ctrl_t ctrl, const char *url, estream_t outfp)
 {