001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.eclipse.aether;
020
021/**
022 * The keys and defaults for common configuration properties.
023 *
024 * @see RepositorySystemSession#getConfigProperties()
025 */
026public final class ConfigurationProperties {
027
028    /**
029     * Prefix for all configurations. <em>For internal use only.</em>
030     *
031     * @since 2.0.0
032     */
033    public static final String PREFIX_AETHER = "aether.";
034
035    /**
036     * Prefix for repository system related configurations. <em>For internal use only.</em>
037     *
038     * @since 2.0.0
039     */
040    public static final String PREFIX_SYSTEM = PREFIX_AETHER + "system.";
041
042    /**
043     * Prefix for sync context related configurations. <em>For internal use only.</em>
044     *
045     * @since 2.0.0
046     */
047    public static final String PREFIX_SYNC_CONTEXT = PREFIX_AETHER + "syncContext.";
048
049    /**
050     * Prefix for connector related configurations. <em>For internal use only.</em>
051     *
052     * @since 2.0.0
053     */
054    public static final String PREFIX_CONNECTOR = PREFIX_AETHER + "connector.";
055
056    /**
057     * Prefix for layout related configurations. <em>For internal use only.</em>
058     *
059     * @since 2.0.0
060     */
061    public static final String PREFIX_LAYOUT = PREFIX_AETHER + "layout.";
062
063    /**
064     * Prefix for checksum related configurations. <em>For internal use only.</em>
065     *
066     * @since 2.0.0
067     */
068    public static final String PREFIX_CHECKSUMS = PREFIX_AETHER + "checksums.";
069
070    /**
071     * Prefix for local repository manager related configurations. <em>For internal use only.</em>
072     *
073     * @since 2.0.0
074     */
075    public static final String PREFIX_LRM = PREFIX_AETHER + "lrm.";
076
077    /**
078     * Prefix for generator related configurations. <em>For internal use only.</em>
079     *
080     * @since 2.0.0
081     */
082    public static final String PREFIX_GENERATOR = PREFIX_AETHER + "generator.";
083
084    /**
085     * Prefix for util related configurations. <em>For internal use only.</em>
086     *
087     * @since 2.0.10
088     */
089    public static final String PREFIX_UTIL = PREFIX_AETHER + "util.";
090
091    /**
092     * Prefix for installer related configurations. <em>For internal use only.</em>
093     *
094     * @since 2.0.25
095     */
096    public static final String PREFIX_INSTALLER = PREFIX_AETHER + "installer.";
097
098    /**
099     * Prefix for transport related configurations. <em>For internal use only.</em>
100     *
101     * @since 2.0.0
102     */
103    public static final String PREFIX_TRANSPORT = PREFIX_AETHER + "transport.";
104
105    /**
106     * Prefix for HTTP protocol related configurations. <em>For internal use only.</em>
107     *
108     * @since 2.0.0
109     */
110    public static final String PREFIX_TRANSPORT_HTTP = PREFIX_TRANSPORT + "http.";
111
112    /**
113     * Prefix for HTTPS protocol related configurations. <em>For internal use only.</em>
114     *
115     * @since 2.0.0
116     */
117    public static final String PREFIX_TRANSPORT_HTTPS = PREFIX_TRANSPORT + "https.";
118
119    /**
120     * The prefix for properties that control the priority of pluggable extensions like transporters. For example, for
121     * an extension with the fully qualified class name "org.eclipse.MyExtensionFactory", the configuration properties
122     * "aether.priority.org.eclipse.MyExtensionFactory", "aether.priority.MyExtensionFactory" and
123     * "aether.priority.MyExtension" will be consulted for the priority, in that order (obviously, the last key is only
124     * tried if the class name ends with "Factory"). The corresponding value is a float and the special value
125     * {@link Float#NaN} or "NaN" (case-sensitive) can be used to disable the extension.
126     */
127    public static final String PREFIX_PRIORITY = PREFIX_AETHER + "priority.";
128
129    /**
130     * A flag indicating whether the priorities of pluggable extensions are implicitly given by their iteration order
131     * such that the first extension has the highest priority. If set, an extension's built-in priority as well as any
132     * corresponding {@code aether.priority.*} configuration properties are ignored when searching for a suitable
133     * implementation among the available extensions. This priority mode is meant for cases where the application will
134     * present/inject extensions in the desired search order.
135     *
136     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
137     * @configurationType {@link java.lang.Boolean}
138     * @configurationDefaultValue {@link #DEFAULT_IMPLICIT_PRIORITIES}
139     * @configurationRepoIdSuffix No
140     */
141    public static final String IMPLICIT_PRIORITIES = PREFIX_PRIORITY + "implicit";
142
143    /**
144     * The default extension priority mode if {@link #IMPLICIT_PRIORITIES} isn't set.
145     */
146    public static final boolean DEFAULT_IMPLICIT_PRIORITIES = false;
147
148    /**
149     * A flag indicating whether the created ordered components should be cached in session.
150     *
151     * @since 2.0.0
152     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
153     * @configurationType {@link java.lang.Boolean}
154     * @configurationDefaultValue {@link #DEFAULT_CACHED_PRIORITIES}
155     * @configurationRepoIdSuffix No
156     */
157    public static final String CACHED_PRIORITIES = PREFIX_PRIORITY + "cached";
158
159    /**
160     * The default caching of priority components if {@link #CACHED_PRIORITIES} isn't set. Default value is {@code true}.
161     *
162     * @since 2.0.0
163     */
164    public static final boolean DEFAULT_CACHED_PRIORITIES = true;
165
166    /**
167     * The priority to use for a certain extension class. {@code &lt;class&gt;} can either be the fully qualified
168     * name or the simple name of a class. If the class name ends with Factory that suffix could optionally be left out.
169     * This configuration is used by {@code org.eclipse.aether.internal.impl.PrioritizedComponents} internal utility
170     * to sort classes by priority. This is reusable utility (so an extension can make use of it), but by default
171     * in "vanilla" Resolver following classes are sorted:
172     * <ul>
173     *     <li>{@code org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory}</li>
174     *     <li>{@code org.eclipse.aether.spi.connector.RepositoryConnectorFactory}</li>
175     *     <li>{@code org.eclipse.aether.spi.connector.layout.RepositoryLayoutFactory}</li>
176     *     <li>{@code org.eclipse.aether.spi.connector.transport.TransporterFactory}</li>
177     *     <li>{@code org.eclipse.aether.spi.artifact.decorator.ArtifactDecoratorFactory}</li>
178     *     <li>{@code org.eclipse.aether.spi.artifact.generator.ArtifactGeneratorFactory}</li>
179     *     <li>{@code org.eclipse.aether.impl.MetadataGeneratorFactory}</li>
180     * </ul>
181     *
182     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
183     * @configurationType {@link java.lang.Float}
184     * @configurationRepoIdSuffix No
185     */
186    public static final String CLASS_PRIORITIES = PREFIX_PRIORITY + "<class>";
187
188    /**
189     * A flag indicating whether interaction with the user is allowed.
190     *
191     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
192     * @configurationType {@link java.lang.Boolean}
193     * @configurationDefaultValue {@link #DEFAULT_INTERACTIVE}
194     * @configurationRepoIdSuffix No
195     */
196    public static final String INTERACTIVE = PREFIX_AETHER + "interactive";
197
198    /**
199     * The default interactive mode if {@link #INTERACTIVE} isn't set.
200     */
201    public static final boolean DEFAULT_INTERACTIVE = false;
202
203    /**
204     * The user agent that repository connectors should report to servers.
205     *
206     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
207     * @configurationType {@link java.lang.String}
208     * @configurationDefaultValue {@link #DEFAULT_USER_AGENT}
209     * @configurationRepoIdSuffix No
210     */
211    public static final String USER_AGENT = PREFIX_TRANSPORT_HTTP + "userAgent";
212
213    /**
214     * The default user agent to use if {@link #USER_AGENT} isn't set.
215     */
216    public static final String DEFAULT_USER_AGENT = "Aether";
217
218    /**
219     * The maximum amount of time (in milliseconds) to wait for a successful connection to a remote server. Non-positive
220     * values indicate no timeout.
221     *
222     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
223     * @configurationType {@link java.lang.Integer}
224     * @configurationDefaultValue {@link #DEFAULT_CONNECT_TIMEOUT}
225     * @configurationRepoIdSuffix Yes
226     */
227    public static final String CONNECT_TIMEOUT = PREFIX_TRANSPORT_HTTP + "connectTimeout";
228
229    /**
230     * The default connect timeout to use if {@link #CONNECT_TIMEOUT} isn't set.
231     */
232    public static final int DEFAULT_CONNECT_TIMEOUT = 30 * 1000;
233
234    /**
235     * The maximum amount of time (in milliseconds) to wait for remaining data to arrive from a remote server. Note that
236     * this timeout does not restrict the overall duration of a request, it only restricts the duration of inactivity
237     * between consecutive data packets. Non-positive values indicate no timeout.
238     *
239     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
240     * @configurationType {@link java.lang.Integer}
241     * @configurationDefaultValue {@link #DEFAULT_REQUEST_TIMEOUT}
242     * @configurationRepoIdSuffix Yes
243     */
244    public static final String REQUEST_TIMEOUT = PREFIX_TRANSPORT_HTTP + "requestTimeout";
245
246    /**
247     * The default request timeout to use if {@link #REQUEST_TIMEOUT} isn't set.
248     */
249    public static final int DEFAULT_REQUEST_TIMEOUT = 1800 * 1000;
250
251    /**
252     * The request headers to use for HTTP-based repository connectors. The headers are specified using a
253     * {@code Map<String, String>}, mapping a header name to its value. Besides this general key, clients may also
254     * specify headers for a specific remote repository by appending the suffix {@code .&lt;repoId&gt;} to this key when
255     * storing the headers map. The repository-specific headers map is supposed to be complete, i.e. is not merged with
256     * the general headers map.
257     * <p>
258     * <strong>Security note:</strong> configured headers are attached to every request the transport sends for the
259     * repository and, depending on the transport implementation, may be re-sent when the repository responds with
260     * a redirect - including redirects that leave the repository origin. Avoid placing credentials (for example
261     * {@code Authorization}, cookies or private token headers) in this map where repository authentication can be
262     * used instead: repository authentication is negotiated per host. All shipped HTTP transports scope configured
263     * headers to the repository origin by default, controlled by {@link #HTTP_ORIGIN_SCOPED_HEADERS}.
264     *
265     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
266     * @configurationType {@link java.util.Map}
267     * @configurationRepoIdSuffix Yes
268     */
269    public static final String HTTP_HEADERS = PREFIX_TRANSPORT_HTTP + "headers";
270
271    /**
272     * The mode that controls how HTTP redirects are handled. By default, any redirect is followed, but this can be
273     * restricted to only redirects within the same authority or no redirects at all.
274     *
275     * @since 2.0.25
276     */
277    public enum RedirectMode {
278        /**
279         * No redirects allowed.
280         */
281        NONE,
282        /**
283         * Redirects only within same authority.
284         */
285        SAME_AUTHORITY,
286        /**
287         * Any redirect is followed.
288         */
289        ANY
290    }
291
292    /**
293     * Optionally restricts following HTTP redirects to either the same authority or not allowing any redirects at all.
294     * By default any redirect is followed.
295     * Blocked redirects lead to exceptions being thrown by the transport.
296     *
297     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
298     * @configurationType {@link ConfigurationProperties.RedirectMode}
299     * @configurationDefaultValue {@link #DEFAULT_REDIRECT_MODE}
300     * @configurationRepoIdSuffix Yes
301     * @since 2.0.25
302     * @see #HTTP_ORIGIN_SCOPED_HEADERS
303     * @see #HTTP_FOLLOW_INSECURE_REDIRECT
304     */
305    public static final String HTTP_REDIRECT_MODE = PREFIX_TRANSPORT_HTTP + "redirectMode";
306
307    /**
308     * Default value if {@link #HTTP_REDIRECT_MODE} is not set.
309     *
310     * @since 2.0.25
311     */
312    public static final RedirectMode DEFAULT_REDIRECT_MODE = RedirectMode.ANY;
313
314    /**
315     * If enabled (default), HTTP transports only send configured request headers and preemptively applied
316     * {@code Authorization} on requests targeting the repository origin.
317     *
318     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
319     * @configurationType {@link java.lang.Boolean}
320     * @configurationDefaultValue {@link #DEFAULT_HTTP_ORIGIN_SCOPED_HEADERS}
321     * @configurationRepoIdSuffix Yes
322     * @since 2.0.25
323     * @see #HTTP_REDIRECT_MODE
324     */
325    public static final String HTTP_ORIGIN_SCOPED_HEADERS = PREFIX_TRANSPORT_HTTP + "originScopedHeaders";
326
327    /**
328     * The default value for {@link #HTTP_ORIGIN_SCOPED_HEADERS}: {@code true}.
329     *
330     * @since 2.0.25
331     */
332    public static final boolean DEFAULT_HTTP_ORIGIN_SCOPED_HEADERS = true;
333
334    /**
335     * If enabled, HTTP transports follow redirects that downgrade the protocol from HTTPS to HTTP. Disabled by
336     * default because such a downgrade removes transport encryption from artifact and checksum bytes.
337     *
338     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
339     * @configurationType {@link java.lang.Boolean}
340     * @configurationDefaultValue {@link #DEFAULT_HTTP_FOLLOW_INSECURE_REDIRECT}
341     * @configurationRepoIdSuffix Yes
342     * @since 2.0.25
343     */
344    public static final String HTTP_FOLLOW_INSECURE_REDIRECT = PREFIX_TRANSPORT_HTTP + "followInsecureRedirect";
345
346    /**
347     * The default value for {@link #HTTP_FOLLOW_INSECURE_REDIRECT}: {@code false}.
348     *
349     * @since 2.0.25
350     */
351    public static final boolean DEFAULT_HTTP_FOLLOW_INSECURE_REDIRECT = false;
352
353    /**
354     * The encoding/charset to use when exchanging credentials with HTTP servers. Besides this general key, clients may
355     * also specify the encoding for a specific remote repository by appending the suffix {@code .&lt;repoId&gt;} to this key
356     * when storing the charset name.
357     *
358     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
359     * @configurationType {@link java.lang.String}
360     * @configurationDefaultValue {@link #DEFAULT_HTTP_CREDENTIAL_ENCODING}
361     * @configurationRepoIdSuffix Yes
362     */
363    public static final String HTTP_CREDENTIAL_ENCODING = PREFIX_TRANSPORT_HTTP + "credentialEncoding";
364
365    /**
366     * The default encoding/charset to use if {@link #HTTP_CREDENTIAL_ENCODING} isn't set.
367     */
368    public static final String DEFAULT_HTTP_CREDENTIAL_ENCODING = "ISO-8859-1";
369
370    /**
371     * The maximum number of times a request to a remote server should be retried in case of an error.
372     *
373     * @since 1.9.6
374     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
375     * @configurationType {@link java.lang.Integer}
376     * @configurationDefaultValue {@link #DEFAULT_HTTP_RETRY_HANDLER_COUNT}
377     * @configurationRepoIdSuffix Yes
378     */
379    public static final String HTTP_RETRY_HANDLER_COUNT = PREFIX_TRANSPORT_HTTP + "retryHandler.count";
380
381    /**
382     * The default number of retries to use if {@link #HTTP_RETRY_HANDLER_COUNT} isn't set.
383     *
384     * @since 1.9.6
385     */
386    public static final int DEFAULT_HTTP_RETRY_HANDLER_COUNT = 3;
387
388    /**
389     * The initial delay in milliseconds for retried requests after receiving a server response with status
390     * "too many requests" (HTTP codes 429 and 503). Accepts long as milliseconds. This value is used if the remote server
391     * does not use {@code Retry-After} header, in which case the server value is obeyed.
392     * This delay is increased for every retry, up to {@link #HTTP_RETRY_HANDLER_INTERVAL_MAX}.
393     *
394     * @since 1.9.16
395     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
396     * @configurationType {@link java.lang.Long}
397     * @configurationDefaultValue {@link #DEFAULT_HTTP_RETRY_HANDLER_INTERVAL}
398     * @configurationRepoIdSuffix Yes
399     */
400    public static final String HTTP_RETRY_HANDLER_INTERVAL = PREFIX_TRANSPORT_HTTP + "retryHandler.interval";
401
402    /**
403     * The default initial retry delay to use if {@link #HTTP_RETRY_HANDLER_INTERVAL} isn't set.
404     * Default value 5000ms.
405     *
406     * @since 1.9.16
407     */
408    public static final long DEFAULT_HTTP_RETRY_HANDLER_INTERVAL = 5000L;
409
410    /**
411     * The maximum delay in milliseconds for retried requests. Every delay is capped to this value.
412     * This is a security measure to avoid malicious servers from stalling the build for too long.
413     *
414     * @since 1.9.16
415     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
416     * @configurationType {@link java.lang.Long}
417     * @configurationDefaultValue {@link #DEFAULT_HTTP_RETRY_HANDLER_INTERVAL_MAX}
418     * @configurationRepoIdSuffix Yes
419     */
420    public static final String HTTP_RETRY_HANDLER_INTERVAL_MAX = PREFIX_TRANSPORT_HTTP + "retryHandler.intervalMax";
421
422    /**
423     * The default retry delay maximum to use if {@link #HTTP_RETRY_HANDLER_INTERVAL_MAX} isn't set.
424     * Default value 5 minutes.
425     *
426     * @since 1.9.16
427     */
428    public static final long DEFAULT_HTTP_RETRY_HANDLER_INTERVAL_MAX = 300_000L;
429
430    /**
431     * The HTTP codes of remote server responses that should be handled as "too many requests"
432     * (examples: HTTP codes 429 and 503). Accepts comma separated list of HTTP response codes.
433     *
434     * @since 1.9.16
435     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
436     * @configurationType {@link java.lang.String}
437     * @configurationDefaultValue {@link #DEFAULT_HTTP_RETRY_HANDLER_SERVICE_UNAVAILABLE}
438     * @configurationRepoIdSuffix Yes
439     */
440    public static final String HTTP_RETRY_HANDLER_SERVICE_UNAVAILABLE =
441            PREFIX_TRANSPORT_HTTP + "retryHandler.serviceUnavailable";
442
443    /**
444     * The default HTTP codes of remote server responses that should be handled as "too many requests".
445     * Default value: "429,503".
446     *
447     * @since 1.9.16
448     */
449    public static final String DEFAULT_HTTP_RETRY_HANDLER_SERVICE_UNAVAILABLE = "429,503";
450
451    /**
452     * Should HTTP client use preemptive-authentication for all HTTP verbs (works only w/ BASIC). By default, is
453     * disabled, as it is considered less secure.
454     *
455     * @since 1.9.6
456     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
457     * @configurationType {@link java.lang.Boolean}
458     * @configurationDefaultValue {@link #DEFAULT_HTTP_PREEMPTIVE_AUTH}
459     * @configurationRepoIdSuffix Yes
460     */
461    public static final String HTTP_PREEMPTIVE_AUTH = PREFIX_TRANSPORT_HTTP + "preemptiveAuth";
462
463    /**
464     * The default value to use if {@link #HTTP_PREEMPTIVE_AUTH} isn't set (false).
465     *
466     * @since 1.9.6
467     */
468    public static final boolean DEFAULT_HTTP_PREEMPTIVE_AUTH = false;
469
470    /**
471     * Should HTTP client reuse connections (in other words, pool connections) or not?
472     *
473     * @since 1.9.8
474     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
475     * @configurationType {@link java.lang.Boolean}
476     * @configurationDefaultValue {@link #DEFAULT_HTTP_REUSE_CONNECTIONS}
477     * @configurationRepoIdSuffix Yes
478     */
479    public static final String HTTP_REUSE_CONNECTIONS = PREFIX_TRANSPORT_HTTP + "reuseConnections";
480
481    /**
482     * The default value to use if {@link #HTTP_REUSE_CONNECTIONS} isn't set (true).
483     *
484     * @since 1.9.8
485     */
486    public static final boolean DEFAULT_HTTP_REUSE_CONNECTIONS = true;
487
488    /**
489     * Total time to live in seconds for an HTTP connection, after that time, the connection will be dropped
490     * (no matter for how long it was idle).
491     *
492     * @since 1.9.8
493     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
494     * @configurationType {@link java.lang.Integer}
495     * @configurationDefaultValue {@link #DEFAULT_HTTP_CONNECTION_MAX_TTL}
496     * @configurationRepoIdSuffix Yes
497     */
498    public static final String HTTP_CONNECTION_MAX_TTL = PREFIX_TRANSPORT_HTTP + "connectionMaxTtl";
499
500    /**
501     * The default value to use if {@link #HTTP_CONNECTION_MAX_TTL} isn't set (300 seconds).
502     *
503     * @since 1.9.8
504     */
505    public static final int DEFAULT_HTTP_CONNECTION_MAX_TTL = 300;
506
507    /**
508     * The maximum concurrent connections per route HTTP client is allowed to use.
509     *
510     * @since 1.9.8
511     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
512     * @configurationType {@link java.lang.Integer}
513     * @configurationDefaultValue {@link #DEFAULT_HTTP_MAX_CONNECTIONS_PER_ROUTE}
514     * @configurationRepoIdSuffix Yes
515     */
516    public static final String HTTP_MAX_CONNECTIONS_PER_ROUTE = PREFIX_TRANSPORT_HTTP + "maxConnectionsPerRoute";
517
518    /**
519     * The default value to use if {@link #HTTP_MAX_CONNECTIONS_PER_ROUTE} isn't set (50 connections).
520     *
521     * @since 1.9.8
522     */
523    public static final int DEFAULT_HTTP_MAX_CONNECTIONS_PER_ROUTE = 50;
524
525    /**
526     * The local address (interface) to use with HTTP transport. Not all transport supports this option.
527     *
528     * @since 2.0.0
529     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
530     * @configurationType {@link java.lang.String}
531     * @configurationRepoIdSuffix Yes
532     */
533    public static final String HTTP_LOCAL_ADDRESS = PREFIX_TRANSPORT_HTTP + "localAddress";
534
535    /**
536     * Boolean flag should the HTTP transport support WebDAV remote. Not all transport support this option.
537     *
538     * @since 2.0.0 (moved out from maven-resolver-transport-http).
539     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
540     * @configurationType {@link java.lang.Boolean}
541     * @configurationDefaultValue {@link #DEFAULT_HTTP_SUPPORT_WEBDAV}
542     * @configurationRepoIdSuffix Yes
543     */
544    public static final String HTTP_SUPPORT_WEBDAV = PREFIX_TRANSPORT_HTTP + "supportWebDav";
545
546    /**
547     * Default value to use if {@link #HTTP_SUPPORT_WEBDAV} is not set: {@code false}.
548     *
549     * @since 2.0.0
550     */
551    public static final boolean DEFAULT_HTTP_SUPPORT_WEBDAV = false;
552
553    /**
554     * Boolean flag should the HTTP transport use preemptive-auth for PUT requests. Not all transport support this
555     * option.
556     *
557     * @since 2.0.0 (moved out from maven-resolver-transport-http).
558     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
559     * @configurationType {@link java.lang.Boolean}
560     * @configurationDefaultValue {@link #DEFAULT_HTTP_PREEMPTIVE_PUT_AUTH}
561     * @configurationRepoIdSuffix Yes
562     */
563    public static final String HTTP_PREEMPTIVE_PUT_AUTH = PREFIX_TRANSPORT_HTTP + "preemptivePutAuth";
564
565    /**
566     * Default value if {@link #HTTP_PREEMPTIVE_PUT_AUTH} is not set: {@code true}.
567     *
568     * @since 2.0.0
569     */
570    public static final boolean DEFAULT_HTTP_PREEMPTIVE_PUT_AUTH = true;
571
572    /**
573     * Boolean flag should the HTTP transport use expect-continue handshake for PUT requests. Not all transport support
574     * this option. This option may be needed for some broken HTTP servers. Default value corresponds to given
575     * transport default one (resolver does not override those), but if configuration IS given, it will replace
576     * given transport own default value.
577     *
578     * @since 1.9.17
579     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
580     * @configurationType {@link java.lang.Boolean}
581     * @configurationRepoIdSuffix Yes
582     */
583    public static final String HTTP_EXPECT_CONTINUE = PREFIX_TRANSPORT_HTTP + "expectContinue";
584
585    /**
586     * The mode that sets HTTPS transport "security mode": to ignore any SSL errors (certificate validity checks,
587     * hostname verification). The default value is {@link #HTTPS_SECURITY_MODE_DEFAULT}.
588     *
589     * @see #HTTPS_SECURITY_MODE_DEFAULT
590     * @see #HTTPS_SECURITY_MODE_INSECURE
591     * @since 1.9.6
592     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
593     * @configurationType {@link java.lang.String}
594     * @configurationDefaultValue {@link #HTTPS_SECURITY_MODE_DEFAULT}
595     * @configurationRepoIdSuffix Yes
596     */
597    public static final String HTTPS_SECURITY_MODE = PREFIX_TRANSPORT_HTTPS + "securityMode";
598
599    /**
600     * The default HTTPS security mode.
601     *
602     * @since 1.9.6
603     */
604    public static final String HTTPS_SECURITY_MODE_DEFAULT = "default";
605
606    /**
607     * The insecure HTTPS security mode (certificate validation, hostname verification are all ignored).
608     *
609     * @since 1.9.6
610     */
611    public static final String HTTPS_SECURITY_MODE_INSECURE = "insecure";
612
613    /**
614     * HTTP protocol version to use for the HTTP transport.
615     *
616     * @since 2.0.21
617     */
618    public enum HttpVersion {
619        /**
620         * The default HTTP version supported by the respective transporter (the most recent stable one, usually HTTP/2)
621         */
622        DEFAULT,
623        /** HTTP/1.1. */
624        HTTP_1_1,
625        /** HTTP/2. */
626        HTTP_2,
627        /** HTTP/3. */
628        HTTP_3,
629        /**
630         * The maximum HTTP version supported by the respective transporter (may be unstable).
631         */
632        MAXIMUM;
633    }
634
635    /**
636     * The maximum and preferred HTTP version. Some transporters transparently fall back to lower versions if remote server does not
637     * support the requested version, while other may just simply fail the request.
638     * Value must be a {@link HttpVersion} enum value or its String representation.
639     *
640     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
641     * @configurationType {@link ConfigurationProperties.HttpVersion}
642     * @configurationDefaultValue {@link #DEFAULT_HTTP_VERSION}
643     * @configurationRepoIdSuffix Yes
644     * @since 2.0.21
645     */
646    public static final String HTTP_VERSION = PREFIX_TRANSPORT_HTTP + "version";
647
648    /**
649     * Default value if {@link #HTTP_VERSION} is not set.
650     *
651     * @since 2.0.21
652     */
653    public static final HttpVersion DEFAULT_HTTP_VERSION = HttpVersion.DEFAULT;
654
655    /**
656     * A flag indicating which visitor should be used to "flatten" the dependency graph into list. In Maven 4
657     * the default is new "levelOrder", while Maven 3 used "preOrder". This property accepts values
658     * "preOrder", "postOrder" and "levelOrder".
659     *
660     * @see #REPOSITORY_SYSTEM_DEPENDENCY_VISITOR_PREORDER
661     * @see #REPOSITORY_SYSTEM_DEPENDENCY_VISITOR_POSTORDER
662     * @see #REPOSITORY_SYSTEM_DEPENDENCY_VISITOR_LEVELORDER
663     * @since 2.0.0
664     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
665     * @configurationType {@link java.lang.String}
666     * @configurationDefaultValue {@link #DEFAULT_REPOSITORY_SYSTEM_DEPENDENCY_VISITOR}
667     * @configurationRepoIdSuffix No
668     */
669    public static final String REPOSITORY_SYSTEM_DEPENDENCY_VISITOR = PREFIX_SYSTEM + "dependencyVisitor";
670
671    /**
672     * The visitor strategy "preOrder".
673     *
674     * @since 2.0.0
675     */
676    public static final String REPOSITORY_SYSTEM_DEPENDENCY_VISITOR_PREORDER = "preOrder";
677
678    /**
679     * The visitor strategy "postOrder". This was the only one supported in Resolver 1.x and is hence the
680     * default as well.
681     *
682     * @since 2.0.0
683     */
684    public static final String REPOSITORY_SYSTEM_DEPENDENCY_VISITOR_POSTORDER = "postOrder";
685
686    /**
687     * The visitor strategy "levelOrder".
688     *
689     * @since 2.0.0
690     */
691    public static final String REPOSITORY_SYSTEM_DEPENDENCY_VISITOR_LEVELORDER = "levelOrder";
692
693    /**
694     * The default visitor strategy.
695     *
696     * @since 2.0.12
697     */
698    public static final String DEFAULT_REPOSITORY_SYSTEM_DEPENDENCY_VISITOR =
699            REPOSITORY_SYSTEM_DEPENDENCY_VISITOR_LEVELORDER;
700
701    /**
702     * <b>Experimental:</b> Configuration for system-wide "repository key" function.
703     * Accepted and recommended values: "nid" (default), "nid_hurl" and "ngurk", while "simple" is Maven 3 legacy,
704     * technically equivalent to "nid". For complete description see enum
705     * {@code org.eclipse.aether.util.repository.RepositoryIdHelper.RepositoryKeyType} in utils. <em>Warning:</em>
706     * repository key function affects Resolver fundamentally and may have unexpected results! Only change this
707     * if you know what you are doing!
708     *
709     * @since 2.0.14
710     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
711     * @configurationType {@link java.lang.String}
712     * @configurationDefaultValue {@link #DEFAULT_REPOSITORY_SYSTEM_REPOSITORY_KEY_FUNCTION}
713     */
714    public static final String REPOSITORY_SYSTEM_REPOSITORY_KEY_FUNCTION = PREFIX_SYSTEM + "repositoryKeyFunction";
715
716    /**
717     * Default value if {@link #REPOSITORY_SYSTEM_REPOSITORY_KEY_FUNCTION} is not set.
718     *
719     * @since 2.0.14
720     */
721    public static final String DEFAULT_REPOSITORY_SYSTEM_REPOSITORY_KEY_FUNCTION = "nid";
722
723    /**
724     * Repository key function used for the provenance tracking entries that this local repository manager
725     * writes and reads. With an ID-only key, a repository declared in an untrusted (for example, transitively
726     * resolved) POM under the same ID as a trusted repository would be tracked as the same origin, potentially
727     * poisoning a shared local repository. The default is therefore the URL-qualified {@code "nid_hurl"}
728     * function.
729     * <p>
730     * This function is scoped to tracking entries, path composition, and split local repository prefixes.
731     * Repository identity used for aggregation and mirror merging continues to follow the system-wide key
732     * function ({@link #REPOSITORY_SYSTEM_REPOSITORY_KEY_FUNCTION}), whose default is unchanged.
733     * If the system-wide function is explicitly configured, tracking follows it (setting it to {@code "nid"}
734     * restores the legacy ID-only behaviour); this property, when set, overrides both.
735     * <p>
736     * Tracking entries written under a different function than the active one never match a lookup and never
737     * enable the untracked-file fallback: affected artifacts are treated as locally unavailable and
738     * re-fetched (with checksum validation) once.
739     *
740     * @since 2.0.23
741     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
742     * @configurationType {@link java.lang.String}
743     * @configurationDefaultValue {@link #DEFAULT_REPOSITORY_TRACKING_REPOSITORY_KEY_FUNCTION}
744     */
745    public static final String REPOSITORY_TRACKING_REPOSITORY_KEY_FUNCTION =
746            PREFIX_SYSTEM + "trackingRepositoryKeyFunction";
747
748    /**
749     * Default value if {@link #REPOSITORY_TRACKING_REPOSITORY_KEY_FUNCTION} is not set.
750     *
751     * @since 2.0.23
752     */
753    public static final String DEFAULT_REPOSITORY_TRACKING_REPOSITORY_KEY_FUNCTION = "nid_hurl";
754
755    /**
756     * A flag indicating whether version scheme cache statistics should be printed on JVM shutdown.
757     * This is useful for analyzing cache performance and effectiveness in development and testing scenarios.
758     *
759     * @since 2.0.10
760     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
761     * @configurationType {@link java.lang.Boolean}
762     * @configurationDefaultValue {@link #DEFAULT_VERSION_SCHEME_CACHE_DEBUG}
763     * @configurationRepoIdSuffix No
764     */
765    public static final String VERSION_SCHEME_CACHE_DEBUG = PREFIX_UTIL + "versionScheme.cacheDebug";
766
767    /**
768     * The default value for version scheme cache debug if {@link #VERSION_SCHEME_CACHE_DEBUG} isn't set.
769     *
770     * @since 2.0.10
771     */
772    public static final boolean DEFAULT_VERSION_SCHEME_CACHE_DEBUG = false;
773
774    /**
775     * Boolean flag should the HTTP transport send HTTP <pre>Accept</pre> header to signal that it supports RFC 9457
776     * error messages. Some servers have issues with handling the HTTP Accept headers. Known servers not supporting it
777     * is for example Staging REST endpoint of Sonatype Nexus 2.
778     * This configuration is only about sending (or not sending) HTTP header with content of
779     * <pre>Accept: application/problem+json</pre> that may be required by some servers to trigger error reporting
780     * using RFC 9457.
781     *
782     * @since 2.0.19
783     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
784     * @configurationType {@link java.lang.Boolean}
785     * @configurationDefaultValue {@link #DEFAULT_HTTP_SEND_RFC9457_ACCEPT}
786     * @configurationRepoIdSuffix Yes
787     */
788    public static final String HTTP_SEND_RFC9457_ACCEPT = PREFIX_TRANSPORT_HTTP + "sendRfc9457Accept";
789
790    /**
791     * Default value to use if {@link #HTTP_SEND_RFC9457_ACCEPT} is not set: {@code true}.
792     *
793     * @since 2.0.19
794     */
795    public static final boolean DEFAULT_HTTP_SEND_RFC9457_ACCEPT = true;
796
797    /**
798     * A flag indicating whether artifact installation should use hard links instead of copying files. When enabled,
799     * the installer creates a hard link from the source artifact (build output) to its destination in the local
800     * repository, avoiding a full file copy and saving disk I/O and space for large JARs.
801     * <p>
802     * Hard links require that the source and target paths reside on the <strong>same filesystem volume</strong>.
803     * When they do not (e.g. {@code ~/.m2} is on a separate mount, or a custom in-memory filesystem such as
804     * Jimfs is used for testing), the JVM throws {@link java.lang.UnsupportedOperationException},
805     * {@link IllegalArgumentException} (provider mismatch), or {@link java.io.IOException} (cross-device),
806     * and the installer automatically falls back to a regular file copy, so the build is never broken.
807     * <p>
808     * <strong>Note:</strong> hard links share an inode. Any tool that overwrites the build output file
809     * <em>in-place</em> (rather than via an atomic rename) would silently corrupt the cached artifact.
810     * Standard Maven build tooling always replaces output via rename, so this is generally safe. Set this
811     * property to {@code false} if your environment performs in-place writes to build output files.
812     *
813     * @since 2.0.25
814     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
815     * @configurationType {@link java.lang.Boolean}
816     * @configurationDefaultValue {@link #DEFAULT_INSTALLER_HARD_LINK}
817     * @configurationRepoIdSuffix No
818     */
819    public static final String INSTALLER_HARD_LINK = PREFIX_INSTALLER + "hardLink";
820
821    /**
822     * The default value for {@link #INSTALLER_HARD_LINK}: {@code true}.
823     *
824     * @since 2.0.25
825     */
826    public static final boolean DEFAULT_INSTALLER_HARD_LINK = true;
827
828    private ConfigurationProperties() {
829        // hide constructor
830    }
831}