package org.apache.maven.wagon.shared.http;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import org.apache.maven.wagon.authorization.AuthorizationException;
import org.apache.maven.wagon.proxy.ProxyInfo;
import org.codehaus.plexus.util.StringUtils;

Helper for HTTP related messages.

Important notice on Reason Phrase:

  • reason phrase was defined by initial HTTP/1.1 RFC 2616: The Reason-Phrase is intended to give a short textual description of the Status-Code. The Status-Code is intended for use by automata and the Reason-Phrase is intended for the human user. The client is not required to examine or display the Reason- Phrase.
  • it has been later largely deprecated in the updated HTTP/1.1 RFC-7230: The reason-phrase element exists for the sole purpose of providing a textual description associated with the numeric status code, mostly out of deference to earlier Internet application protocols that were more frequently used with interactive text clients. A client SHOULD ignore the reason-phrase content.
  • it has been removed from HTTP/2 RFC 7540: HTTP/2 does not define a way to carry the version or reason phrase that is included in an HTTP/1.1 status line..
The use of Reason Phrase done here to improve the message to the end-user (particularly in case of failures) will disappear while HTTP/2 is deployed: a new mechanism to provide such a message needs to be defined...
Since:3.3.4
/** * Helper for HTTP related messages. * <p> * <b>Important notice on Reason Phrase</b>: * <ul> * <li>reason phrase was <a href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html">defined by initial HTTP/1.1 * RFC 2616</a>: <cite>The Reason-Phrase is intended to give a short textual description of the Status-Code. The * Status-Code is intended for use by automata and the Reason-Phrase is intended for the human user. The client is not * required to examine or display the Reason- Phrase.</cite></li> * <li>it has been later largely deprecated in <a href="https://tools.ietf.org/html/rfc7230#section-3.1.2">the updated * HTTP/1.1 RFC-7230</a>: <cite>The reason-phrase element exists for the sole purpose of providing a textual description * associated with the numeric status code, mostly out of deference to earlier Internet application protocols that were * more frequently used with interactive text clients. A client SHOULD ignore the reason-phrase content.</cite></li> * <li>it has been removed from <a href="https://tools.ietf.org/html/rfc7540#section-8.1.2.4">HTTP/2 RFC 7540</a>: * <cite>HTTP/2 does not define a way to carry the version or reason phrase that is included in an HTTP/1.1 status * line.</cite>.</li> * </ul> * The use of Reason Phrase done here to improve the message to the end-user (particularly in case of failures) will * disappear while HTTP/2 is deployed: a new mechanism to provide such a message needs to be defined... * * @since 3.3.4 */
public class HttpMessageUtils { // status codes here to avoid checkstyle magic number and not have have hard depend on non-wagon classes private static final int SC_UNAUTHORIZED = 401; private static final int SC_FORBIDDEN = 403; private static final int SC_NOT_FOUND = 404; private static final int SC_PROXY_AUTH_REQUIRED = 407; private static final int SC_GONE = 410;
A HTTP status code used to indicate that the actual response status code is not known at time of message generation.
/** * A HTTP status code used to indicate that the actual response status code is not known at time of message * generation. */
public static final int UNKNOWN_STATUS_CODE = -1;
Format a consistent HTTP transfer debug message combining url, status code, status line reason phrase and HTTP proxy server info.

Url will always be included in the message. A status code other than UNKNOWN_STATUS_CODE will be included. A reason phrase will only be included if non-empty and status code is not UNKNOWN_STATUS_CODE. Proxy information will only be included if not null.

Params:
  • url – the required non-null URL associated with the message
  • statusCode – an HTTP response status code
  • reasonPhrase – an HTTP status line reason phrase
  • proxyInfo – proxy server used during the transfer, may be null if none used
Throws:
Returns:a formatted debug message combining the parameters of this method
/** * Format a consistent HTTP transfer debug message combining url, status code, status line reason phrase and HTTP * proxy server info. * <p> * Url will always be included in the message. A status code other than {@link #UNKNOWN_STATUS_CODE} will be * included. A reason phrase will only be included if non-empty and status code is not {@link #UNKNOWN_STATUS_CODE}. * Proxy information will only be included if not null. * * @param url the required non-null URL associated with the message * @param statusCode an HTTP response status code * @param reasonPhrase an HTTP status line reason phrase * @param proxyInfo proxy server used during the transfer, may be null if none used * @return a formatted debug message combining the parameters of this method * @throws NullPointerException if url is null */
public static String formatTransferDebugMessage( String url, int statusCode, String reasonPhrase, ProxyInfo proxyInfo ) { String msg = url; if ( statusCode != UNKNOWN_STATUS_CODE ) { msg += " -- status code: " + statusCode; if ( StringUtils.isNotEmpty( reasonPhrase ) ) { msg += ", reason phrase: " + reasonPhrase; } } if ( proxyInfo != null ) { msg += " -- " + proxyInfo.toString(); } return msg; }
Format a consistent message for HTTP related TransferFailedException.

This variation typically used in cases where there is no HTTP transfer response data to extract status code and reason phrase from. Equivalent to calling formatTransferFailedMessage(String, int, String, ProxyInfo) with UNKNOWN_STATUS_CODE and null reason phrase.

Params:
  • url – the URL associated with the message
  • proxyInfo – proxy server used during the transfer, may be null if none used
Returns:a formatted failure message combining the parameters of this method
/** * Format a consistent message for HTTP related {@link TransferFailedException}. * <p> * This variation typically used in cases where there is no HTTP transfer response data to extract status code and * reason phrase from. Equivalent to calling {@link #formatTransferFailedMessage(String, int, String, ProxyInfo)} * with {@link #UNKNOWN_STATUS_CODE} and null reason phrase. * * @param url the URL associated with the message * @param proxyInfo proxy server used during the transfer, may be null if none used * @return a formatted failure message combining the parameters of this method */
public static String formatTransferFailedMessage( String url, ProxyInfo proxyInfo ) { return formatTransferFailedMessage( url, UNKNOWN_STATUS_CODE, null, proxyInfo ); }
Format a consistent message for HTTP related TransferFailedException.
Params:
  • url – the URL associated with the message
  • statusCode – an HTTP response status code or UNKNOWN_STATUS_CODE
  • reasonPhrase – an HTTP status line reason phrase or null if the reason phrase unknown
  • proxyInfo – proxy server used during the transfer, may be null if none used
Returns:a formatted failure message combining the parameters of this method
/** * Format a consistent message for HTTP related {@link TransferFailedException}. * * @param url the URL associated with the message * @param statusCode an HTTP response status code or {@link #UNKNOWN_STATUS_CODE} * @param reasonPhrase an HTTP status line reason phrase or null if the reason phrase unknown * @param proxyInfo proxy server used during the transfer, may be null if none used * @return a formatted failure message combining the parameters of this method */
public static String formatTransferFailedMessage( String url, int statusCode, String reasonPhrase, ProxyInfo proxyInfo ) { return formatMessage( "Transfer failed for ", url, statusCode, reasonPhrase, proxyInfo ); }
Format a consistent message for HTTP related AuthorizationException.

The message will always include the URL and status code provided. If empty, the reason phrase is substituted with a common reason based on status code. ProxyInfo is only included in the message if not null.

Params:
  • url – the URL associated with the message
  • statusCode – an HTTP response status code related to auth
  • reasonPhrase – an HTTP status line reason phrase
  • proxyInfo – proxy server used during the transfer, may be null if none used
Returns:a consistent message for a HTTP related AuthorizationException
/** * Format a consistent message for HTTP related {@link AuthorizationException}. * <p> * The message will always include the URL and status code provided. If empty, the reason phrase is substituted with * a common reason based on status code. {@link ProxyInfo} is only included in the message if not null. * * @param url the URL associated with the message * @param statusCode an HTTP response status code related to auth * @param reasonPhrase an HTTP status line reason phrase * @param proxyInfo proxy server used during the transfer, may be null if none used * @return a consistent message for a HTTP related {@link AuthorizationException} */
public static String formatAuthorizationMessage( String url, int statusCode, String reasonPhrase, ProxyInfo proxyInfo ) { switch ( statusCode ) { case SC_UNAUTHORIZED: // no credentials or auth was not valid return formatMessage( "Authentication failed for ", url, statusCode, reasonPhrase, null ); case SC_FORBIDDEN: // forbidden based on permissions usually return formatMessage( "Authorization failed for ", url, statusCode, reasonPhrase, null ); case SC_PROXY_AUTH_REQUIRED: return formatMessage( "HTTP proxy server authentication failed for ", url, statusCode, reasonPhrase, null ); default: break; } return formatMessage( "Authorization failed for ", url, statusCode, reasonPhrase, proxyInfo ); }
Format a consistent message for HTTP related ResourceDoesNotExistException.

The message will always include the URL and status code provided. If empty, the reason phrase is substituted with the commonly used reason phrases per status code. ProxyInfo is only included if not null.

Params:
  • url – the URL associated with the message
  • statusCode – an HTTP response status code related to resources not being found
  • reasonPhrase – an HTTP status line reason phrase
  • proxyInfo – proxy server used during the transfer, may be null if none used
Returns:a consistent message for a HTTP related ResourceDoesNotExistException
/** * Format a consistent message for HTTP related {@link ResourceDoesNotExistException}. * <p> * The message will always include the URL and status code provided. If empty, the reason phrase is substituted with * the commonly used reason phrases per status code. {@link ProxyInfo} is only included if not null. * * @param url the URL associated with the message * @param statusCode an HTTP response status code related to resources not being found * @param reasonPhrase an HTTP status line reason phrase * @param proxyInfo proxy server used during the transfer, may be null if none used * @return a consistent message for a HTTP related {@link ResourceDoesNotExistException} */
public static String formatResourceDoesNotExistMessage( String url, int statusCode, String reasonPhrase, ProxyInfo proxyInfo ) { return formatMessage( "Resource missing at ", url, statusCode, reasonPhrase, proxyInfo ); } private static String formatMessage( String message, String url, int statusCode, String reasonPhrase, ProxyInfo proxyInfo ) { String msg = message + url; if ( statusCode != UNKNOWN_STATUS_CODE ) { msg += " " + statusCode; if ( StringUtils.isNotEmpty( reasonPhrase ) ) { msg += " " + reasonPhrase; } else { switch ( statusCode ) { case SC_UNAUTHORIZED: msg += " Unauthorized"; break; case SC_FORBIDDEN: msg += " Forbidden"; break; case SC_NOT_FOUND: msg += " Not Found"; break; case SC_PROXY_AUTH_REQUIRED: msg += " Proxy Authentication Required"; break; case SC_GONE: msg += " Gone"; break; default: break; } } } if ( proxyInfo != null ) { msg += " " + proxyInfo.toString(); } return msg; } }