11/*
2- * Copyright (c) 1998-2018 John Caron and University Corporation for Atmospheric Research/Unidata
2+ * Copyright (c) 1998-2025 John Caron and University Corporation for Atmospheric Research/Unidata
33 * See LICENSE for license information.
44 */
5+
56package ucar .nc2 .dataset ;
67
78import static java .net .HttpURLConnection .HTTP_FORBIDDEN ;
89import static java .net .HttpURLConnection .HTTP_NOT_ACCEPTABLE ;
910import static java .net .HttpURLConnection .HTTP_OK ;
1011import static java .net .HttpURLConnection .HTTP_UNAUTHORIZED ;
12+
1113import com .google .common .annotations .VisibleForTesting ;
14+ import java .io .BufferedInputStream ;
15+ import java .io .File ;
16+ import java .io .FileInputStream ;
17+ import java .io .IOException ;
18+ import java .util .ArrayList ;
19+ import java .util .HashMap ;
20+ import java .util .List ;
21+ import java .util .Map ;
22+ import java .util .Objects ;
23+ import java .util .Optional ;
1224import javax .annotation .Nullable ;
1325
14- import com .google .common .collect .Multimap ;
1526import thredds .client .catalog .ServiceType ;
16- import thredds .inventory .MFile ;
17- import thredds .inventory .MFiles ;
1827import ucar .httpservices .HTTPFactory ;
1928import ucar .httpservices .HTTPMethod ;
2029import ucar .nc2 .util .EscapeStrings ;
2130import ucar .unidata .util .StringUtil2 ;
2231import ucar .unidata .util .Urlencoded ;
23- import java .io .*;
24- import java .util .*;
2532
2633/**
2734 * Detection of the protocol from a location string.
3138 * @since 10/20/2015.
3239 */
3340public class DatasetUrl {
41+ private static final org .slf4j .Logger logger = org .slf4j .LoggerFactory .getLogger (DatasetUrl .class );
3442 private static final String alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
3543 private static final String slashalpha = "\\ /" + alpha ;
3644
@@ -398,15 +406,23 @@ private static ServiceType disambiguateHttp(String location) throws IOException
398406 return null ;
399407 }
400408
409+ private static void handleCheckIfResponse (HTTPMethod method , int statusCode , ServiceType serviceChecked )
410+ throws IOException {
411+ if (statusCode == HTTP_UNAUTHORIZED ) {
412+ throw new IOException ("Unauthorized to open dataset " + method .getURI ());
413+ } else if (statusCode == HTTP_FORBIDDEN ) {
414+ logger .warn (String .format (
415+ "Forbidden Request to %s - assuming remote server is not a %s server, but could also indicate incorrect credentials." ,
416+ method .getURI (), serviceChecked ));
417+ }
418+ }
419+
401420 // cdmremote
402421 private static ServiceType checkIfCdmr (String location ) throws IOException {
403422 try (HTTPMethod method = HTTPFactory .Head (location + "?req=header" )) {
404423 int statusCode = method .execute ();
405424 if (statusCode >= 300 ) {
406- if (statusCode == HTTP_UNAUTHORIZED || statusCode == HTTP_FORBIDDEN )
407- throw new IOException ("Unauthorized to open dataset " + location );
408- else
409- throw new IOException (location + " is not a valid URL, return status=" + statusCode );
425+ handleCheckIfResponse (method , statusCode , ServiceType .CdmRemote );
410426 }
411427
412428 Optional <String > value = method .getResponseHeaderValue ("Content-Description" );
@@ -442,8 +458,7 @@ private static ServiceType checkIfDods(String location) throws IOException {
442458 throw new IOException ("OPeNDAP Server Error= " + method .getResponseAsString ());
443459 }
444460 }
445- if (status == HTTP_UNAUTHORIZED || status == HTTP_FORBIDDEN )
446- throw new IOException ("Unauthorized to open dataset " + location );
461+ handleCheckIfResponse (method , status , ServiceType .OPENDAP );
447462
448463 // not dods
449464 return null ;
@@ -471,6 +486,7 @@ else if (location.endsWith(".html"))
471486 return ServiceType .DAP4 ;
472487 }
473488 }
489+ handleCheckIfResponse (method , status , ServiceType .DAP4 );
474490 // not dap4
475491 return null ;
476492 }
@@ -497,14 +513,15 @@ private static boolean checkIfRemoteNcml(String location) throws IOException {
497513 method .setRequestHeader ("accept-encoding" , "identity" );
498514 int statusCode = method .execute ();
499515 if (statusCode >= 300 ) {
500- if ( statusCode == HTTP_UNAUTHORIZED ) {
501- throw new IOException ( "Unauthorized to open dataset " + location );
502- } else if (statusCode == HTTP_NOT_ACCEPTABLE ) {
516+ handleCheckIfResponse ( method , statusCode , ServiceType . NCML );
517+ // additional checks
518+ if (statusCode == HTTP_NOT_ACCEPTABLE ) {
503519 String msg = location + " - this server does not support returning content without any encoding." ;
504520 msg = msg + " Please download the file locally. Return status=" + statusCode ;
505521 throw new IOException (msg );
506522 } else {
507- throw new IOException (location + " is not a valid URL, return status=" + statusCode );
523+ throw new IOException (String .format ("Error opening %s: %s, (HTTP Status Code %d)" , location ,
524+ method .getResponseAsString (), statusCode ));
508525 }
509526 }
510527
0 commit comments