@Override protected boolean checkRemoteAvailability( final long newerThen, final ProxyRepository repository, final ResourceStoreRequest request, final boolean isStrict) throws RemoteStorageException { final URL remoteUrl = appendQueryString(repository, request, getAbsoluteUrlFromBase(repository, request)); HttpRequestBase method; HttpResponse httpResponse = null; int statusCode = HttpStatus.SC_BAD_REQUEST; // artifactory hack, it pukes on HEAD so we will try with GET if HEAD fails boolean doGet = false; { method = new HttpHead(remoteUrl.toExternalForm()); try { httpResponse = executeRequestAndRelease(repository, request, method, repository.getRemoteUrl()); statusCode = httpResponse.getStatusLine().getStatusCode(); } catch (RemoteStorageException e) { // If HEAD failed, attempt a GET. Some repos may not support HEAD method doGet = true; log.debug("HEAD method failed, will attempt GET. Exception: " + e.getMessage(), e); } finally { // HEAD returned error, but not exception, try GET before failing if (!doGet && statusCode != HttpStatus.SC_OK) { doGet = true; log.debug("HEAD method failed, will attempt GET. Status: " + statusCode); } } } { if (doGet) { // create a GET method = new HttpGet(remoteUrl.toExternalForm()); // execute it httpResponse = executeRequestAndRelease(repository, request, method, repository.getRemoteUrl()); statusCode = httpResponse.getStatusLine().getStatusCode(); } } // if we are not strict and remote is S3 if (!isStrict && isRemotePeerAmazonS3Storage(repository)) { // if we are relaxed, we will accept any HTTP response code below 500. This means anyway the // HTTP // transaction succeeded. This method was never really detecting that the remoteUrl really // denotes a root of // repository (how could we do that?) // this "relaxed" check will help us to "pass" S3 remote storage. return statusCode >= HttpStatus.SC_OK && statusCode <= HttpStatus.SC_INTERNAL_SERVER_ERROR; } else { // non relaxed check is strict, and will select only the OK response if (statusCode == HttpStatus.SC_OK) { // we have it // we have newer if this below is true return makeDateFromHeader(httpResponse.getFirstHeader("last-modified")) > newerThen; } else if ((statusCode >= HttpStatus.SC_MULTIPLE_CHOICES && statusCode < HttpStatus.SC_BAD_REQUEST) || statusCode == HttpStatus.SC_NOT_FOUND) { if (RepositoryItemUid.PATH_ROOT.equals(request.getRequestPath()) && statusCode == HttpStatus.SC_NOT_FOUND) { // NEXUS-5944: Give it a chance: it might be remote Nexus with browsing disabled? // to check that, we will check is remote is Nexus by pinging "well know" location // if we got it, we will know it's only browsing forbidden on remote final RemoteStorageContext ctx = getRemoteStorageContext(repository); final HttpClient httpClient = (HttpClient) ctx.getContextObject(CTX_KEY_CLIENT); final PageContext pageContext = new RepositoryPageContext(httpClient, repository); final ResourceStoreRequest rmRequest = new ResourceStoreRequest("/.meta/repository-metadata.xml"); final URL nxRepoMetadataUrl = appendQueryString( repository, rmRequest, getAbsoluteUrlFromBase(repository, rmRequest)); try { final Page page = Page.getPageFor(pageContext, nxRepoMetadataUrl.toExternalForm()); if (page.getStatusCode() == 200) { // this is a Nexus with browsing disabled. say OK log.debug( "Original GET request for URL {} failed with 404, but GET request for URL {} succeeded, we assume remote is a Nexus repository having browsing disabled.", remoteUrl, nxRepoMetadataUrl); return true; } } catch (IOException e) { // just fall trough } } return false; } else { throw new RemoteStorageException( "Unexpected response code while executing " + method.getMethod() + " method [repositoryId=\"" + repository.getId() + "\", requestPath=\"" + request.getRequestPath() + "\", remoteUrl=\"" + remoteUrl.toString() + "\"]. Expected: \"SUCCESS (200)\". Received: " + statusCode + " : " + httpResponse.getStatusLine().getReasonPhrase()); } } }
@Override protected boolean checkRemoteAvailability( final long newerThen, final ProxyRepository repository, final ResourceStoreRequest request, final boolean isStrict) throws RemoteStorageException { final URL remoteUrl = appendQueryString(getAbsoluteUrlFromBase(repository, request), repository); HttpRequestBase method; HttpResponse httpResponse = null; int statusCode = HttpStatus.SC_BAD_REQUEST; // artifactory hack, it pukes on HEAD so we will try with GET if HEAD fails boolean doGet = false; { method = new HttpHead(remoteUrl.toExternalForm()); try { httpResponse = executeRequestAndRelease(repository, request, method); statusCode = httpResponse.getStatusLine().getStatusCode(); } catch (RemoteStorageException e) { // If HEAD failed, attempt a GET. Some repos may not support HEAD method doGet = true; getLogger().debug("HEAD method failed, will attempt GET. Exception: " + e.getMessage(), e); } finally { // HEAD returned error, but not exception, try GET before failing if (!doGet && statusCode != HttpStatus.SC_OK) { doGet = true; getLogger().debug("HEAD method failed, will attempt GET. Status: " + statusCode); } } } { if (doGet) { // create a GET method = new HttpGet(remoteUrl.toExternalForm()); // execute it httpResponse = executeRequestAndRelease(repository, request, method); statusCode = httpResponse.getStatusLine().getStatusCode(); } } // if we are not strict and remote is S3 if (!isStrict && isRemotePeerAmazonS3Storage(repository)) { // if we are relaxed, we will accept any HTTP response code below 500. This means anyway the // HTTP // transaction succeeded. This method was never really detecting that the remoteUrl really // denotes a root of // repository (how could we do that?) // this "relaxed" check will help us to "pass" S3 remote storage. return statusCode >= HttpStatus.SC_OK && statusCode <= HttpStatus.SC_INTERNAL_SERVER_ERROR; } else { // non relaxed check is strict, and will select only the OK response if (statusCode == HttpStatus.SC_OK) { // we have it // we have newer if this below is true return makeDateFromHeader(httpResponse.getFirstHeader("last-modified")) > newerThen; } else if ((statusCode >= HttpStatus.SC_MULTIPLE_CHOICES && statusCode < HttpStatus.SC_BAD_REQUEST) || statusCode == HttpStatus.SC_NOT_FOUND) { return false; } else { throw new RemoteStorageException( "Unexpected response code while executing " + method.getMethod() + " method [repositoryId=\"" + repository.getId() + "\", requestPath=\"" + request.getRequestPath() + "\", remoteUrl=\"" + remoteUrl.toString() + "\"]. Expected: \"SUCCESS (200)\". Received: " + statusCode + " : " + httpResponse.getStatusLine().getReasonPhrase()); } } }
@Override protected boolean checkRemoteAvailability( long newerThen, ProxyRepository repository, ResourceStoreRequest request, boolean isStrict) throws RemoteStorageException { final URL remoteURL = getAbsoluteUrlFromBase(repository, request); final String itemUrl = remoteURL.toString(); final AsyncHttpClient client = getClient(repository); if (getLogger().isDebugEnabled()) { getLogger() .debug( String.format( "Checking remote availability of proxy repository \"%s\" (id=%s) on URL %s", repository.getName(), repository.getId(), itemUrl)); } // artifactory hack, it pukes on HEAD so we will try with GET if HEAD fails boolean doGet = false; Response responseObject = null; int response = 400; try { responseObject = client.prepareHead(itemUrl).execute().get(); response = responseObject.getStatusCode(); validateResponse(repository, request, "HEAD", itemUrl, responseObject, 200); } catch (ItemNotFoundException e) { return false; } catch (RemoteStorageException e) { // If HEAD failed, attempt a GET. Some repos may not support HEAD method doGet = true; getLogger().debug("HEAD method failed, will attempt GET. Exception: " + e.getMessage(), e); } catch (Exception e) { throw new RemoteStorageException(e); } finally { // HEAD returned error, but not exception, try GET before failing if (!doGet && response != 200) { // try with GET unless some known to fail responses are in doGet = (response != 401) && (response != 403); getLogger().debug("HEAD method failed, will attempt GET. Status: " + response); } } if (doGet) { try { responseObject = client.prepareGet(itemUrl).execute().get(); response = responseObject.getStatusCode(); validateResponse(repository, request, "GET", itemUrl, responseObject, 200); } catch (ItemNotFoundException e) { return false; } catch (Exception e) { throw new RemoteStorageException(e); } } // if we are not strict and remote is S3 if (!isStrict && isRemotePeerAmazonS3Storage(repository)) { // if we are relaxed, we will accept any HTTP response code below 500. This means anyway the // HTTP // transaction succeeded. This method was never really detecting that the remoteUrl really // denotes a root of // repository (how could we do that?) // this "relaxed" check will help us to "pass" S3 remote storage. return response >= 200 && response < 500; } else { // non relaxed check is strict, and will select only the OK response if (response == 200) { // we have it // we have newer if this below is true return AHCUtils.getLastModified(responseObject, System.currentTimeMillis()) > newerThen; } else if ((response >= 300 && response < 400) || response == 404) { return false; } else { throw new RemoteStorageException( "Unexpected response code while executing GET" + " method [repositoryId=\"" + repository.getId() + "\", requestPath=\"" + request.getRequestPath() + "\", remoteUrl=\"" + itemUrl + "\"]. Expected: \"SUCCESS (200)\". Received: " + response + " : " + responseObject.getStatusText()); } } }